From 3fea0f88f36d5e2d14376281d6b877d32d39a06e Mon Sep 17 00:00:00 2001 From: YevhenBondarenko Date: Tue, 12 Dec 2023 14:03:48 +0100 Subject: [PATCH 001/179] moved queueName from rule-node config to rule-node --- .../main/data/upgrade/3.6.2/schema_update.sql | 19 +++++++ .../actors/ruleChain/DefaultTbContext.java | 4 +- .../install/ThingsboardInstallService.java | 5 ++ .../AnnotationComponentDiscoveryService.java | 1 + .../install/SqlDatabaseUpgradeService.java | 3 ++ .../update/DefaultDataUpdateService.java | 49 +++++++++++++++++++ .../impl/RuleChainImportService.java | 21 +++++++- .../data/plugin/ComponentDescriptor.java | 7 +++ .../server/common/data/rule/RuleNode.java | 6 ++- .../server/dao/model/ModelConstants.java | 2 + .../model/sql/ComponentDescriptorEntity.java | 5 ++ .../server/dao/model/sql/RuleNodeEntity.java | 5 ++ ...ctComponentDescriptorInsertRepository.java | 3 +- ...qlComponentDescriptorInsertRepository.java | 4 +- .../main/resources/sql/schema-entities.sql | 4 +- .../thingsboard/rule/engine/api/RuleNode.java | 2 + .../rule/engine/debug/TbMsgGeneratorNode.java | 9 ++-- .../TbMsgGeneratorNodeConfiguration.java | 1 - .../deduplication/TbMsgDeduplicationNode.java | 5 +- .../TbMsgDeduplicationNodeConfiguration.java | 1 - .../rule/engine/flow/TbCheckpointNode.java | 9 ++-- .../flow/TbCheckpointNodeConfiguration.java | 30 ------------ .../transform/TbMsgDeduplicationNodeTest.java | 17 +++++-- 23 files changed, 158 insertions(+), 54 deletions(-) create mode 100644 application/src/main/data/upgrade/3.6.2/schema_update.sql delete mode 100644 rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/flow/TbCheckpointNodeConfiguration.java diff --git a/application/src/main/data/upgrade/3.6.2/schema_update.sql b/application/src/main/data/upgrade/3.6.2/schema_update.sql new file mode 100644 index 0000000000..903137be79 --- /dev/null +++ b/application/src/main/data/upgrade/3.6.2/schema_update.sql @@ -0,0 +1,19 @@ +-- +-- Copyright © 2016-2023 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. +-- + +ALTER TABLE rule_node ADD COLUMN IF NOT EXISTS queue_name varchar(255); + +ALTER TABLE component_descriptor ADD COLUMN IF NOT EXISTS has_queue_name boolean DEFAULT false; diff --git a/application/src/main/java/org/thingsboard/server/actors/ruleChain/DefaultTbContext.java b/application/src/main/java/org/thingsboard/server/actors/ruleChain/DefaultTbContext.java index 28963b383a..bf61cf7a59 100644 --- a/application/src/main/java/org/thingsboard/server/actors/ruleChain/DefaultTbContext.java +++ b/application/src/main/java/org/thingsboard/server/actors/ruleChain/DefaultTbContext.java @@ -185,7 +185,7 @@ class DefaultTbContext implements TbContext { @Override public void enqueue(TbMsg tbMsg, Runnable onSuccess, Consumer onFailure) { - TopicPartitionInfo tpi = mainCtx.resolve(ServiceType.TB_RULE_ENGINE, getTenantId(), tbMsg.getOriginator()); + TopicPartitionInfo tpi = mainCtx.resolve(ServiceType.TB_RULE_ENGINE, nodeCtx.getSelf().getQueueName(), getTenantId(), tbMsg.getOriginator()); enqueue(tpi, tbMsg, onFailure, onSuccess); } @@ -310,7 +310,7 @@ class DefaultTbContext implements TbContext { @Override public boolean isLocalEntity(EntityId entityId) { - return mainCtx.resolve(ServiceType.TB_RULE_ENGINE, getTenantId(), entityId).isMyPartition(); + return mainCtx.resolve(ServiceType.TB_RULE_ENGINE, nodeCtx.getSelf().getQueueName(), getTenantId(), entityId).isMyPartition(); } private void scheduleMsgWithDelay(TbActorMsg msg, long delayInMs, TbActorRef target) { diff --git a/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java b/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java index 3fc68b9cc3..1be7fdecc4 100644 --- a/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java +++ b/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java @@ -277,6 +277,11 @@ public class ThingsboardInstallService { } else { log.info("Skipping images migration. Run the upgrade with fromVersion as '3.6.2-images' to migrate"); } + break; + case "3.6.2": + log.info("Upgrading ThingsBoard from version 3.6.2 to 3.6.3 ..."); + databaseEntitiesUpgradeService.upgradeDatabase("3.6.2"); + dataUpdateService.updateData("3.6.2"); //TODO DON'T FORGET to update switch statement in the CacheCleanupService if you need to clear the cache break; default: diff --git a/application/src/main/java/org/thingsboard/server/service/component/AnnotationComponentDiscoveryService.java b/application/src/main/java/org/thingsboard/server/service/component/AnnotationComponentDiscoveryService.java index d5f150ce24..571d37f05b 100644 --- a/application/src/main/java/org/thingsboard/server/service/component/AnnotationComponentDiscoveryService.java +++ b/application/src/main/java/org/thingsboard/server/service/component/AnnotationComponentDiscoveryService.java @@ -189,6 +189,7 @@ public class AnnotationComponentDiscoveryService implements ComponentDiscoverySe scannedComponent.setName(ruleNodeAnnotation.name()); scannedComponent.setScope(ruleNodeAnnotation.scope()); scannedComponent.setClusteringMode(ruleNodeAnnotation.clusteringMode()); + scannedComponent.setHasQueueName(ruleNodeAnnotation.hasQueueName()); NodeDefinition nodeDefinition = prepareNodeDefinition(clazz, ruleNodeAnnotation); ObjectNode configurationDescriptor = JacksonUtil.newObjectNode(); JsonNode node = JacksonUtil.valueToTree(nodeDefinition); diff --git a/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java b/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java index c2444390f6..4a96d0d2c3 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java +++ b/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java @@ -772,6 +772,9 @@ public class SqlDatabaseUpgradeService implements DatabaseEntitiesUpgradeService } }); break; + case "3.6.2": + updateSchema("3.6.2", 3006002, "3.6.3", 3006003, null); + break; default: throw new RuntimeException("Unable to upgrade SQL database, unsupported fromVersion: " + fromVersion); } diff --git a/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java b/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java index 7d08fdca00..c57d38b66d 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java +++ b/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java @@ -227,11 +227,25 @@ public class DefaultDataUpdateService implements DataUpdateService { log.info("Updating data from version 3.6.0 to 3.6.1 ..."); migrateDeviceConnectivity(); break; + case "3.6.2": + updateRuleNodesQueueName(); + break; default: throw new RuntimeException("Unable to update data, unsupported fromVersion: " + fromVersion); } } + private void updateRuleNodesQueueName() { + String[] ruleNodeTypes = { + "org.thingsboard.rule.engine.debug.TbMsgGeneratorNode", + "org.thingsboard.rule.engine.flow.TbCheckpointNode", + "org.thingsboard.rule.engine.deduplication.TbMsgDeduplicationNode" + }; + for (String ruleNodeType : ruleNodeTypes) { + ruleNodeQueueNameUpdater.updateEntities(ruleNodeType); + } + } + private void migrateEdgeEvents(String logPrefix) { boolean skipEdgeEventsMigration = getEnv("TB_SKIP_EDGE_EVENTS_MIGRATION", false); if (!skipEdgeEventsMigration) { @@ -792,4 +806,39 @@ public class DefaultDataUpdateService implements DataUpdateService { } } + private final PaginatedUpdater ruleNodeQueueNameUpdater = + new PaginatedUpdater<>() { + + @Override + protected String getName() { + return "RuleNode queue name updater"; + } + + @Override + protected boolean forceReportTotal() { + return true; + } + + @Override + protected PageData findEntities(String type, PageLink pageLink) { + return ruleChainService.findAllRuleNodesByType(type, pageLink); + } + + @Override + protected void updateEntity(RuleNode ruleNode) { + try { + ObjectNode configuration = (ObjectNode) ruleNode.getConfiguration(); + JsonNode queueName = configuration.remove("queueName"); + if (queueName != null) { + if (!queueName.isNull()) { + ruleNode.setQueueName(queueName.asText()); + } + ruleChainService.saveRuleNode(null, ruleNode); + } + } catch (Exception e) { + log.error("Unable to update RuleNode", e); + } + } + }; + } diff --git a/application/src/main/java/org/thingsboard/server/service/sync/ie/importing/impl/RuleChainImportService.java b/application/src/main/java/org/thingsboard/server/service/sync/ie/importing/impl/RuleChainImportService.java index d2673595ff..f3a01913a2 100644 --- a/application/src/main/java/org/thingsboard/server/service/sync/ie/importing/impl/RuleChainImportService.java +++ b/application/src/main/java/org/thingsboard/server/service/sync/ie/importing/impl/RuleChainImportService.java @@ -15,13 +15,14 @@ */ package org.thingsboard.server.service.sync.ie.importing.impl; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ObjectNode; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.audit.ActionType; -import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.id.RuleChainId; import org.thingsboard.server.common.data.id.RuleNodeId; import org.thingsboard.server.common.data.id.TenantId; @@ -84,12 +85,14 @@ public class RuleChainImportService extends BaseEntityImportService { node.setRuleChainId(null); node.setExternalId(node.getId()); node.setId(null); + setQueueName(node); }); } @@ -105,6 +108,22 @@ public class RuleChainImportService extends BaseEntityImportService clazz = Class.forName(ruleNode.getType()); + org.thingsboard.rule.engine.api.RuleNode ruleNodeAnnotation = clazz.getAnnotation(org.thingsboard.rule.engine.api.RuleNode.class); + if (ruleNodeAnnotation.hasQueueName()) { + ObjectNode configuration = (ObjectNode) ruleNode.getConfiguration(); + JsonNode queueName = configuration.remove("queueName"); + if (queueName != null && !queueName.isNull()) { + ruleNode.setQueueName(queueName.asText()); + } + } + } catch (ClassNotFoundException e) { + log.warn("[{}] RuleNode class not found [{}]", ruleNode.getName(), ruleNode.getType()); + } + } + @Override protected RuleChain saveOrUpdate(EntitiesImportCtx ctx, RuleChain ruleChain, RuleChainExportData exportData, IdProvider idProvider) { ruleChain = ruleChainService.saveRuleChain(ruleChain); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/plugin/ComponentDescriptor.java b/common/data/src/main/java/org/thingsboard/server/common/data/plugin/ComponentDescriptor.java index aab0a8f858..0e9b31ec09 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/plugin/ComponentDescriptor.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/plugin/ComponentDescriptor.java @@ -55,6 +55,8 @@ public class ComponentDescriptor extends BaseData { @Length(fieldName = "actions") @ApiModelProperty(position = 10, value = "Rule Node Actions. Deprecated. Always null.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) @Getter @Setter private String actions; + @ApiModelProperty(position = 11, value = "Indicates that the RuleNode is support queue name.", accessMode = ApiModelProperty.AccessMode.READ_ONLY, example = "true") + @Getter @Setter private boolean hasQueueName; public ComponentDescriptor() { super(); @@ -74,6 +76,7 @@ public class ComponentDescriptor extends BaseData { this.configurationDescriptor = plugin.getConfigurationDescriptor(); this.configurationVersion = plugin.getConfigurationVersion(); this.actions = plugin.getActions(); + this.hasQueueName = plugin.isHasQueueName(); } @ApiModelProperty(position = 1, value = "JSON object with the descriptor Id. " + @@ -104,6 +107,8 @@ public class ComponentDescriptor extends BaseData { if (!Objects.equals(actions, that.actions)) return false; if (!Objects.equals(configurationDescriptor, that.configurationDescriptor)) return false; if (configurationVersion != that.configurationVersion) return false; + if (clusteringMode != that.clusteringMode) return false; + if (hasQueueName != that.isHasQueueName()) return false; return Objects.equals(clazz, that.clazz); } @@ -115,6 +120,8 @@ public class ComponentDescriptor extends BaseData { result = 31 * result + (name != null ? name.hashCode() : 0); result = 31 * result + (clazz != null ? clazz.hashCode() : 0); result = 31 * result + (actions != null ? actions.hashCode() : 0); + result = 31 * result + (clusteringMode != null ? clusteringMode.hashCode() : 0); + result = 31 * result + (hasQueueName ? 1 : 0); return result; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleNode.java b/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleNode.java index 3fc1ceb628..3123ab1577 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleNode.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleNode.java @@ -50,9 +50,11 @@ public class RuleNode extends BaseDataWithAdditionalInfo implements private boolean debugMode; @ApiModelProperty(position = 7, value = "Enable/disable singleton mode. ", example = "false") private boolean singletonMode; - @ApiModelProperty(position = 8, value = "Version of rule node configuration. ", example = "0") + @ApiModelProperty(position = 8, value = "Queue name. ", example = "Main") + private String queueName; + @ApiModelProperty(position = 9, value = "Version of rule node configuration. ", example = "0") private int configurationVersion; - @ApiModelProperty(position = 9, value = "JSON with the rule node configuration. Structure depends on the rule node implementation.", dataType = "com.fasterxml.jackson.databind.JsonNode") + @ApiModelProperty(position = 10, value = "JSON with the rule node configuration. Structure depends on the rule node implementation.", dataType = "com.fasterxml.jackson.databind.JsonNode") private transient JsonNode configuration; @JsonIgnore private byte[] configurationBytes; diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java b/dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java index 21cea59ee3..2a9672de76 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java @@ -354,6 +354,7 @@ public class ModelConstants { public static final String COMPONENT_DESCRIPTOR_CONFIGURATION_DESCRIPTOR_PROPERTY = "configuration_descriptor"; public static final String COMPONENT_DESCRIPTOR_CONFIGURATION_VERSION_PROPERTY = "configuration_version"; public static final String COMPONENT_DESCRIPTOR_ACTIONS_PROPERTY = "actions"; + public static final String COMPONENT_DESCRIPTOR_HAS_QUEUE_NAME_PROPERTY = "has_queue_name"; /** * Event constants. @@ -389,6 +390,7 @@ public class ModelConstants { public static final String DEBUG_MODE = "debug_mode"; public static final String SINGLETON_MODE = "singleton_mode"; + public static final String QUEUE_NAME = "queue_name"; /** * Rule chain constants. diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/ComponentDescriptorEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/ComponentDescriptorEntity.java index a476d69c97..c4fa05ef03 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/ComponentDescriptorEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/ComponentDescriptorEntity.java @@ -70,6 +70,9 @@ public class ComponentDescriptorEntity extends BaseSqlEntity { @Column(name = ModelConstants.SINGLETON_MODE) private boolean singletonMode; + @Column(name = ModelConstants.QUEUE_NAME) + private String queueName; + @Column(name = ModelConstants.EXTERNAL_ID_PROPERTY) private UUID externalId; @@ -84,6 +87,7 @@ public class RuleNodeEntity extends BaseSqlEntity { this.name = ruleNode.getName(); this.debugMode = ruleNode.isDebugMode(); this.singletonMode = ruleNode.isSingletonMode(); + this.queueName = ruleNode.getQueueName(); this.configurationVersion = ruleNode.getConfigurationVersion(); this.configuration = ruleNode.getConfiguration(); this.additionalInfo = ruleNode.getAdditionalInfo(); @@ -103,6 +107,7 @@ public class RuleNodeEntity extends BaseSqlEntity { ruleNode.setName(name); ruleNode.setDebugMode(debugMode); ruleNode.setSingletonMode(singletonMode); + ruleNode.setQueueName(queueName); ruleNode.setConfigurationVersion(configurationVersion); ruleNode.setConfiguration(configuration); ruleNode.setAdditionalInfo(additionalInfo); diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/component/AbstractComponentDescriptorInsertRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/component/AbstractComponentDescriptorInsertRepository.java index ad8a07be08..0c2587dd5b 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/component/AbstractComponentDescriptorInsertRepository.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/component/AbstractComponentDescriptorInsertRepository.java @@ -77,7 +77,8 @@ public abstract class AbstractComponentDescriptorInsertRepository implements Com .setParameter("name", entity.getName()) .setParameter("scope", entity.getScope().name()) .setParameter("type", entity.getType().name()) - .setParameter("clustering_mode", entity.getClusteringMode().name()); + .setParameter("clustering_mode", entity.getClusteringMode().name()) + .setParameter("has_queue_name", entity.isHasQueueName()); } private ComponentDescriptorEntity processSaveOrUpdate(ComponentDescriptorEntity entity, String query) { diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/component/SqlComponentDescriptorInsertRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/component/SqlComponentDescriptorInsertRepository.java index c462f263f1..5a3038ab0e 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/component/SqlComponentDescriptorInsertRepository.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/component/SqlComponentDescriptorInsertRepository.java @@ -44,10 +44,10 @@ public class SqlComponentDescriptorInsertRepository extends AbstractComponentDes } private static String getInsertOrUpdateStatement(String conflictKeyStatement, String updateKeyStatement) { - return "INSERT INTO component_descriptor (id, created_time, actions, clazz, configuration_descriptor, configuration_version, name, scope, type, clustering_mode) VALUES (:id, :created_time, :actions, :clazz, :configuration_descriptor, :configuration_version, :name, :scope, :type, :clustering_mode) ON CONFLICT " + conflictKeyStatement + " DO UPDATE SET " + updateKeyStatement + " returning *"; + return "INSERT INTO component_descriptor (id, created_time, actions, clazz, configuration_descriptor, configuration_version, name, scope, type, clustering_mode, has_queue_name) VALUES (:id, :created_time, :actions, :clazz, :configuration_descriptor, :configuration_version, :name, :scope, :type, :clustering_mode, :has_queue_name) ON CONFLICT " + conflictKeyStatement + " DO UPDATE SET " + updateKeyStatement + " returning *"; } private static String getUpdateStatement(String id) { - return "actions = :actions, " + id + ",created_time = :created_time, configuration_descriptor = :configuration_descriptor, configuration_version = :configuration_version, name = :name, scope = :scope, type = :type, clustering_mode = :clustering_mode"; + return "actions = :actions, " + id + ",created_time = :created_time, configuration_descriptor = :configuration_descriptor, configuration_version = :configuration_version, name = :name, scope = :scope, type = :type, clustering_mode = :clustering_mode, has_queue_name = :has_queue_name"; } } diff --git a/dao/src/main/resources/sql/schema-entities.sql b/dao/src/main/resources/sql/schema-entities.sql index 35d1d49cda..402e0d23b5 100644 --- a/dao/src/main/resources/sql/schema-entities.sql +++ b/dao/src/main/resources/sql/schema-entities.sql @@ -126,7 +126,8 @@ CREATE TABLE IF NOT EXISTS component_descriptor ( name varchar(255), scope varchar(255), type varchar(255), - clustering_mode varchar(255) + clustering_mode varchar(255), + has_queue_name boolean DEFAULT false ); CREATE TABLE IF NOT EXISTS customer ( @@ -187,6 +188,7 @@ CREATE TABLE IF NOT EXISTS rule_node ( name varchar(255), debug_mode boolean, singleton_mode boolean, + queue_name varchar(255), external_id uuid ); diff --git a/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/RuleNode.java b/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/RuleNode.java index 7037f2f3fe..65fe9457ca 100644 --- a/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/RuleNode.java +++ b/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/RuleNode.java @@ -42,6 +42,8 @@ public @interface RuleNode { ComponentClusteringMode clusteringMode() default ComponentClusteringMode.ENABLED; + boolean hasQueueName() default false; + boolean inEnabled() default true; boolean outEnabled() default true; diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/debug/TbMsgGeneratorNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/debug/TbMsgGeneratorNode.java index b31c98bc0f..0b60f38981 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/debug/TbMsgGeneratorNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/debug/TbMsgGeneratorNode.java @@ -50,6 +50,7 @@ import static org.thingsboard.common.util.DonAsynchron.withCallback; type = ComponentType.ACTION, name = "generator", configClazz = TbMsgGeneratorNodeConfiguration.class, + hasQueueName = true, nodeDescription = "Periodically generates messages", nodeDetails = "Generates messages with configurable period. Javascript function used for message generation.", inEnabled = false, @@ -69,6 +70,7 @@ public class TbMsgGeneratorNode implements TbNode { private UUID nextTickId; private TbMsg prevMsg; private final AtomicBoolean initialized = new AtomicBoolean(false); + private String queueName; @Override public void init(TbContext ctx, TbNodeConfiguration configuration) throws TbNodeException { @@ -76,6 +78,7 @@ public class TbMsgGeneratorNode implements TbNode { this.config = TbNodeUtils.convert(configuration, TbMsgGeneratorNodeConfiguration.class); this.delay = TimeUnit.SECONDS.toMillis(config.getPeriodInSeconds()); this.currentMsgCount = 0; + this.queueName = ctx.getSelf().getQueueName(); if (!StringUtils.isEmpty(config.getOriginatorId())) { originatorId = EntityIdFactory.getByTypeAndUuid(config.getOriginatorType(), config.getOriginatorId()); ctx.checkTenantEntity(originatorId); @@ -137,7 +140,7 @@ public class TbMsgGeneratorNode implements TbNode { } lastScheduledTs = lastScheduledTs + delay; long curDelay = Math.max(0L, (lastScheduledTs - curTs)); - TbMsg tickMsg = ctx.newMsg(config.getQueueName(), TbMsgType.GENERATOR_NODE_SELF_MSG, ctx.getSelfId(), + TbMsg tickMsg = ctx.newMsg(queueName, TbMsgType.GENERATOR_NODE_SELF_MSG, ctx.getSelfId(), getCustomerIdFromMsg(msg), TbMsgMetaData.EMPTY, TbMsg.EMPTY_STRING); nextTickId = tickMsg.getId(); ctx.tellSelf(tickMsg, curDelay); @@ -146,14 +149,14 @@ public class TbMsgGeneratorNode implements TbNode { private ListenableFuture generate(TbContext ctx, TbMsg msg) { log.trace("generate, config {}", config); if (prevMsg == null) { - prevMsg = ctx.newMsg(config.getQueueName(), TbMsg.EMPTY_STRING, originatorId, msg.getCustomerId(), TbMsgMetaData.EMPTY, TbMsg.EMPTY_JSON_OBJECT); + prevMsg = ctx.newMsg(queueName, TbMsg.EMPTY_STRING, originatorId, msg.getCustomerId(), TbMsgMetaData.EMPTY, TbMsg.EMPTY_JSON_OBJECT); } if (initialized.get()) { ctx.logJsEvalRequest(); return Futures.transformAsync(scriptEngine.executeGenerateAsync(prevMsg), generated -> { log.trace("generate process response, generated {}, config {}", generated, config); ctx.logJsEvalResponse(); - prevMsg = ctx.newMsg(config.getQueueName(), generated.getType(), originatorId, msg.getCustomerId(), generated.getMetaData(), generated.getData()); + prevMsg = ctx.newMsg(queueName, generated.getType(), originatorId, msg.getCustomerId(), generated.getMetaData(), generated.getData()); return Futures.immediateFuture(prevMsg); }, MoreExecutors.directExecutor()); //usually it runs on js-executor-remote-callback thread pool } diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/debug/TbMsgGeneratorNodeConfiguration.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/debug/TbMsgGeneratorNodeConfiguration.java index 5f12603832..027f4aa708 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/debug/TbMsgGeneratorNodeConfiguration.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/debug/TbMsgGeneratorNodeConfiguration.java @@ -36,7 +36,6 @@ public class TbMsgGeneratorNodeConfiguration implements NodeConfiguration deduplicationMap; private long deduplicationInterval; + private String queueName; public TbMsgDeduplicationNode() { this.deduplicationMap = new HashMap<>(); @@ -75,6 +77,7 @@ public class TbMsgDeduplicationNode implements TbNode { public void init(TbContext ctx, TbNodeConfiguration configuration) throws TbNodeException { this.config = TbNodeUtils.convert(configuration, TbMsgDeduplicationNodeConfiguration.class); this.deduplicationInterval = TimeUnit.SECONDS.toMillis(config.getInterval()); + this.queueName = ctx.getSelf().getQueueName(); } @Override @@ -132,7 +135,7 @@ public class TbMsgDeduplicationNode implements TbNode { } } deduplicationResults.add(TbMsg.newMsg( - config.getQueueName(), + queueName, config.getOutMsgType(), deduplicationId, getMetadata(), diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/deduplication/TbMsgDeduplicationNodeConfiguration.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/deduplication/TbMsgDeduplicationNodeConfiguration.java index 9560247033..08e81d8a6e 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/deduplication/TbMsgDeduplicationNodeConfiguration.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/deduplication/TbMsgDeduplicationNodeConfiguration.java @@ -26,7 +26,6 @@ public class TbMsgDeduplicationNodeConfiguration implements NodeConfiguration { - - private String queueName; - - @Override - public TbCheckpointNodeConfiguration defaultConfiguration() { - return new TbCheckpointNodeConfiguration(); - } -} diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/transform/TbMsgDeduplicationNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/transform/TbMsgDeduplicationNodeTest.java index be6aea6fa5..4e3ae2a015 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/transform/TbMsgDeduplicationNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/transform/TbMsgDeduplicationNodeTest.java @@ -40,6 +40,7 @@ import org.thingsboard.server.common.data.id.RuleNodeId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.msg.TbMsgType; import org.thingsboard.server.common.data.msg.TbNodeConnectionType; +import org.thingsboard.server.common.data.rule.RuleNode; import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsgMetaData; @@ -241,7 +242,7 @@ public class TbMsgDeduplicationNodeTest { config.setInterval(deduplicationInterval); config.setStrategy(DeduplicationStrategy.ALL); config.setOutMsgType(TbMsgType.POST_ATTRIBUTES_REQUEST.name()); - config.setQueueName(DataConstants.HP_QUEUE_NAME); + setQueueName(DataConstants.HP_QUEUE_NAME); nodeConfiguration = new TbNodeConfiguration(JacksonUtil.valueToTree(config)); node.init(ctx, nodeConfiguration); @@ -268,7 +269,7 @@ public class TbMsgDeduplicationNodeTest { Assertions.assertEquals(getMergedData(inputMsgs), outMessage.getData()); Assertions.assertEquals(deviceId, outMessage.getOriginator()); Assertions.assertEquals(config.getOutMsgType(), outMessage.getType()); - Assertions.assertEquals(config.getQueueName(), outMessage.getQueueName()); + Assertions.assertEquals(DataConstants.HP_QUEUE_NAME, outMessage.getQueueName()); } @Test @@ -281,7 +282,7 @@ public class TbMsgDeduplicationNodeTest { config.setInterval(deduplicationInterval); config.setStrategy(DeduplicationStrategy.ALL); config.setOutMsgType(TbMsgType.POST_ATTRIBUTES_REQUEST.name()); - config.setQueueName(DataConstants.HP_QUEUE_NAME); + setQueueName(DataConstants.HP_QUEUE_NAME); nodeConfiguration = new TbNodeConfiguration(JacksonUtil.valueToTree(config)); node.init(ctx, nodeConfiguration); @@ -316,13 +317,13 @@ public class TbMsgDeduplicationNodeTest { Assertions.assertEquals(getMergedData(firstMsgPack), firstMsg.getData()); Assertions.assertEquals(deviceId, firstMsg.getOriginator()); Assertions.assertEquals(config.getOutMsgType(), firstMsg.getType()); - Assertions.assertEquals(config.getQueueName(), firstMsg.getQueueName()); + Assertions.assertEquals(DataConstants.HP_QUEUE_NAME, firstMsg.getQueueName()); TbMsg secondMsg = resultMsgs.get(1); Assertions.assertEquals(getMergedData(secondMsgPack), secondMsg.getData()); Assertions.assertEquals(deviceId, secondMsg.getOriginator()); Assertions.assertEquals(config.getOutMsgType(), secondMsg.getType()); - Assertions.assertEquals(config.getQueueName(), secondMsg.getQueueName()); + Assertions.assertEquals(DataConstants.HP_QUEUE_NAME, secondMsg.getQueueName()); } @Test @@ -429,4 +430,10 @@ public class TbMsgDeduplicationNodeTest { return JacksonUtil.toString(mergedData); } + private void setQueueName(String queueName) { + RuleNode ruleNode = new RuleNode(); + ruleNode.setQueueName(queueName); + when(ctx.getSelf()).thenReturn(ruleNode); + } + } From b65391e6ac5fc1cb3ec861feb371db1d3041ca02 Mon Sep 17 00:00:00 2001 From: YevhenBondarenko Date: Tue, 12 Dec 2023 16:47:19 +0100 Subject: [PATCH 002/179] fixed TbMsgDeduplicationNodeTest --- .../rule/engine/transform/TbMsgDeduplicationNodeTest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/transform/TbMsgDeduplicationNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/transform/TbMsgDeduplicationNodeTest.java index 4e3ae2a015..ac3f2acfd5 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/transform/TbMsgDeduplicationNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/transform/TbMsgDeduplicationNodeTest.java @@ -94,6 +94,7 @@ public class TbMsgDeduplicationNodeTest { when(ctx.getSelfId()).thenReturn(ruleNodeId); when(ctx.getTenantId()).thenReturn(tenantId); + when(ctx.getSelf()).thenReturn(new RuleNode()); doAnswer((Answer) invocationOnMock -> { TbMsgType type = (TbMsgType) (invocationOnMock.getArguments())[1]; From e8dc2ddc2d388936a7d7d1b4351b793c74b5eeb7 Mon Sep 17 00:00:00 2001 From: YevhenBondarenko Date: Tue, 12 Dec 2023 20:47:25 +0100 Subject: [PATCH 003/179] used TbNodeUpgradeUtils instead of rule-node upgrade --- .../install/ThingsboardInstallService.java | 1 - .../update/DefaultDataUpdateService.java | 49 ------------------- .../impl/RuleChainImportService.java | 20 -------- .../server/utils/TbNodeUpgradeUtils.java | 6 +++ .../rule/engine/api/util/TbNodeUtils.java | 1 + .../rule/engine/debug/TbMsgGeneratorNode.java | 21 ++++++++ .../deduplication/TbMsgDeduplicationNode.java | 20 ++++++++ .../rule/engine/flow/TbCheckpointNode.java | 22 +++++++++ 8 files changed, 70 insertions(+), 70 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java b/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java index 1be7fdecc4..054c7a6751 100644 --- a/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java +++ b/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java @@ -281,7 +281,6 @@ public class ThingsboardInstallService { case "3.6.2": log.info("Upgrading ThingsBoard from version 3.6.2 to 3.6.3 ..."); databaseEntitiesUpgradeService.upgradeDatabase("3.6.2"); - dataUpdateService.updateData("3.6.2"); //TODO DON'T FORGET to update switch statement in the CacheCleanupService if you need to clear the cache break; default: diff --git a/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java b/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java index c57d38b66d..7d08fdca00 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java +++ b/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java @@ -227,25 +227,11 @@ public class DefaultDataUpdateService implements DataUpdateService { log.info("Updating data from version 3.6.0 to 3.6.1 ..."); migrateDeviceConnectivity(); break; - case "3.6.2": - updateRuleNodesQueueName(); - break; default: throw new RuntimeException("Unable to update data, unsupported fromVersion: " + fromVersion); } } - private void updateRuleNodesQueueName() { - String[] ruleNodeTypes = { - "org.thingsboard.rule.engine.debug.TbMsgGeneratorNode", - "org.thingsboard.rule.engine.flow.TbCheckpointNode", - "org.thingsboard.rule.engine.deduplication.TbMsgDeduplicationNode" - }; - for (String ruleNodeType : ruleNodeTypes) { - ruleNodeQueueNameUpdater.updateEntities(ruleNodeType); - } - } - private void migrateEdgeEvents(String logPrefix) { boolean skipEdgeEventsMigration = getEnv("TB_SKIP_EDGE_EVENTS_MIGRATION", false); if (!skipEdgeEventsMigration) { @@ -806,39 +792,4 @@ public class DefaultDataUpdateService implements DataUpdateService { } } - private final PaginatedUpdater ruleNodeQueueNameUpdater = - new PaginatedUpdater<>() { - - @Override - protected String getName() { - return "RuleNode queue name updater"; - } - - @Override - protected boolean forceReportTotal() { - return true; - } - - @Override - protected PageData findEntities(String type, PageLink pageLink) { - return ruleChainService.findAllRuleNodesByType(type, pageLink); - } - - @Override - protected void updateEntity(RuleNode ruleNode) { - try { - ObjectNode configuration = (ObjectNode) ruleNode.getConfiguration(); - JsonNode queueName = configuration.remove("queueName"); - if (queueName != null) { - if (!queueName.isNull()) { - ruleNode.setQueueName(queueName.asText()); - } - ruleChainService.saveRuleNode(null, ruleNode); - } - } catch (Exception e) { - log.error("Unable to update RuleNode", e); - } - } - }; - } diff --git a/application/src/main/java/org/thingsboard/server/service/sync/ie/importing/impl/RuleChainImportService.java b/application/src/main/java/org/thingsboard/server/service/sync/ie/importing/impl/RuleChainImportService.java index f3a01913a2..bb930f9634 100644 --- a/application/src/main/java/org/thingsboard/server/service/sync/ie/importing/impl/RuleChainImportService.java +++ b/application/src/main/java/org/thingsboard/server/service/sync/ie/importing/impl/RuleChainImportService.java @@ -15,8 +15,6 @@ */ package org.thingsboard.server.service.sync.ie.importing.impl; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.ObjectNode; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; @@ -85,14 +83,12 @@ public class RuleChainImportService extends BaseEntityImportService { node.setRuleChainId(null); node.setExternalId(node.getId()); node.setId(null); - setQueueName(node); }); } @@ -108,22 +104,6 @@ public class RuleChainImportService extends BaseEntityImportService clazz = Class.forName(ruleNode.getType()); - org.thingsboard.rule.engine.api.RuleNode ruleNodeAnnotation = clazz.getAnnotation(org.thingsboard.rule.engine.api.RuleNode.class); - if (ruleNodeAnnotation.hasQueueName()) { - ObjectNode configuration = (ObjectNode) ruleNode.getConfiguration(); - JsonNode queueName = configuration.remove("queueName"); - if (queueName != null && !queueName.isNull()) { - ruleNode.setQueueName(queueName.asText()); - } - } - } catch (ClassNotFoundException e) { - log.warn("[{}] RuleNode class not found [{}]", ruleNode.getName(), ruleNode.getType()); - } - } - @Override protected RuleChain saveOrUpdate(EntitiesImportCtx ctx, RuleChain ruleChain, RuleChainExportData exportData, IdProvider idProvider) { ruleChain = ruleChainService.saveRuleChain(ruleChain); diff --git a/application/src/main/java/org/thingsboard/server/utils/TbNodeUpgradeUtils.java b/application/src/main/java/org/thingsboard/server/utils/TbNodeUpgradeUtils.java index 530679683d..23c75b430b 100644 --- a/application/src/main/java/org/thingsboard/server/utils/TbNodeUpgradeUtils.java +++ b/application/src/main/java/org/thingsboard/server/utils/TbNodeUpgradeUtils.java @@ -25,6 +25,8 @@ import org.thingsboard.server.common.data.rule.RuleNode; import org.thingsboard.server.common.data.util.TbPair; import org.thingsboard.server.service.component.RuleNodeClassInfo; +import static org.thingsboard.rule.engine.api.util.TbNodeUtils.QUEUE_NAME; + @Slf4j public class TbNodeUpgradeUtils { @@ -44,9 +46,13 @@ public class TbNodeUpgradeUtils { } else { var tbVersionedNode = getTbVersionedNode(nodeInfo); try { + JsonNode queueName = oldConfiguration.get(QUEUE_NAME); TbPair upgradeResult = tbVersionedNode.upgrade(configurationVersion, oldConfiguration); if (upgradeResult.getFirst()) { node.setConfiguration(upgradeResult.getSecond()); + if (nodeInfo.getAnnotation().hasQueueName() && queueName != null && queueName.isTextual()) { + node.setQueueName(queueName.asText()); + } } } catch (Exception e) { try { diff --git a/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/util/TbNodeUtils.java b/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/util/TbNodeUtils.java index 396d810b00..cce5649336 100644 --- a/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/util/TbNodeUtils.java +++ b/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/util/TbNodeUtils.java @@ -36,6 +36,7 @@ import java.util.stream.Collectors; */ public class TbNodeUtils { + public static final String QUEUE_NAME = "queueName"; private static final Pattern DATA_PATTERN = Pattern.compile("(\\$\\[)(.*?)(])"); diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/debug/TbMsgGeneratorNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/debug/TbMsgGeneratorNode.java index 0b60f38981..80170a28f1 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/debug/TbMsgGeneratorNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/debug/TbMsgGeneratorNode.java @@ -15,6 +15,8 @@ */ package org.thingsboard.rule.engine.debug; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ObjectNode; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.MoreExecutors; @@ -35,6 +37,7 @@ import org.thingsboard.server.common.data.msg.TbMsgType; import org.thingsboard.server.common.data.msg.TbNodeConnectionType; import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.data.script.ScriptLanguage; +import org.thingsboard.server.common.data.util.TbPair; import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsgMetaData; import org.thingsboard.server.common.msg.queue.PartitionChangeMsg; @@ -44,12 +47,14 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import static org.thingsboard.common.util.DonAsynchron.withCallback; +import static org.thingsboard.rule.engine.api.util.TbNodeUtils.QUEUE_NAME; @Slf4j @RuleNode( type = ComponentType.ACTION, name = "generator", configClazz = TbMsgGeneratorNodeConfiguration.class, + version = 1, hasQueueName = true, nodeDescription = "Periodically generates messages", nodeDetails = "Generates messages with configurable period. Javascript function used for message generation.", @@ -177,4 +182,20 @@ public class TbMsgGeneratorNode implements TbNode { scriptEngine = null; } } + + @Override + public TbPair upgrade(int fromVersion, JsonNode oldConfiguration) throws TbNodeException { + boolean hasChanges = false; + switch (fromVersion) { + case 0: + if (oldConfiguration.has(QUEUE_NAME)) { + hasChanges = true; + ((ObjectNode) oldConfiguration).remove(QUEUE_NAME); + } + break; + default: + break; + } + return new TbPair<>(hasChanges, oldConfiguration); + } } diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/deduplication/TbMsgDeduplicationNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/deduplication/TbMsgDeduplicationNode.java index a7a8b44b21..8f818583e8 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/deduplication/TbMsgDeduplicationNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/deduplication/TbMsgDeduplicationNode.java @@ -15,6 +15,7 @@ */ package org.thingsboard.rule.engine.deduplication; +import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; import lombok.extern.slf4j.Slf4j; @@ -43,10 +44,13 @@ import java.util.Optional; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; +import static org.thingsboard.rule.engine.api.util.TbNodeUtils.QUEUE_NAME; + @RuleNode( type = ComponentType.TRANSFORMATION, name = "deduplication", configClazz = TbMsgDeduplicationNodeConfiguration.class, + version = 1, hasQueueName = true, nodeDescription = "Deduplicate messages within the same originator entity for a configurable period " + "based on a specified deduplication strategy.", @@ -94,6 +98,22 @@ public class TbMsgDeduplicationNode implements TbNode { deduplicationMap.clear(); } + @Override + public TbPair upgrade(int fromVersion, JsonNode oldConfiguration) throws TbNodeException { + boolean hasChanges = false; + switch (fromVersion) { + case 0: + if (oldConfiguration.has(QUEUE_NAME)) { + hasChanges = true; + ((ObjectNode) oldConfiguration).remove(QUEUE_NAME); + } + break; + default: + break; + } + return new TbPair<>(hasChanges, oldConfiguration); + } + private void processOnRegularMsg(TbContext ctx, TbMsg msg) { EntityId id = msg.getOriginator(); DeduplicationData deduplicationMsgs = deduplicationMap.computeIfAbsent(id, k -> new DeduplicationData()); diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/flow/TbCheckpointNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/flow/TbCheckpointNode.java index eb658ada68..8fe2de58b2 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/flow/TbCheckpointNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/flow/TbCheckpointNode.java @@ -15,6 +15,8 @@ */ package org.thingsboard.rule.engine.flow; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ObjectNode; import lombok.extern.slf4j.Slf4j; import org.thingsboard.rule.engine.api.EmptyNodeConfiguration; import org.thingsboard.rule.engine.api.RuleNode; @@ -25,13 +27,17 @@ import org.thingsboard.rule.engine.api.TbNodeException; import org.thingsboard.server.common.data.msg.TbNodeConnectionType; import org.thingsboard.rule.engine.api.util.TbNodeUtils; import org.thingsboard.server.common.data.plugin.ComponentType; +import org.thingsboard.server.common.data.util.TbPair; import org.thingsboard.server.common.msg.TbMsg; +import static org.thingsboard.rule.engine.api.util.TbNodeUtils.QUEUE_NAME; + @Slf4j @RuleNode( type = ComponentType.FLOW, name = "checkpoint", configClazz = EmptyNodeConfiguration.class, + version = 1, hasQueueName = true, nodeDescription = "transfers the message to another queue", nodeDetails = "After successful transfer incoming message is automatically acknowledged. Queue name is configurable.", @@ -52,4 +58,20 @@ public class TbCheckpointNode implements TbNode { ctx.enqueueForTellNext(msg, queueName, TbNodeConnectionType.SUCCESS, () -> ctx.ack(msg), error -> ctx.tellFailure(msg, error)); } + @Override + public TbPair upgrade(int fromVersion, JsonNode oldConfiguration) throws TbNodeException { + boolean hasChanges = false; + switch (fromVersion) { + case 0: + if (oldConfiguration.has(QUEUE_NAME)) { + hasChanges = true; + ((ObjectNode) oldConfiguration).remove(QUEUE_NAME); + } + break; + default: + break; + } + return new TbPair<>(hasChanges, oldConfiguration); + } + } From 1e2c7f95791f4340e1156608634b19f7089f94a9 Mon Sep 17 00:00:00 2001 From: YevhenBondarenko Date: Wed, 13 Dec 2023 10:35:13 +0100 Subject: [PATCH 004/179] refactoring --- .../server/actors/ruleChain/DefaultTbContext.java | 9 +++++++-- .../org/thingsboard/rule/engine/api/TbContext.java | 2 ++ .../rule/engine/debug/TbMsgGeneratorNode.java | 2 +- .../engine/deduplication/TbMsgDeduplicationNode.java | 2 +- .../rule/engine/flow/TbCheckpointNode.java | 2 +- .../engine/transform/TbMsgDeduplicationNodeTest.java | 11 ++--------- 6 files changed, 14 insertions(+), 14 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/actors/ruleChain/DefaultTbContext.java b/application/src/main/java/org/thingsboard/server/actors/ruleChain/DefaultTbContext.java index bf61cf7a59..0d1a65d899 100644 --- a/application/src/main/java/org/thingsboard/server/actors/ruleChain/DefaultTbContext.java +++ b/application/src/main/java/org/thingsboard/server/actors/ruleChain/DefaultTbContext.java @@ -185,7 +185,7 @@ class DefaultTbContext implements TbContext { @Override public void enqueue(TbMsg tbMsg, Runnable onSuccess, Consumer onFailure) { - TopicPartitionInfo tpi = mainCtx.resolve(ServiceType.TB_RULE_ENGINE, nodeCtx.getSelf().getQueueName(), getTenantId(), tbMsg.getOriginator()); + TopicPartitionInfo tpi = mainCtx.resolve(ServiceType.TB_RULE_ENGINE, getQueueName(), getTenantId(), tbMsg.getOriginator()); enqueue(tpi, tbMsg, onFailure, onSuccess); } @@ -310,7 +310,7 @@ class DefaultTbContext implements TbContext { @Override public boolean isLocalEntity(EntityId entityId) { - return mainCtx.resolve(ServiceType.TB_RULE_ENGINE, nodeCtx.getSelf().getQueueName(), getTenantId(), entityId).isMyPartition(); + return mainCtx.resolve(ServiceType.TB_RULE_ENGINE, getQueueName(), getTenantId(), entityId).isMyPartition(); } private void scheduleMsgWithDelay(TbActorMsg msg, long delayInMs, TbActorRef target) { @@ -509,6 +509,11 @@ class DefaultTbContext implements TbContext { return ruleChainName; } + @Override + public String getQueueName() { + return getSelf().getQueueName(); + } + @Override public TenantId getTenantId() { return nodeCtx.getTenantId(); diff --git a/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/TbContext.java b/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/TbContext.java index 40ed2c378a..241e20115f 100644 --- a/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/TbContext.java +++ b/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/TbContext.java @@ -255,6 +255,8 @@ public interface TbContext { String getRuleChainName(); + String getQueueName(); + TenantId getTenantId(); AttributesService getAttributesService(); diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/debug/TbMsgGeneratorNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/debug/TbMsgGeneratorNode.java index 80170a28f1..cec7aca0a3 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/debug/TbMsgGeneratorNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/debug/TbMsgGeneratorNode.java @@ -83,7 +83,7 @@ public class TbMsgGeneratorNode implements TbNode { this.config = TbNodeUtils.convert(configuration, TbMsgGeneratorNodeConfiguration.class); this.delay = TimeUnit.SECONDS.toMillis(config.getPeriodInSeconds()); this.currentMsgCount = 0; - this.queueName = ctx.getSelf().getQueueName(); + this.queueName = ctx.getQueueName(); if (!StringUtils.isEmpty(config.getOriginatorId())) { originatorId = EntityIdFactory.getByTypeAndUuid(config.getOriginatorType(), config.getOriginatorId()); ctx.checkTenantEntity(originatorId); diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/deduplication/TbMsgDeduplicationNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/deduplication/TbMsgDeduplicationNode.java index 8f818583e8..17b72cd27a 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/deduplication/TbMsgDeduplicationNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/deduplication/TbMsgDeduplicationNode.java @@ -81,7 +81,7 @@ public class TbMsgDeduplicationNode implements TbNode { public void init(TbContext ctx, TbNodeConfiguration configuration) throws TbNodeException { this.config = TbNodeUtils.convert(configuration, TbMsgDeduplicationNodeConfiguration.class); this.deduplicationInterval = TimeUnit.SECONDS.toMillis(config.getInterval()); - this.queueName = ctx.getSelf().getQueueName(); + this.queueName = ctx.getQueueName(); } @Override diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/flow/TbCheckpointNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/flow/TbCheckpointNode.java index 8fe2de58b2..9616d8a167 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/flow/TbCheckpointNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/flow/TbCheckpointNode.java @@ -50,7 +50,7 @@ public class TbCheckpointNode implements TbNode { @Override public void init(TbContext ctx, TbNodeConfiguration configuration) throws TbNodeException { - this.queueName = ctx.getSelf().getQueueName(); + this.queueName = ctx.getQueueName(); } @Override diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/transform/TbMsgDeduplicationNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/transform/TbMsgDeduplicationNodeTest.java index ac3f2acfd5..8e8340c713 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/transform/TbMsgDeduplicationNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/transform/TbMsgDeduplicationNodeTest.java @@ -94,7 +94,6 @@ public class TbMsgDeduplicationNodeTest { when(ctx.getSelfId()).thenReturn(ruleNodeId); when(ctx.getTenantId()).thenReturn(tenantId); - when(ctx.getSelf()).thenReturn(new RuleNode()); doAnswer((Answer) invocationOnMock -> { TbMsgType type = (TbMsgType) (invocationOnMock.getArguments())[1]; @@ -240,10 +239,10 @@ public class TbMsgDeduplicationNodeTest { awaitTellSelfLatch = new CountDownLatch(wantedNumberOfTellSelfInvocation); invokeTellSelf(wantedNumberOfTellSelfInvocation); + when(ctx.getQueueName()).thenReturn(DataConstants.HP_QUEUE_NAME); config.setInterval(deduplicationInterval); config.setStrategy(DeduplicationStrategy.ALL); config.setOutMsgType(TbMsgType.POST_ATTRIBUTES_REQUEST.name()); - setQueueName(DataConstants.HP_QUEUE_NAME); nodeConfiguration = new TbNodeConfiguration(JacksonUtil.valueToTree(config)); node.init(ctx, nodeConfiguration); @@ -280,10 +279,10 @@ public class TbMsgDeduplicationNodeTest { awaitTellSelfLatch = new CountDownLatch(wantedNumberOfTellSelfInvocation); invokeTellSelf(wantedNumberOfTellSelfInvocation, true, 3); + when(ctx.getQueueName()).thenReturn(DataConstants.HP_QUEUE_NAME); config.setInterval(deduplicationInterval); config.setStrategy(DeduplicationStrategy.ALL); config.setOutMsgType(TbMsgType.POST_ATTRIBUTES_REQUEST.name()); - setQueueName(DataConstants.HP_QUEUE_NAME); nodeConfiguration = new TbNodeConfiguration(JacksonUtil.valueToTree(config)); node.init(ctx, nodeConfiguration); @@ -431,10 +430,4 @@ public class TbMsgDeduplicationNodeTest { return JacksonUtil.toString(mergedData); } - private void setQueueName(String queueName) { - RuleNode ruleNode = new RuleNode(); - ruleNode.setQueueName(queueName); - when(ctx.getSelf()).thenReturn(ruleNode); - } - } From 65a8b0a34c4972793f1c41f32761853d640fd871 Mon Sep 17 00:00:00 2001 From: YevhenBondarenko Date: Wed, 13 Dec 2023 23:13:05 +0100 Subject: [PATCH 005/179] added test for singleton mqtt node --- .../server/msa/ContainerTestSuite.java | 2 + .../server/msa/TestProperties.java | 9 + .../server/msa/TestRestClient.java | 41 ++++ .../server/msa/rule/node/MqttNodeTest.java | 204 ++++++++++++++++++ .../resources/MqttRuleNodeTestMetadata.json | 79 +++++++ .../resources/docker-compose.mosquitto.yml | 25 +++ .../test/resources/mosquitto/mosquitto.conf | 18 ++ 7 files changed, 378 insertions(+) create mode 100644 msa/black-box-tests/src/test/java/org/thingsboard/server/msa/rule/node/MqttNodeTest.java create mode 100644 msa/black-box-tests/src/test/resources/MqttRuleNodeTestMetadata.json create mode 100644 msa/black-box-tests/src/test/resources/docker-compose.mosquitto.yml create mode 100644 msa/black-box-tests/src/test/resources/mosquitto/mosquitto.conf diff --git a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ContainerTestSuite.java b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ContainerTestSuite.java index dd3948c495..142b42e5b2 100644 --- a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ContainerTestSuite.java +++ b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ContainerTestSuite.java @@ -107,6 +107,7 @@ public class ContainerTestSuite { List composeFiles = new ArrayList<>(Arrays.asList( new File(targetDir + "docker-compose.yml"), new File(targetDir + "docker-compose.volumes.yml"), + new File(targetDir + "docker-compose.mosquitto.yml"), new File(targetDir + (IS_HYBRID_MODE ? "docker-compose.hybrid.yml" : "docker-compose.postgres.yml")), new File(targetDir + (IS_HYBRID_MODE ? "docker-compose.hybrid-test-extras.yml" : "docker-compose.postgres-test-extras.yml")), new File(targetDir + "docker-compose.postgres.volumes.yml"), @@ -162,6 +163,7 @@ public class ContainerTestSuite { .withEnv(queueEnv) .withEnv("LOAD_BALANCER_NAME", "") .withExposedService("haproxy", 80, Wait.forHttp("/swagger-ui.html").withStartupTimeout(CONTAINER_STARTUP_TIMEOUT)) + .withExposedService("broker", 1883) .waitingFor("tb-core1", Wait.forLogMessage(TB_CORE_LOG_REGEXP, 1).withStartupTimeout(CONTAINER_STARTUP_TIMEOUT)) .waitingFor("tb-core2", Wait.forLogMessage(TB_CORE_LOG_REGEXP, 1).withStartupTimeout(CONTAINER_STARTUP_TIMEOUT)) .waitingFor("tb-http-transport1", Wait.forLogMessage(TRANSPORTS_LOG_REGEXP, 1).withStartupTimeout(CONTAINER_STARTUP_TIMEOUT)) diff --git a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/TestProperties.java b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/TestProperties.java index a70d1022ce..26f9da3618 100644 --- a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/TestProperties.java +++ b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/TestProperties.java @@ -48,4 +48,13 @@ public class TestProperties { } return System.getProperty("tb.wsUrl", "ws://localhost:8080"); } + + public static String getMqttBrokerUrl() { + if (instance.isActive()) { + String host = instance.getTestContainer().getServiceHost("broker", 1883); + Integer port = instance.getTestContainer().getServicePort("broker", 1883); + return "tcp://" + host + ":" + port; + } + return System.getProperty("mqtt.broker", "tcp://localhost:1883"); + } } diff --git a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/TestRestClient.java b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/TestRestClient.java index f04331e01e..a675ef4a20 100644 --- a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/TestRestClient.java +++ b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/TestRestClient.java @@ -31,10 +31,12 @@ import org.thingsboard.server.common.data.Dashboard; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.DeviceProfile; import org.thingsboard.server.common.data.EntityView; +import org.thingsboard.server.common.data.EventInfo; import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.alarm.Alarm; import org.thingsboard.server.common.data.asset.Asset; import org.thingsboard.server.common.data.asset.AssetProfile; +import org.thingsboard.server.common.data.event.EventType; import org.thingsboard.server.common.data.id.AlarmId; import org.thingsboard.server.common.data.id.AssetId; import org.thingsboard.server.common.data.id.AssetProfileId; @@ -45,9 +47,11 @@ import org.thingsboard.server.common.data.id.DeviceProfileId; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.EntityViewId; import org.thingsboard.server.common.data.id.RuleChainId; +import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.UserId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; +import org.thingsboard.server.common.data.page.TimePageLink; import org.thingsboard.server.common.data.relation.EntityRelation; import org.thingsboard.server.common.data.relation.RelationTypeGroup; import org.thingsboard.server.common.data.rule.RuleChain; @@ -527,4 +531,41 @@ public class TestRestClient { .then() .statusCode(HTTP_OK); } + + public PageData getEvents(EntityId entityId, EventType eventType, TenantId tenantId, TimePageLink pageLink) { + Map params = new HashMap<>(); + params.put("entityType", entityId.getEntityType().name()); + params.put("entityId", entityId.getId().toString()); + params.put("eventType", eventType.name()); + params.put("tenantId", tenantId.getId().toString()); + addTimePageLinkToParam(params, pageLink); + + return given().spec(requestSpec) + .get("/api/events/{entityType}/{entityId}/{eventType}?tenantId={tenantId}&" + getTimeUrlParams(pageLink), params) + .then() + .statusCode(HTTP_OK) + .extract() + .as(new TypeRef<>() {}); + } + + private void addTimePageLinkToParam(Map params, TimePageLink pageLink) { + this.addPageLinkToParam(params, pageLink); + if (pageLink.getStartTime() != null) { + params.put("startTime", String.valueOf(pageLink.getStartTime())); + } + if (pageLink.getEndTime() != null) { + params.put("endTime", String.valueOf(pageLink.getEndTime())); + } + } + + private String getTimeUrlParams(TimePageLink pageLink) { + String urlParams = getUrlParams(pageLink); + if (pageLink.getStartTime() != null) { + urlParams += "&startTime={startTime}"; + } + if (pageLink.getEndTime() != null) { + urlParams += "&endTime={endTime}"; + } + return urlParams; + } } diff --git a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/rule/node/MqttNodeTest.java b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/rule/node/MqttNodeTest.java new file mode 100644 index 0000000000..5aa0ae48fb --- /dev/null +++ b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/rule/node/MqttNodeTest.java @@ -0,0 +1,204 @@ +/** + * Copyright © 2016-2023 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.server.msa.rule.node; + +import com.fasterxml.jackson.databind.JsonNode; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; +import org.awaitility.Awaitility; +import org.eclipse.paho.client.mqttv3.IMqttMessageListener; +import org.eclipse.paho.client.mqttv3.MqttClient; +import org.eclipse.paho.client.mqttv3.MqttConnectOptions; +import org.eclipse.paho.client.mqttv3.MqttMessage; +import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; +import org.thingsboard.common.util.JacksonUtil; +import org.thingsboard.server.common.data.Device; +import org.thingsboard.server.common.data.EventInfo; +import org.thingsboard.server.common.data.StringUtils; +import org.thingsboard.server.common.data.event.EventType; +import org.thingsboard.server.common.data.id.RuleChainId; +import org.thingsboard.server.common.data.page.PageData; +import org.thingsboard.server.common.data.page.PageLink; +import org.thingsboard.server.common.data.page.TimePageLink; +import org.thingsboard.server.common.data.rule.NodeConnectionInfo; +import org.thingsboard.server.common.data.rule.RuleChain; +import org.thingsboard.server.common.data.rule.RuleChainMetaData; +import org.thingsboard.server.common.data.rule.RuleNode; +import org.thingsboard.server.common.data.security.DeviceCredentials; +import org.thingsboard.server.msa.AbstractContainerTest; +import org.thingsboard.server.msa.DisableUIListeners; +import org.thingsboard.server.msa.TestProperties; +import org.thingsboard.server.msa.WsClient; +import org.thingsboard.server.msa.mapper.WsTelemetryResponse; + +import java.util.Arrays; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.testng.Assert.fail; +import static org.thingsboard.server.msa.prototypes.DevicePrototypes.defaultDevicePrototype; + +@DisableUIListeners +@Slf4j +public class MqttNodeTest extends AbstractContainerTest { + + private static final String TOPIC = "tb/mqtt/device"; + + private Device device; + + @BeforeMethod + public void setUp() { + testRestClient.login("tenant@thingsboard.org", "tenant"); + device = testRestClient.postDevice("", defaultDevicePrototype("mqtt_")); + } + + @AfterMethod + public void tearDown() { + testRestClient.deleteDeviceIfExists(device.getId()); + } + + @Test + public void telemetryUpload() throws Exception { + RuleChainId defaultRuleChainId = getDefaultRuleChainId(); + + createRootRuleChainWithTestNode("MqttRuleNodeTestMetadata.json", "org.thingsboard.rule.engine.mqtt.TbMqttNode", 2); + + DeviceCredentials deviceCredentials = testRestClient.getDeviceCredentialsByDeviceId(device.getId()); + + WsClient wsClient = subscribeToWebSocket(device.getId(), "LATEST_TELEMETRY", CmdsType.TS_SUB_CMDS); + + MqttMessageListener messageListener = new MqttMessageListener(); + MqttClient responseClient = new MqttClient(TestProperties.getMqttBrokerUrl(), StringUtils.randomAlphanumeric(10), new MemoryPersistence()); + responseClient.connect(); + responseClient.subscribe(TOPIC, messageListener); + + MqttClient mqttClient = new MqttClient("tcp://localhost:1883", StringUtils.randomAlphanumeric(10), new MemoryPersistence()); + MqttConnectOptions mqttConnectOptions = new MqttConnectOptions(); + mqttConnectOptions.setUserName(deviceCredentials.getCredentialsId()); + mqttClient.connect(mqttConnectOptions); + mqttClient.publish("v1/devices/me/telemetry", new MqttMessage(createPayload().toString().getBytes())); + + WsTelemetryResponse actualLatestTelemetry = wsClient.getLastMessage(); + log.info("Received telemetry: {}", actualLatestTelemetry); + wsClient.closeBlocking(); + + assertThat(actualLatestTelemetry.getData()).hasSize(4); + assertThat(actualLatestTelemetry.getLatestValues().keySet()).containsOnlyOnceElementsOf(Arrays.asList("booleanKey", "stringKey", "doubleKey", "longKey")); + + assertThat(actualLatestTelemetry.getDataValuesByKey("booleanKey").get(1)).isEqualTo(Boolean.TRUE.toString()); + assertThat(actualLatestTelemetry.getDataValuesByKey("stringKey").get(1)).isEqualTo("value1"); + assertThat(actualLatestTelemetry.getDataValuesByKey("doubleKey").get(1)).isEqualTo(Double.toString(42.0)); + assertThat(actualLatestTelemetry.getDataValuesByKey("longKey").get(1)).isEqualTo(Long.toString(73)); + + Awaitility + .await() + .alias("Get integration events") + .atMost(10, TimeUnit.SECONDS) + .until(() -> messageListener.getEvents().size() > 0); + + BlockingQueue events = messageListener.getEvents(); + JsonNode actual = JacksonUtil.toJsonNode(Objects.requireNonNull(events.poll()).message); + + assertThat(actual.get("stringKey").asText()).isEqualTo("value1"); + assertThat(actual.get("booleanKey").asBoolean()).isEqualTo(Boolean.TRUE); + assertThat(actual.get("doubleKey").asDouble()).isEqualTo(42.0); + assertThat(actual.get("longKey").asLong()).isEqualTo(73); + + testRestClient.setRootRuleChain(defaultRuleChainId); + } + + @Data + private class MqttMessageListener implements IMqttMessageListener { + private final BlockingQueue events; + + private MqttMessageListener() { + events = new ArrayBlockingQueue<>(100); + } + + @Override + public void messageArrived(String s, MqttMessage mqttMessage) { + log.info("MQTT message [{}], topic [{}]", mqttMessage.toString(), s); + events.add(new MqttEvent(s, mqttMessage.toString())); + } + + public BlockingQueue getEvents() { + return events; + } + } + + @Data + private class MqttEvent { + private final String topic; + private final String message; + } + + private RuleChainId getDefaultRuleChainId() { + PageData ruleChains = testRestClient.getRuleChains(new PageLink(40, 0)); + + Optional defaultRuleChain = ruleChains.getData() + .stream() + .filter(RuleChain::isRoot) + .findFirst(); + if (!defaultRuleChain.isPresent()) { + fail("Root rule chain wasn't found"); + } + return defaultRuleChain.get().getId(); + } + + protected RuleChainId createRootRuleChainWithTestNode(String ruleChainMetadataFile, String ruleNodeType, int eventsCount) throws Exception { + RuleChain newRuleChain = new RuleChain(); + newRuleChain.setName("testRuleChain"); + RuleChain ruleChain = testRestClient.postRuleChain(newRuleChain); + + JsonNode configuration = JacksonUtil.OBJECT_MAPPER.readTree(this.getClass().getClassLoader().getResourceAsStream(ruleChainMetadataFile)); + RuleChainMetaData ruleChainMetaData = new RuleChainMetaData(); + ruleChainMetaData.setRuleChainId(ruleChain.getId()); + ruleChainMetaData.setFirstNodeIndex(configuration.get("firstNodeIndex").asInt()); + ruleChainMetaData.setNodes(Arrays.asList(JacksonUtil.OBJECT_MAPPER.treeToValue(configuration.get("nodes"), RuleNode[].class))); + ruleChainMetaData.setConnections(Arrays.asList(JacksonUtil.OBJECT_MAPPER.treeToValue(configuration.get("connections"), NodeConnectionInfo[].class))); + + ruleChainMetaData = testRestClient.postRuleChainMetadata(ruleChainMetaData); + + testRestClient.setRootRuleChain(ruleChain.getId()); + + RuleNode node = ruleChainMetaData.getNodes().stream().filter(ruleNode -> ruleNode.getType().equals(ruleNodeType)).findFirst().get(); + + Awaitility + .await() + .alias("Get events from rule chain") + .atMost(10, TimeUnit.SECONDS) + .until(() -> { + PageData events = testRestClient.getEvents(node.getId(), EventType.LC_EVENT, ruleChain.getTenantId(), new TimePageLink(1024)); + List eventInfos = events.getData().stream().filter(eventInfo -> + "STARTED".equals(eventInfo.getBody().get("event").asText()) && + "true".equals(eventInfo.getBody().get("success").asText())) + .collect(Collectors.toList()); + + return eventInfos.size() == eventsCount; + }); + + return ruleChain.getId(); + } +} diff --git a/msa/black-box-tests/src/test/resources/MqttRuleNodeTestMetadata.json b/msa/black-box-tests/src/test/resources/MqttRuleNodeTestMetadata.json new file mode 100644 index 0000000000..e6c9f5a53f --- /dev/null +++ b/msa/black-box-tests/src/test/resources/MqttRuleNodeTestMetadata.json @@ -0,0 +1,79 @@ +{ + "firstNodeIndex": 2, + "nodes": [ + { + "additionalInfo": { + "description": "", + "layoutX": 626, + "layoutY": 152 + }, + "type": "org.thingsboard.rule.engine.mqtt.TbMqttNode", + "name": "test mqtt", + "debugMode": true, + "singletonMode": true, + "queueName": "HighPriority", + "configurationVersion": 0, + "configuration": { + "topicPattern": "tb/mqtt/device", + "host": "broker", + "port": 1883, + "connectTimeoutSec": 10, + "clientId": null, + "cleanSession": true, + "retainedMessage": false, + "ssl": false, + "credentials": { + "type": "anonymous" + } + }, + "externalId": null + }, + { + "additionalInfo": { + "description": "", + "layoutX": 949, + "layoutY": 153 + }, + "type": "org.thingsboard.rule.engine.telemetry.TbMsgTimeseriesNode", + "name": "save timeseries", + "debugMode": true, + "singletonMode": false, + "configurationVersion": 0, + "configuration": { + "defaultTTL": 0, + "skipLatestPersistence": false, + "useServerTs": false + }, + "externalId": null + }, + { + "additionalInfo": { + "description": "", + "layoutX": 305, + "layoutY": 151 + }, + "type": "org.thingsboard.rule.engine.filter.TbMsgTypeSwitchNode", + "name": "swatch", + "debugMode": false, + "singletonMode": false, + "configurationVersion": 0, + "configuration": { + "version": 0 + }, + "externalId": null + } + ], + "connections": [ + { + "fromIndex": 0, + "toIndex": 1, + "type": "Success" + }, + { + "fromIndex": 2, + "toIndex": 0, + "type": "Post telemetry" + } + ], + "ruleChainConnections": null +} \ No newline at end of file diff --git a/msa/black-box-tests/src/test/resources/docker-compose.mosquitto.yml b/msa/black-box-tests/src/test/resources/docker-compose.mosquitto.yml new file mode 100644 index 0000000000..10675c9a23 --- /dev/null +++ b/msa/black-box-tests/src/test/resources/docker-compose.mosquitto.yml @@ -0,0 +1,25 @@ +# +# Copyright © 2016-2023 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. +# + +version: '3.0' +services: + broker: + image: eclipse-mosquitto + volumes: + - ./mosquitto/mosquitto.conf:/mosquitto/config/mosquitto.conf + ports: + - "1883" + restart: always diff --git a/msa/black-box-tests/src/test/resources/mosquitto/mosquitto.conf b/msa/black-box-tests/src/test/resources/mosquitto/mosquitto.conf new file mode 100644 index 0000000000..7a40d338fc --- /dev/null +++ b/msa/black-box-tests/src/test/resources/mosquitto/mosquitto.conf @@ -0,0 +1,18 @@ +# +# Copyright © 2016-2023 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. +# + +listener 1883 +allow_anonymous true From 4101fc3963c7269455076fb6d83af16ba0cd7016 Mon Sep 17 00:00:00 2001 From: YevhenBondarenko Date: Thu, 14 Dec 2023 21:14:31 +0100 Subject: [PATCH 006/179] added upgrade tests, and minor fixes --- .../install/ThingsboardInstallService.java | 1 - .../server/utils/TbNodeUpgradeUtils.java | 2 +- .../server/common/data/DataConstants.java | 1 + .../data/plugin/ComponentDescriptor.java | 2 +- .../resources/MqttRuleNodeTestMetadata.json | 4 +- .../rule/engine/api/util/TbNodeUtils.java | 2 - .../rule/engine/debug/TbMsgGeneratorNode.java | 2 +- .../deduplication/TbMsgDeduplicationNode.java | 4 +- .../rule/engine/flow/TbCheckpointNode.java | 2 +- .../engine/AbstractRuleNodeUpgradeTest.java | 52 ++++++++++++++++++ .../engine/debug/TbMsgGeneratorNodeTest.java | 53 ++++++++++++++++++ .../engine/flow/TbCheckpointNodeTest.java | 55 +++++++++++++++++++ .../telemetry/TbMsgAttributesNodeTest.java | 25 ++------- .../transform/TbMsgDeduplicationNodeTest.java | 35 +++++++++++- 14 files changed, 207 insertions(+), 33 deletions(-) create mode 100644 rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/AbstractRuleNodeUpgradeTest.java create mode 100644 rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/debug/TbMsgGeneratorNodeTest.java create mode 100644 rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/flow/TbCheckpointNodeTest.java diff --git a/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java b/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java index 054c7a6751..4c9677494b 100644 --- a/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java +++ b/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java @@ -277,7 +277,6 @@ public class ThingsboardInstallService { } else { log.info("Skipping images migration. Run the upgrade with fromVersion as '3.6.2-images' to migrate"); } - break; case "3.6.2": log.info("Upgrading ThingsBoard from version 3.6.2 to 3.6.3 ..."); databaseEntitiesUpgradeService.upgradeDatabase("3.6.2"); diff --git a/application/src/main/java/org/thingsboard/server/utils/TbNodeUpgradeUtils.java b/application/src/main/java/org/thingsboard/server/utils/TbNodeUpgradeUtils.java index 23c75b430b..e0ecfdd038 100644 --- a/application/src/main/java/org/thingsboard/server/utils/TbNodeUpgradeUtils.java +++ b/application/src/main/java/org/thingsboard/server/utils/TbNodeUpgradeUtils.java @@ -25,7 +25,7 @@ import org.thingsboard.server.common.data.rule.RuleNode; import org.thingsboard.server.common.data.util.TbPair; import org.thingsboard.server.service.component.RuleNodeClassInfo; -import static org.thingsboard.rule.engine.api.util.TbNodeUtils.QUEUE_NAME; +import static org.thingsboard.server.common.data.DataConstants.QUEUE_NAME; @Slf4j public class TbNodeUpgradeUtils { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/DataConstants.java b/common/data/src/main/java/org/thingsboard/server/common/data/DataConstants.java index ca48ef364a..14142de3db 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/DataConstants.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/DataConstants.java @@ -135,5 +135,6 @@ public class DataConstants { public static final String HP_QUEUE_TOPIC = "tb_rule_engine.hp"; public static final String SQ_QUEUE_NAME = "SequentialByOriginator"; public static final String SQ_QUEUE_TOPIC = "tb_rule_engine.sq"; + public static final String QUEUE_NAME = "queueName"; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/plugin/ComponentDescriptor.java b/common/data/src/main/java/org/thingsboard/server/common/data/plugin/ComponentDescriptor.java index 0e9b31ec09..1558080d42 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/plugin/ComponentDescriptor.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/plugin/ComponentDescriptor.java @@ -55,7 +55,7 @@ public class ComponentDescriptor extends BaseData { @Length(fieldName = "actions") @ApiModelProperty(position = 10, value = "Rule Node Actions. Deprecated. Always null.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) @Getter @Setter private String actions; - @ApiModelProperty(position = 11, value = "Indicates that the RuleNode is support queue name.", accessMode = ApiModelProperty.AccessMode.READ_ONLY, example = "true") + @ApiModelProperty(position = 11, value = "Indicates that the RuleNode supports queue name configuration.", accessMode = ApiModelProperty.AccessMode.READ_ONLY, example = "true") @Getter @Setter private boolean hasQueueName; public ComponentDescriptor() { diff --git a/msa/black-box-tests/src/test/resources/MqttRuleNodeTestMetadata.json b/msa/black-box-tests/src/test/resources/MqttRuleNodeTestMetadata.json index e6c9f5a53f..7a5015add3 100644 --- a/msa/black-box-tests/src/test/resources/MqttRuleNodeTestMetadata.json +++ b/msa/black-box-tests/src/test/resources/MqttRuleNodeTestMetadata.json @@ -53,7 +53,7 @@ "layoutY": 151 }, "type": "org.thingsboard.rule.engine.filter.TbMsgTypeSwitchNode", - "name": "swatch", + "name": "switch", "debugMode": false, "singletonMode": false, "configurationVersion": 0, @@ -76,4 +76,4 @@ } ], "ruleChainConnections": null -} \ No newline at end of file +} diff --git a/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/util/TbNodeUtils.java b/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/util/TbNodeUtils.java index cce5649336..7c3be84410 100644 --- a/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/util/TbNodeUtils.java +++ b/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/util/TbNodeUtils.java @@ -36,8 +36,6 @@ import java.util.stream.Collectors; */ public class TbNodeUtils { - public static final String QUEUE_NAME = "queueName"; - private static final Pattern DATA_PATTERN = Pattern.compile("(\\$\\[)(.*?)(])"); public static T convert(TbNodeConfiguration configuration, Class clazz) throws TbNodeException { diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/debug/TbMsgGeneratorNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/debug/TbMsgGeneratorNode.java index cec7aca0a3..689e14429f 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/debug/TbMsgGeneratorNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/debug/TbMsgGeneratorNode.java @@ -47,7 +47,7 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import static org.thingsboard.common.util.DonAsynchron.withCallback; -import static org.thingsboard.rule.engine.api.util.TbNodeUtils.QUEUE_NAME; +import static org.thingsboard.server.common.data.DataConstants.QUEUE_NAME; @Slf4j @RuleNode( diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/deduplication/TbMsgDeduplicationNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/deduplication/TbMsgDeduplicationNode.java index 17b72cd27a..dc7f2ee07f 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/deduplication/TbMsgDeduplicationNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/deduplication/TbMsgDeduplicationNode.java @@ -44,7 +44,7 @@ import java.util.Optional; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; -import static org.thingsboard.rule.engine.api.util.TbNodeUtils.QUEUE_NAME; +import static org.thingsboard.server.common.data.DataConstants.QUEUE_NAME; @RuleNode( type = ComponentType.TRANSFORMATION, @@ -177,7 +177,7 @@ public class TbMsgDeduplicationNode implements TbNode { } if (resultMsg != null) { deduplicationResults.add(TbMsg.newMsg( - resultMsg.getQueueName(), + queueName, resultMsg.getType(), resultMsg.getOriginator(), resultMsg.getCustomerId(), diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/flow/TbCheckpointNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/flow/TbCheckpointNode.java index 9616d8a167..c7e775f5a4 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/flow/TbCheckpointNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/flow/TbCheckpointNode.java @@ -30,7 +30,7 @@ import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.data.util.TbPair; import org.thingsboard.server.common.msg.TbMsg; -import static org.thingsboard.rule.engine.api.util.TbNodeUtils.QUEUE_NAME; +import static org.thingsboard.server.common.data.DataConstants.QUEUE_NAME; @Slf4j @RuleNode( diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/AbstractRuleNodeUpgradeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/AbstractRuleNodeUpgradeTest.java new file mode 100644 index 0000000000..6e665357bc --- /dev/null +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/AbstractRuleNodeUpgradeTest.java @@ -0,0 +1,52 @@ +/** + * Copyright © 2016-2023 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; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ObjectNode; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; +import org.thingsboard.common.util.JacksonUtil; +import org.thingsboard.rule.engine.api.TbNode; +import org.thingsboard.rule.engine.api.TbNodeException; +import org.thingsboard.server.common.data.util.TbPair; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.BDDMockito.willCallRealMethod; + +public abstract class AbstractRuleNodeUpgradeTest { + + protected abstract TbNode getTestNode(); + + @ParameterizedTest + @MethodSource + public void givenFromVersionAndConfig_whenUpgrade_thenVerifyHasChangesAndConfig(int givenVersion, String givenConfigStr, boolean hasChanges, String expectedConfigStr) throws TbNodeException { + // GIVEN + willCallRealMethod().given(getTestNode()).upgrade(anyInt(), any()); + JsonNode givenConfig = JacksonUtil.toJsonNode(givenConfigStr); + JsonNode expectedConfig = JacksonUtil.toJsonNode(expectedConfigStr); + + // WHEN + TbPair upgradeResult = getTestNode().upgrade(givenVersion, givenConfig); + + // THEN + assertThat(upgradeResult.getFirst()).isEqualTo(hasChanges); + ObjectNode upgradedConfig = (ObjectNode) upgradeResult.getSecond(); + assertThat(upgradedConfig).isEqualTo(expectedConfig); + } +} diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/debug/TbMsgGeneratorNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/debug/TbMsgGeneratorNodeTest.java new file mode 100644 index 0000000000..2e188bf002 --- /dev/null +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/debug/TbMsgGeneratorNodeTest.java @@ -0,0 +1,53 @@ +/** + * Copyright © 2016-2023 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.debug; + +import org.junit.jupiter.params.provider.Arguments; +import org.thingsboard.rule.engine.AbstractRuleNodeUpgradeTest; +import org.thingsboard.rule.engine.api.TbNode; + +import java.util.stream.Stream; + +import static org.mockito.Mockito.spy; + +public class TbMsgGeneratorNodeTest extends AbstractRuleNodeUpgradeTest { + + // Rule nodes upgrade + private static Stream givenFromVersionAndConfig_whenUpgrade_thenVerifyHasChangesAndConfig() { + return Stream.of( + // default config for version 0 + Arguments.of(0, + "{\"msgCount\":0,\"periodInSeconds\":1,\"originatorId\":null,\"originatorType\":null, \"queueName\":null, \"scriptLang\":\"TBEL\",\"jsScript\":\"var msg = { temp: 42, humidity: 77 };\\nvar metadata = { data: 40 };\\nvar msgType = \\\"POST_TELEMETRY_REQUEST\\\";\\n\\nreturn { msg: msg, metadata: metadata, msgType: msgType };\",\"tbelScript\":\"var msg = { temp: 42, humidity: 77 };\\nvar metadata = { data: 40 };\\nvar msgType = \\\"POST_TELEMETRY_REQUEST\\\";\\n\\nreturn { msg: msg, metadata: metadata, msgType: msgType };\"}", + true, + "{\"msgCount\":0,\"periodInSeconds\":1,\"originatorId\":null,\"originatorType\":null, \"scriptLang\":\"TBEL\",\"jsScript\":\"var msg = { temp: 42, humidity: 77 };\\nvar metadata = { data: 40 };\\nvar msgType = \\\"POST_TELEMETRY_REQUEST\\\";\\n\\nreturn { msg: msg, metadata: metadata, msgType: msgType };\",\"tbelScript\":\"var msg = { temp: 42, humidity: 77 };\\nvar metadata = { data: 40 };\\nvar msgType = \\\"POST_TELEMETRY_REQUEST\\\";\\n\\nreturn { msg: msg, metadata: metadata, msgType: msgType };\"}"), + // default config for version 0 with queueName + Arguments.of(0, + "{\"msgCount\":0,\"periodInSeconds\":1,\"originatorId\":null,\"originatorType\":null, \"queueName\":\"Main\", \"scriptLang\":\"TBEL\",\"jsScript\":\"var msg = { temp: 42, humidity: 77 };\\nvar metadata = { data: 40 };\\nvar msgType = \\\"POST_TELEMETRY_REQUEST\\\";\\n\\nreturn { msg: msg, metadata: metadata, msgType: msgType };\",\"tbelScript\":\"var msg = { temp: 42, humidity: 77 };\\nvar metadata = { data: 40 };\\nvar msgType = \\\"POST_TELEMETRY_REQUEST\\\";\\n\\nreturn { msg: msg, metadata: metadata, msgType: msgType };\"}", + true, + "{\"msgCount\":0,\"periodInSeconds\":1,\"originatorId\":null,\"originatorType\":null, \"scriptLang\":\"TBEL\",\"jsScript\":\"var msg = { temp: 42, humidity: 77 };\\nvar metadata = { data: 40 };\\nvar msgType = \\\"POST_TELEMETRY_REQUEST\\\";\\n\\nreturn { msg: msg, metadata: metadata, msgType: msgType };\",\"tbelScript\":\"var msg = { temp: 42, humidity: 77 };\\nvar metadata = { data: 40 };\\nvar msgType = \\\"POST_TELEMETRY_REQUEST\\\";\\n\\nreturn { msg: msg, metadata: metadata, msgType: msgType };\"}"), + // default config for version 1 with upgrade from version 0 + Arguments.of(0, + "{\"msgCount\":0,\"periodInSeconds\":1,\"originatorId\":null,\"originatorType\":null, \"scriptLang\":\"TBEL\",\"jsScript\":\"var msg = { temp: 42, humidity: 77 };\\nvar metadata = { data: 40 };\\nvar msgType = \\\"POST_TELEMETRY_REQUEST\\\";\\n\\nreturn { msg: msg, metadata: metadata, msgType: msgType };\",\"tbelScript\":\"var msg = { temp: 42, humidity: 77 };\\nvar metadata = { data: 40 };\\nvar msgType = \\\"POST_TELEMETRY_REQUEST\\\";\\n\\nreturn { msg: msg, metadata: metadata, msgType: msgType };\"}", + false, + "{\"msgCount\":0,\"periodInSeconds\":1,\"originatorId\":null,\"originatorType\":null, \"scriptLang\":\"TBEL\",\"jsScript\":\"var msg = { temp: 42, humidity: 77 };\\nvar metadata = { data: 40 };\\nvar msgType = \\\"POST_TELEMETRY_REQUEST\\\";\\n\\nreturn { msg: msg, metadata: metadata, msgType: msgType };\",\"tbelScript\":\"var msg = { temp: 42, humidity: 77 };\\nvar metadata = { data: 40 };\\nvar msgType = \\\"POST_TELEMETRY_REQUEST\\\";\\n\\nreturn { msg: msg, metadata: metadata, msgType: msgType };\"}") + ); + } + + @Override + protected TbNode getTestNode() { + return spy(TbMsgGeneratorNode.class); + } +} \ No newline at end of file diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/flow/TbCheckpointNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/flow/TbCheckpointNodeTest.java new file mode 100644 index 0000000000..edb7a7c3b1 --- /dev/null +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/flow/TbCheckpointNodeTest.java @@ -0,0 +1,55 @@ +/** + * Copyright © 2016-2023 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.flow; + +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.params.provider.Arguments; +import org.thingsboard.rule.engine.AbstractRuleNodeUpgradeTest; +import org.thingsboard.rule.engine.api.TbNode; + +import java.util.stream.Stream; + +import static org.mockito.Mockito.spy; + +@Slf4j +public class TbCheckpointNodeTest extends AbstractRuleNodeUpgradeTest { + + // Rule nodes upgrade + private static Stream givenFromVersionAndConfig_whenUpgrade_thenVerifyHasChangesAndConfig() { + return Stream.of( + // default config for version 0 + Arguments.of(0, + "{\"queueName\":null}", + true, + "{}"), + // default config for version 0 with queueName + Arguments.of(0, + "{\"queueName\":\"Main\"}", + true, + "{}"), + // default config for version 1 with upgrade from version 0 + Arguments.of(0, + "{}", + false, + "{}") + ); + } + + @Override + protected TbNode getTestNode() { + return spy(TbCheckpointNode.class); + } +} \ No newline at end of file diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/telemetry/TbMsgAttributesNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/telemetry/TbMsgAttributesNodeTest.java index fe2edc941b..d59e416fcf 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/telemetry/TbMsgAttributesNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/telemetry/TbMsgAttributesNodeTest.java @@ -15,7 +15,6 @@ */ package org.thingsboard.rule.engine.telemetry; -import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ObjectNode; import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.BeforeEach; @@ -25,8 +24,10 @@ import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; import org.mockito.ArgumentCaptor; import org.thingsboard.common.util.JacksonUtil; +import org.thingsboard.rule.engine.AbstractRuleNodeUpgradeTest; import org.thingsboard.rule.engine.api.RuleEngineTelemetryService; import org.thingsboard.rule.engine.api.TbContext; +import org.thingsboard.rule.engine.api.TbNode; import org.thingsboard.rule.engine.api.TbNodeConfiguration; import org.thingsboard.rule.engine.api.TbNodeException; import org.thingsboard.server.common.data.DataConstants; @@ -40,7 +41,6 @@ import org.thingsboard.server.common.data.kv.JsonDataEntry; import org.thingsboard.server.common.data.kv.LongDataEntry; import org.thingsboard.server.common.data.kv.StringDataEntry; import org.thingsboard.server.common.data.msg.TbMsgType; -import org.thingsboard.server.common.data.util.TbPair; import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsgMetaData; @@ -53,7 +53,6 @@ import java.util.stream.Stream; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; -import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.BDDMockito.willCallRealMethod; @@ -65,7 +64,7 @@ import static org.mockito.Mockito.when; import static org.thingsboard.server.common.data.DataConstants.NOTIFY_DEVICE_METADATA_KEY; @Slf4j -class TbMsgAttributesNodeTest { +class TbMsgAttributesNodeTest extends AbstractRuleNodeUpgradeTest { private TenantId tenantId; private DeviceId deviceId; @@ -223,21 +222,9 @@ class TbMsgAttributesNodeTest { ); } - @ParameterizedTest - @MethodSource - void givenFromVersionAndConfig_whenUpgrade_thenVerifyHasChangesAndConfig(int givenVersion, String givenConfigStr, boolean hasChanges, String expectedConfigStr) throws TbNodeException { - // GIVEN - willCallRealMethod().given(node).upgrade(anyInt(), any()); - JsonNode givenConfig = JacksonUtil.toJsonNode(givenConfigStr); - JsonNode expectedConfig = JacksonUtil.toJsonNode(expectedConfigStr); - - // WHEN - TbPair upgradeResult = node.upgrade(givenVersion, givenConfig); - - // THEN - assertThat(upgradeResult.getFirst()).isEqualTo(hasChanges); - ObjectNode upgradedConfig = (ObjectNode) upgradeResult.getSecond(); - assertThat(upgradedConfig).isEqualTo(expectedConfig); + @Override + protected TbNode getTestNode() { + return node; } } diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/transform/TbMsgDeduplicationNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/transform/TbMsgDeduplicationNodeTest.java index 8e8340c713..b5bbcdc0fe 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/transform/TbMsgDeduplicationNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/transform/TbMsgDeduplicationNodeTest.java @@ -22,12 +22,15 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.provider.Arguments; import org.mockito.ArgumentCaptor; import org.mockito.ArgumentMatchers; import org.mockito.stubbing.Answer; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.common.util.ThingsBoardThreadFactory; +import org.thingsboard.rule.engine.AbstractRuleNodeUpgradeTest; import org.thingsboard.rule.engine.api.TbContext; +import org.thingsboard.rule.engine.api.TbNode; import org.thingsboard.rule.engine.api.TbNodeConfiguration; import org.thingsboard.rule.engine.api.TbNodeException; import org.thingsboard.rule.engine.deduplication.DeduplicationStrategy; @@ -40,7 +43,6 @@ import org.thingsboard.server.common.data.id.RuleNodeId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.msg.TbMsgType; import org.thingsboard.server.common.data.msg.TbNodeConnectionType; -import org.thingsboard.server.common.data.rule.RuleNode; import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsgMetaData; @@ -56,6 +58,7 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; import java.util.function.Consumer; +import java.util.stream.Stream; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; @@ -69,7 +72,7 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @Slf4j -public class TbMsgDeduplicationNodeTest { +public class TbMsgDeduplicationNodeTest extends AbstractRuleNodeUpgradeTest { private TbContext ctx; @@ -293,7 +296,7 @@ public class TbMsgDeduplicationNodeTest { for (TbMsg msg : firstMsgPack) { node.onMsg(ctx, msg); } - long firstPackDeduplicationPackEndTs = firstMsgPack.get(0).getMetaDataTs() + TimeUnit.SECONDS.toMillis(deduplicationInterval); + long firstPackDeduplicationPackEndTs = firstMsgPack.get(0).getMetaDataTs() + TimeUnit.SECONDS.toMillis(deduplicationInterval); List secondMsgPack = getTbMsgs(deviceId, msgCount / 2, firstPackDeduplicationPackEndTs, 500); for (TbMsg msg : secondMsgPack) { @@ -386,6 +389,27 @@ public class TbMsgDeduplicationNodeTest { Assertions.assertEquals(msgWithLatestTsInSecondPack.getType(), actualMsg.getType()); } + // Rule nodes upgrade + private static Stream givenFromVersionAndConfig_whenUpgrade_thenVerifyHasChangesAndConfig() { + return Stream.of( + // default config for version 0 + Arguments.of(0, + "{\"interval\":60,\"strategy\":\"FIRST\",\"outMsgType\":null,\"maxPendingMsgs\":100,\"maxRetries\":3, \"queueName\":null}", + true, + "{\"interval\":60,\"strategy\":\"FIRST\",\"outMsgType\":null,\"maxPendingMsgs\":100,\"maxRetries\":3}"), + // default config for version 0 with queueName + Arguments.of(0, + "{\"interval\":60,\"strategy\":\"FIRST\",\"outMsgType\":null,\"maxPendingMsgs\":100,\"maxRetries\":3, \"queueName\":\"Main\"}", + true, + "{\"interval\":60,\"strategy\":\"FIRST\",\"outMsgType\":null,\"maxPendingMsgs\":100,\"maxRetries\":3}"), + // default config for version 1 with upgrade from version 0 + Arguments.of(0, + "{\"interval\":60,\"strategy\":\"FIRST\",\"outMsgType\":null,\"maxPendingMsgs\":100,\"maxRetries\":3}", + false, + "{\"interval\":60,\"strategy\":\"FIRST\",\"outMsgType\":null,\"maxPendingMsgs\":100,\"maxRetries\":3}") + ); + } + private TbMsg getMsgWithLatestTs(List firstMsgPack) { int indexOfLastMsgInArray = firstMsgPack.size() - 1; int indexToSetMaxTs = new Random().nextInt(indexOfLastMsgInArray) + 1; @@ -430,4 +454,9 @@ public class TbMsgDeduplicationNodeTest { return JacksonUtil.toString(mergedData); } + @Override + protected TbNode getTestNode() { + return node; + } + } From fe6ca79c4154cd16ff243a26a822beb1dbe07522 Mon Sep 17 00:00:00 2001 From: YevhenBondarenko Date: Mon, 18 Dec 2023 15:31:23 +0100 Subject: [PATCH 007/179] minor improvements --- .../deduplication/TbMsgDeduplicationNode.java | 2 +- .../engine/debug/TbMsgGeneratorNodeTest.java | 2 +- .../engine/flow/TbCheckpointNodeTest.java | 2 +- .../transform/TbMsgDeduplicationNodeTest.java | 23 +++++++++++++++++-- 4 files changed, 24 insertions(+), 5 deletions(-) diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/deduplication/TbMsgDeduplicationNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/deduplication/TbMsgDeduplicationNode.java index dc7f2ee07f..4e83b1887b 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/deduplication/TbMsgDeduplicationNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/deduplication/TbMsgDeduplicationNode.java @@ -177,7 +177,7 @@ public class TbMsgDeduplicationNode implements TbNode { } if (resultMsg != null) { deduplicationResults.add(TbMsg.newMsg( - queueName, + queueName != null ? queueName : resultMsg.getQueueName(), resultMsg.getType(), resultMsg.getOriginator(), resultMsg.getCustomerId(), diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/debug/TbMsgGeneratorNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/debug/TbMsgGeneratorNodeTest.java index 2e188bf002..f0ba55e03b 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/debug/TbMsgGeneratorNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/debug/TbMsgGeneratorNodeTest.java @@ -50,4 +50,4 @@ public class TbMsgGeneratorNodeTest extends AbstractRuleNodeUpgradeTest { protected TbNode getTestNode() { return spy(TbMsgGeneratorNode.class); } -} \ No newline at end of file +} diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/flow/TbCheckpointNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/flow/TbCheckpointNodeTest.java index edb7a7c3b1..c7d50528d5 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/flow/TbCheckpointNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/flow/TbCheckpointNodeTest.java @@ -52,4 +52,4 @@ public class TbCheckpointNodeTest extends AbstractRuleNodeUpgradeTest { protected TbNode getTestNode() { return spy(TbCheckpointNode.class); } -} \ No newline at end of file +} diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/transform/TbMsgDeduplicationNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/transform/TbMsgDeduplicationNodeTest.java index b5bbcdc0fe..89eda98090 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/transform/TbMsgDeduplicationNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/transform/TbMsgDeduplicationNodeTest.java @@ -22,7 +22,9 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; import org.mockito.ArgumentCaptor; import org.mockito.ArgumentMatchers; import org.mockito.stubbing.Answer; @@ -143,13 +145,24 @@ public class TbMsgDeduplicationNodeTest extends AbstractRuleNodeUpgradeTest { node.destroy(); } - @Test - public void given_100_messages_strategy_first_then_verifyOutput() throws TbNodeException, ExecutionException, InterruptedException { + private static Stream given_100_messages_strategy_first_then_verifyOutput() { + return Stream.of( + Arguments.of((String) null), + Arguments.of(DataConstants.MAIN_QUEUE_NAME), + Arguments.of(DataConstants.HP_QUEUE_NAME) + ); + } + + @ParameterizedTest + @MethodSource + public void given_100_messages_strategy_first_then_verifyOutput(String queueName) throws TbNodeException, ExecutionException, InterruptedException { int wantedNumberOfTellSelfInvocation = 2; int msgCount = 100; awaitTellSelfLatch = new CountDownLatch(wantedNumberOfTellSelfInvocation); invokeTellSelf(wantedNumberOfTellSelfInvocation); + when(ctx.getQueueName()).thenReturn(queueName); + config.setInterval(deduplicationInterval); config.setMaxPendingMsgs(msgCount); nodeConfiguration = new TbNodeConfiguration(JacksonUtil.valueToTree(config)); @@ -186,6 +199,12 @@ public class TbMsgDeduplicationNodeTest extends AbstractRuleNodeUpgradeTest { Assertions.assertEquals(firstMsg.getData(), actualMsg.getData()); Assertions.assertEquals(firstMsg.getMetaData(), actualMsg.getMetaData()); Assertions.assertEquals(firstMsg.getType(), actualMsg.getType()); + + if (queueName == null) { + Assertions.assertEquals(firstMsg.getQueueName(), actualMsg.getQueueName()); + } else { + Assertions.assertEquals(ctx.getQueueName(), actualMsg.getQueueName()); + } } @Test From 1fdbba6fc6897921928ef70b563d69bc7c44c8fa Mon Sep 17 00:00:00 2001 From: Dmitriymush Date: Tue, 19 Dec 2023 13:44:28 +0200 Subject: [PATCH 008/179] UI: fixed initial value for targetDashboardId valueChanges pipe --- .../widget/action/widget-action-dialog.component.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/ui-ngx/src/app/modules/home/components/widget/action/widget-action-dialog.component.ts b/ui-ngx/src/app/modules/home/components/widget/action/widget-action-dialog.component.ts index 06cb6b1106..0aeed84e5e 100644 --- a/ui-ngx/src/app/modules/home/components/widget/action/widget-action-dialog.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/action/widget-action-dialog.component.ts @@ -225,7 +225,7 @@ export class WidgetActionDialogComponent extends DialogComponent(targetDashboardId), + dashboardControl.valueChanges.pipe( + startWith(dashboardControl.value), tap(() => { this.targetDashboardStateSearchText = ''; }), From 98086153dd02886022062e7c847f841a33179d91 Mon Sep 17 00:00:00 2001 From: rusikv Date: Wed, 20 Dec 2023 13:50:54 +0200 Subject: [PATCH 009/179] UI: added search to rule chain selector --- .../rulechain/rulechain-page.component.html | 2 +- .../rule-chain-select-panel.component.html | 42 +++++ .../rule-chain-select-panel.component.scss | 18 +++ .../rule-chain-select-panel.component.ts | 143 ++++++++++++++++++ .../rule-chain-select.component.html | 20 +-- .../rule-chain-select.component.scss | 27 ++-- .../rule-chain/rule-chain-select.component.ts | 93 ++++++++---- ui-ngx/src/app/shared/shared.module.ts | 3 + 8 files changed, 292 insertions(+), 56 deletions(-) create mode 100644 ui-ngx/src/app/shared/components/rule-chain/rule-chain-select-panel.component.html create mode 100644 ui-ngx/src/app/shared/components/rule-chain/rule-chain-select-panel.component.scss create mode 100644 ui-ngx/src/app/shared/components/rule-chain/rule-chain-select-panel.component.ts diff --git a/ui-ngx/src/app/modules/home/pages/rulechain/rulechain-page.component.html b/ui-ngx/src/app/modules/home/pages/rulechain/rulechain-page.component.html index 6911558ad4..1e41e72543 100644 --- a/ui-ngx/src/app/modules/home/pages/rulechain/rulechain-page.component.html +++ b/ui-ngx/src/app/modules/home/pages/rulechain/rulechain-page.component.html @@ -34,7 +34,7 @@ *ngIf="!isImport" [ruleChainType]="ruleChainType" [disabled]="isDirtyValue" - [(ngModel)]="ruleChain.id.id" + [(ngModel)]="ruleChain" (ngModelChange)="currentRuleChainIdChanged(ruleChain.id?.id)"> diff --git a/ui-ngx/src/app/shared/components/rule-chain/rule-chain-select-panel.component.html b/ui-ngx/src/app/shared/components/rule-chain/rule-chain-select-panel.component.html new file mode 100644 index 0000000000..d022de9e83 --- /dev/null +++ b/ui-ngx/src/app/shared/components/rule-chain/rule-chain-select-panel.component.html @@ -0,0 +1,42 @@ + + + + search + + + + + +
+ + {{ translate.get('rulechain.no-rulechains-matching', {entity: searchText}) | async }} + +
+
+
+
+ diff --git a/ui-ngx/src/app/shared/components/rule-chain/rule-chain-select-panel.component.scss b/ui-ngx/src/app/shared/components/rule-chain/rule-chain-select-panel.component.scss new file mode 100644 index 0000000000..758b1f9bcd --- /dev/null +++ b/ui-ngx/src/app/shared/components/rule-chain/rule-chain-select-panel.component.scss @@ -0,0 +1,18 @@ +/** + * Copyright © 2016-2023 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. + */ +:host { + width: 100%; +} diff --git a/ui-ngx/src/app/shared/components/rule-chain/rule-chain-select-panel.component.ts b/ui-ngx/src/app/shared/components/rule-chain/rule-chain-select-panel.component.ts new file mode 100644 index 0000000000..ea9762b6ab --- /dev/null +++ b/ui-ngx/src/app/shared/components/rule-chain/rule-chain-select-panel.component.ts @@ -0,0 +1,143 @@ +/// +/// Copyright © 2016-2023 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 { + AfterViewInit, + Component, + ElementRef, + Inject, + InjectionToken, + OnDestroy, + ViewChild +} from '@angular/core'; +import { FormBuilder, FormGroup } from '@angular/forms'; +import { Observable, of, Subject } from 'rxjs'; +import { catchError, debounceTime, distinctUntilChanged, map, switchMap, takeUntil, startWith, share } from 'rxjs/operators'; +import { PageLink } from '@shared/models/page/page-link'; +import { Direction } from '@shared/models/page/sort-order'; +import { emptyPageData, PageData } from '@shared/models/page/page-data'; +import { OverlayRef } from '@angular/cdk/overlay'; +import { MatAutocompleteSelectedEvent } from '@angular/material/autocomplete'; +import { RuleChain, RuleChainType } from '@shared/models/rule-chain.models'; +import { RuleChainService } from '@core/http/rule-chain.service'; +import { TranslateService } from '@ngx-translate/core'; + +export const RULE_CHAIN_SELECT_PANEL_DATA = new InjectionToken('RuleChainSelectPanelData'); + +export interface RuleChainSelectPanelData { + ruleChainId: string | null; + ruleChainType: RuleChainType; +} + +@Component({ + selector: 'tb-rule-chain-select-panel', + templateUrl: './rule-chain-select-panel.component.html', + styleUrls: ['./rule-chain-select-panel.component.scss'] +}) +export class RuleChainSelectPanelComponent implements AfterViewInit, OnDestroy { + + ruleChainId: string; + ruleChainType: RuleChainType; + + selectRuleChainGroup: FormGroup; + + @ViewChild('ruleChainInput', {static: true}) userInput: ElementRef; + + filteredRuleChains: Observable>; + + searchText = ''; + + ruleChainSelected = false; + + result?: RuleChain; + + private dirty = false; + private destroy$ = new Subject(); + + constructor(@Inject(RULE_CHAIN_SELECT_PANEL_DATA) public data: RuleChainSelectPanelData, + public overlayRef: OverlayRef, + public translate: TranslateService, + private fb: FormBuilder, + private ruleChainService: RuleChainService) { + this.ruleChainId = data.ruleChainId; + this.ruleChainType = data.ruleChainType; + this.selectRuleChainGroup = this.fb.group({ + ruleChainInput: ['', {nonNullable: true}] + }); + this.filteredRuleChains = this.selectRuleChainGroup.get('ruleChainInput').valueChanges + .pipe( + debounceTime(150), + startWith(''), + distinctUntilChanged((a: string, b: string) => a.trim() === b.trim()), + switchMap(name => this.fetchRuleChains(name)), + share(), + takeUntil(this.destroy$) + ); + } + + ngAfterViewInit() { + setTimeout(() => { + this.userInput.nativeElement.focus(); + }, 0); + } + + ngOnDestroy() { + this.destroy$.next(); + this.destroy$.complete(); + } + + selected(event: MatAutocompleteSelectedEvent): void { + this.clear(); + this.ruleChainSelected = true; + if (event.option.value?.id) { + this.result = event.option.value; + } + this.overlayRef.dispose(); + } + + fetchRuleChains(searchText?: string): Observable> { + this.searchText = searchText; + const pageLink = new PageLink(50, 0, searchText, { + property: 'name', + direction: Direction.ASC + }); + return this.getRuleChains(pageLink) + .pipe( + catchError(() => of(emptyPageData())), + map(pageData => pageData.data) + ); + } + + onFocus(): void { + if (!this.dirty) { + this.selectRuleChainGroup.get('ruleChainInput').updateValueAndValidity({onlySelf: true}); + this.dirty = true; + } + } + + clear() { + this.selectRuleChainGroup.get('ruleChainInput').patchValue('', {emitEvent: true}); + setTimeout(() => { + this.userInput.nativeElement.blur(); + this.userInput.nativeElement.focus(); + }, 0); + } + + private getRuleChains(pageLink: PageLink): Observable> { + return this.ruleChainService.getRuleChains(pageLink, this.ruleChainType, {ignoreLoading: true}); + } + +} diff --git a/ui-ngx/src/app/shared/components/rule-chain/rule-chain-select.component.html b/ui-ngx/src/app/shared/components/rule-chain/rule-chain-select.component.html index 1d699b5857..899a43a781 100644 --- a/ui-ngx/src/app/shared/components/rule-chain/rule-chain-select.component.html +++ b/ui-ngx/src/app/shared/components/rule-chain/rule-chain-select.component.html @@ -15,17 +15,13 @@ limitations under the License. --> - + settings_ethernet - - - {{ruleChain.name}} - - + + arrow_drop_down diff --git a/ui-ngx/src/app/shared/components/rule-chain/rule-chain-select.component.scss b/ui-ngx/src/app/shared/components/rule-chain/rule-chain-select.component.scss index 9cbb97cba9..4487ebb092 100644 --- a/ui-ngx/src/app/shared/components/rule-chain/rule-chain-select.component.scss +++ b/ui-ngx/src/app/shared/components/rule-chain/rule-chain-select.component.scss @@ -19,19 +19,22 @@ padding: 0; .tb-rule-select { width: 100%; - } - .tb-rule-chain-select { - display: flex; - min-height: 100%; - pointer-events: all; - } -} -:host ::ng-deep { - .mat-mdc-form-field.tb-rule-select .mdc-text-field { - .mat-mdc-form-field-infix { - min-height: 48px; - padding: 12px 0; + input { + color: #fff; + cursor: pointer; + + &:disabled { + cursor: unset; + } } } } + +.cursor-pointer { + cursor: pointer; +} + +.disabled { + opacity: 0.5; +} diff --git a/ui-ngx/src/app/shared/components/rule-chain/rule-chain-select.component.ts b/ui-ngx/src/app/shared/components/rule-chain/rule-chain-select.component.ts index d9f2f90cc8..df566748f0 100644 --- a/ui-ngx/src/app/shared/components/rule-chain/rule-chain-select.component.ts +++ b/ui-ngx/src/app/shared/components/rule-chain/rule-chain-select.component.ts @@ -14,20 +14,20 @@ /// limitations under the License. /// -import { Component, forwardRef, Input, OnInit } from '@angular/core'; +import { Component, forwardRef, Injector, Input, StaticProvider, ViewContainerRef } from '@angular/core'; import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; -import { Observable } from 'rxjs'; -import { PageLink } from '@shared/models/page/page-link'; -import { map, share } from 'rxjs/operators'; -import { PageData } from '@shared/models/page/page-data'; -import { Store } from '@ngrx/store'; -import { AppState } from '@app/core/core.state'; import { TooltipPosition } from '@angular/material/tooltip'; import { RuleChain, RuleChainType } from '@shared/models/rule-chain.models'; import { RuleChainService } from '@core/http/rule-chain.service'; import { isDefinedAndNotNull } from '@core/utils'; import { coerceBoolean } from '@shared/decorators/coercion'; -import { Direction } from '@shared/models/page/sort-order'; +import { Overlay, OverlayConfig, OverlayRef } from '@angular/cdk/overlay'; +import { + RULE_CHAIN_SELECT_PANEL_DATA, RuleChainSelectPanelComponent, + RuleChainSelectPanelData +} from '@shared/components/rule-chain/rule-chain-select-panel.component'; +import { ComponentPortal } from '@angular/cdk/portal'; +import { POSITION_MAP } from '@shared/models/overlay.models'; @Component({ selector: 'tb-rule-chain-select', @@ -39,7 +39,7 @@ import { Direction } from '@shared/models/page/sort-order'; multi: true }] }) -export class RuleChainSelectComponent implements ControlValueAccessor, OnInit { +export class RuleChainSelectComponent implements ControlValueAccessor { @Input() tooltipPosition: TooltipPosition = 'above'; @@ -55,25 +55,15 @@ export class RuleChainSelectComponent implements ControlValueAccessor, OnInit { @Input() ruleChainType: RuleChainType = RuleChainType.CORE; - ruleChains$: Observable>; + ruleChain: RuleChain | null; - ruleChainId: string | null; + panelOpened = false; private propagateChange = (v: any) => { }; - constructor(private ruleChainService: RuleChainService) { - } - - ngOnInit() { - const pageLink = new PageLink(1024, 0, null, { - property: 'name', - direction: Direction.ASC - }); - - this.ruleChains$ = this.getRuleChains(pageLink).pipe( - map((pageData) => pageData.data), - share() - ); + constructor(private ruleChainService: RuleChainService, + private overlay: Overlay, + private viewContainerRef: ViewContainerRef) { } registerOnChange(fn: any): void { @@ -83,14 +73,13 @@ export class RuleChainSelectComponent implements ControlValueAccessor, OnInit { registerOnTouched(fn: any): void { } - setDisabledState(isDisabled: boolean): void { this.disabled = isDisabled; } - writeValue(value: string | null): void { + writeValue(value: RuleChain): void { if (isDefinedAndNotNull(value)) { - this.ruleChainId = value; + this.ruleChain = value; } } @@ -98,12 +87,54 @@ export class RuleChainSelectComponent implements ControlValueAccessor, OnInit { this.updateView(); } - private updateView() { - this.propagateChange(this.ruleChainId); + openRuleChainSelectPanel($event: Event) { + if ($event) { + $event.stopPropagation(); + } + if (!this.disabled) { + const target = $event.currentTarget; + const config = new OverlayConfig({ + panelClass: 'tb-filter-panel', + backdropClass: 'cdk-overlay-transparent-backdrop', + hasBackdrop: true, + width: (target as HTMLElement).offsetWidth + }); + config.positionStrategy = this.overlay.position() + .flexibleConnectedTo(target as HTMLElement) + .withPositions([POSITION_MAP.bottom]); + const overlayRef = this.overlay.create(config); + overlayRef.backdropClick().subscribe(() => { + overlayRef.dispose(); + }); + const providers: StaticProvider[] = [ + { + provide: RULE_CHAIN_SELECT_PANEL_DATA, + useValue: { + ruleChainId: this.ruleChain.id?.id, + ruleChainType: this.ruleChainType + } as RuleChainSelectPanelData + }, + { + provide: OverlayRef, + useValue: overlayRef + } + ]; + const injector = Injector.create({parent: this.viewContainerRef.injector, providers}); + const componentRef = overlayRef.attach(new ComponentPortal(RuleChainSelectPanelComponent, + this.viewContainerRef, injector)); + this.panelOpened = true; + componentRef.onDestroy(() => { + this.panelOpened = false; + if (componentRef.instance.ruleChainSelected) { + this.ruleChain = componentRef.instance.result; + this.updateView(); + } + }); + } } - private getRuleChains(pageLink: PageLink): Observable> { - return this.ruleChainService.getRuleChains(pageLink, this.ruleChainType, {ignoreLoading: true}); + private updateView() { + this.propagateChange(this.ruleChain); } } diff --git a/ui-ngx/src/app/shared/shared.module.ts b/ui-ngx/src/app/shared/shared.module.ts index bc03c47467..bb439e7283 100644 --- a/ui-ngx/src/app/shared/shared.module.ts +++ b/ui-ngx/src/app/shared/shared.module.ts @@ -215,6 +215,7 @@ import { ImagesInUseDialogComponent } from '@shared/components/image/images-in-u import { GalleryImageInputComponent } from '@shared/components/image/gallery-image-input.component'; import { MultipleGalleryImageInputComponent } from '@shared/components/image/multiple-gallery-image-input.component'; import { EmbedImageDialogComponent } from '@shared/components/image/embed-image-dialog.component'; +import { RuleChainSelectPanelComponent } from '@shared/components/rule-chain/rule-chain-select-panel.component'; export function MarkedOptionsFactory(markedOptionsService: MarkedOptionsService) { return markedOptionsService; @@ -396,6 +397,7 @@ export function MarkedOptionsFactory(markedOptionsService: MarkedOptionsService) StringAutocompleteComponent, MaterialIconsComponent, RuleChainSelectComponent, + RuleChainSelectPanelComponent, TbIconComponent, HintTooltipIconComponent, ImportDialogComponent, @@ -646,6 +648,7 @@ export function MarkedOptionsFactory(markedOptionsService: MarkedOptionsService) StringAutocompleteComponent, MaterialIconsComponent, RuleChainSelectComponent, + RuleChainSelectPanelComponent, TbIconComponent, HintTooltipIconComponent, ImportDialogComponent, From 661ab5b76f9188238155cdf7bb0ea3922577c71e Mon Sep 17 00:00:00 2001 From: Dmitriymush Date: Thu, 21 Dec 2023 17:54:32 +0200 Subject: [PATCH 010/179] UI: widget action dialog refactoring and improvements --- .../widget-action-dialog.component.html | 1 + .../action/widget-action-dialog.component.ts | 65 ++++++++++++++----- 2 files changed, 49 insertions(+), 17 deletions(-) diff --git a/ui-ngx/src/app/modules/home/components/widget/action/widget-action-dialog.component.html b/ui-ngx/src/app/modules/home/components/widget/action/widget-action-dialog.component.html index 7903388d84..57a21b6807 100644 --- a/ui-ngx/src/app/modules/home/components/widget/action/widget-action-dialog.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/action/widget-action-dialog.component.html @@ -97,6 +97,7 @@ #dashboardStateInput formControlName="targetDashboardStateId" [required]="widgetActionFormGroup.get('type').value === widgetActionType.openDashboardState" + (focusin)="onFocus()" [matAutocomplete]="targetDashboardStateAutocomplete"> \n \n \n \n \n
\n \n
\n \n tb.rulenode.alarm-type\n \n \n {{ \'tb.rulenode.alarm-type-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n\n',dependencies:[{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:de.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:ce.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ce.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:ye.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:xt,decorators:[{type:n,args:[{selector:"tb-action-node-clear-alarm-config",template:'
\n \n \n \n \n \n \n \n
\n \n
\n \n tb.rulenode.alarm-type\n \n \n {{ \'tb.rulenode.alarm-type-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder},{type:ie.NodeScriptTestService},{type:X.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}});class bt extends f{constructor(e,t,n,o){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=n,this.translate=o,this.alarmSeverities=Object.keys(h),this.alarmSeverityTranslationMap=v,this.separatorKeysCodes=[xe,be,he],this.tbelEnabled=ae(this.store).tbelEnabled,this.scriptLanguage=b,this.changeScript=new r,this.hasScript=!0,this.testScriptLabel="tb.rulenode.test-details-function"}configForm(){return this.createAlarmConfigForm}onConfigurationSet(e){this.createAlarmConfigForm=this.fb.group({scriptLang:[e?e.scriptLang:b.JS,[_.required]],alarmDetailsBuildJs:[e?e.alarmDetailsBuildJs:null,[]],alarmDetailsBuildTbel:[e?e.alarmDetailsBuildTbel:null,[]],useMessageAlarmData:[!!e&&e.useMessageAlarmData,[]],overwriteAlarmDetails:[!!e&&e.overwriteAlarmDetails,[]],alarmType:[e?e.alarmType:null,[]],severity:[e?e.severity:null,[]],propagate:[!!e&&e.propagate,[]],relationTypes:[e?e.relationTypes:null,[]],propagateToOwner:[!!e&&e.propagateToOwner,[]],propagateToTenant:[!!e&&e.propagateToTenant,[]],dynamicSeverity:!1}),this.createAlarmConfigForm.get("dynamicSeverity").valueChanges.subscribe((e=>{e?this.createAlarmConfigForm.get("severity").patchValue("",{emitEvent:!1}):this.createAlarmConfigForm.get("severity").patchValue(this.alarmSeverities[0],{emitEvent:!1})}))}validatorTriggers(){return["useMessageAlarmData","overwriteAlarmDetails","scriptLang"]}updateValidators(e){const t=this.createAlarmConfigForm.get("useMessageAlarmData").value,n=this.createAlarmConfigForm.get("overwriteAlarmDetails").value;t?(this.createAlarmConfigForm.get("alarmType").setValidators([]),this.createAlarmConfigForm.get("severity").setValidators([])):(this.createAlarmConfigForm.get("alarmType").setValidators([_.required]),this.createAlarmConfigForm.get("severity").setValidators([_.required])),this.createAlarmConfigForm.get("alarmType").updateValueAndValidity({emitEvent:e}),this.createAlarmConfigForm.get("severity").updateValueAndValidity({emitEvent:e});let r=this.createAlarmConfigForm.get("scriptLang").value;r!==b.TBEL||this.tbelEnabled||(r=b.JS,this.createAlarmConfigForm.get("scriptLang").patchValue(r,{emitEvent:!1}),setTimeout((()=>{this.createAlarmConfigForm.updateValueAndValidity({emitEvent:!0})})));const o=!1===t||!0===n;this.createAlarmConfigForm.get("alarmDetailsBuildJs").setValidators(o&&r===b.JS?[_.required]:[]),this.createAlarmConfigForm.get("alarmDetailsBuildTbel").setValidators(o&&r===b.TBEL?[_.required]:[]),this.createAlarmConfigForm.get("alarmDetailsBuildJs").updateValueAndValidity({emitEvent:e}),this.createAlarmConfigForm.get("alarmDetailsBuildTbel").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=b.JS)),e}testScript(e){const t=this.createAlarmConfigForm.get("scriptLang").value,n=t===b.JS?"alarmDetailsBuildJs":"alarmDetailsBuildTbel",r=t===b.JS?"rulenode/create_alarm_node_script_fn":"rulenode/tbel/create_alarm_node_script_fn",o=this.createAlarmConfigForm.get(n).value;this.nodeScriptTestService.testNodeScript(o,"json",this.translate.instant("tb.rulenode.details"),"Details",["msg","metadata","msgType"],this.ruleNodeId,r,t,e).subscribe((e=>{e&&(this.createAlarmConfigForm.get(n).setValue(e),this.changeScript.emit())}))}removeKey(e,t){const n=this.createAlarmConfigForm.get(t).value,r=n.indexOf(e);r>=0&&(n.splice(r,1),this.createAlarmConfigForm.get(t).setValue(n,{emitEvent:!0}))}addKey(e,t){const n=e.input;let r=e.value;if((r||"").trim()){r=r.trim();let e=this.createAlarmConfigForm.get(t).value;e&&-1!==e.indexOf(r)||(e||(e=[]),e.push(r),this.createAlarmConfigForm.get(t).setValue(e,{emitEvent:!0}))}n&&(n.value="")}onValidate(){const e=this.createAlarmConfigForm.get("useMessageAlarmData").value,t=this.createAlarmConfigForm.get("overwriteAlarmDetails").value;if(!e||t){this.createAlarmConfigForm.get("scriptLang").value===b.JS&&this.jsFuncComponent.validateOnSubmit()}}}e("CreateAlarmConfigComponent",bt),bt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:bt,deps:[{token:R.Store},{token:O.UntypedFormBuilder},{token:ie.NodeScriptTestService},{token:X.TranslateService}],target:t.ɵɵFactoryTarget.Component}),bt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:bt,selector:"tb-action-node-create-alarm-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.use-message-alarm-data\' | translate }}\n \n \n {{ \'tb.rulenode.overwrite-alarm-details\' | translate }}\n \n
\n \n \n \n \n \n \n \n
\n \n
\n
\n
\n \n tb.rulenode.alarm-type\n \n \n {{ \'tb.rulenode.alarm-type-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n {{ \'tb.rulenode.use-alarm-severity-pattern\' | translate }}\n \n \n tb.rulenode.alarm-severity\n \n \n {{ alarmSeverityTranslationMap.get(severity) | translate }}\n \n \n \n {{ \'tb.rulenode.alarm-severity-required\' | translate }}\n \n \n \n tb.rulenode.alarm-severity-pattern\n \n \n {{ \'tb.rulenode.alarm-severity-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.propagate\' | translate }}\n \n
\n \n tb.rulenode.relation-types-list\n \n \n {{key}}\n close\n \n \n \n tb.rulenode.relation-types-list-hint\n \n
\n \n {{ \'tb.rulenode.propagate-to-owner\' | translate }}\n \n \n {{ \'tb.rulenode.propagate-to-tenant\' | translate }}\n \n
\n
\n',dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:de.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:ce.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ce.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:J.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:ve.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:ve.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:ve.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:ve.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:ye.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:Ce.SafePipe,name:"safe"},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:bt,decorators:[{type:n,args:[{selector:"tb-action-node-create-alarm-config",template:'
\n \n {{ \'tb.rulenode.use-message-alarm-data\' | translate }}\n \n \n {{ \'tb.rulenode.overwrite-alarm-details\' | translate }}\n \n
\n \n \n \n \n \n \n \n
\n \n
\n
\n
\n \n tb.rulenode.alarm-type\n \n \n {{ \'tb.rulenode.alarm-type-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n {{ \'tb.rulenode.use-alarm-severity-pattern\' | translate }}\n \n \n tb.rulenode.alarm-severity\n \n \n {{ alarmSeverityTranslationMap.get(severity) | translate }}\n \n \n \n {{ \'tb.rulenode.alarm-severity-required\' | translate }}\n \n \n \n tb.rulenode.alarm-severity-pattern\n \n \n {{ \'tb.rulenode.alarm-severity-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.propagate\' | translate }}\n \n
\n \n tb.rulenode.relation-types-list\n \n \n {{key}}\n close\n \n \n \n tb.rulenode.relation-types-list-hint\n \n
\n \n {{ \'tb.rulenode.propagate-to-owner\' | translate }}\n \n \n {{ \'tb.rulenode.propagate-to-tenant\' | translate }}\n \n
\n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder},{type:ie.NodeScriptTestService},{type:X.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}});class ht extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.directionTypes=Object.keys(C),this.directionTypeTranslations=F,this.entityType=k}configForm(){return this.createRelationConfigForm}onConfigurationSet(e){this.createRelationConfigForm=this.fb.group({direction:[e?e.direction:null,[_.required]],entityType:[e?e.entityType:null,[_.required]],entityNamePattern:[e?e.entityNamePattern:null,[]],entityTypePattern:[e?e.entityTypePattern:null,[]],relationType:[e?e.relationType:null,[_.required]],createEntityIfNotExists:[!!e&&e.createEntityIfNotExists,[]],removeCurrentRelations:[!!e&&e.removeCurrentRelations,[]],changeOriginatorToRelatedEntity:[!!e&&e.changeOriginatorToRelatedEntity,[]],entityCacheExpiration:[e?e.entityCacheExpiration:null,[_.required,_.min(0)]]})}validatorTriggers(){return["entityType"]}updateValidators(e){const t=this.createRelationConfigForm.get("entityType").value;t?this.createRelationConfigForm.get("entityNamePattern").setValidators([_.required,_.pattern(/.*\S.*/)]):this.createRelationConfigForm.get("entityNamePattern").setValidators([]),!t||t!==k.DEVICE&&t!==k.ASSET?this.createRelationConfigForm.get("entityTypePattern").setValidators([]):this.createRelationConfigForm.get("entityTypePattern").setValidators([_.required,_.pattern(/.*\S.*/)]),this.createRelationConfigForm.get("entityNamePattern").updateValueAndValidity({emitEvent:e}),this.createRelationConfigForm.get("entityTypePattern").updateValueAndValidity({emitEvent:e})}prepareOutputConfig(e){return e.entityNamePattern=e.entityNamePattern?e.entityNamePattern.trim():null,e.entityTypePattern=e.entityTypePattern?e.entityTypePattern.trim():null,e}}e("CreateRelationConfigComponent",ht),ht.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ht,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),ht.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:ht,selector:"tb-action-node-create-relation-config",usesInheritance:!0,ngImport:t,template:'
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.entity-type-pattern\n \n \n {{ \'tb.rulenode.entity-type-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n
\n \n tb.rulenode.relation-type-pattern\n \n \n {{ \'tb.rulenode.relation-type-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n
\n \n {{ \'tb.rulenode.create-entity-if-not-exists\' | translate }}\n \n
tb.rulenode.create-entity-if-not-exists-hint
\n
\n \n {{ \'tb.rulenode.remove-current-relations\' | translate }}\n \n
tb.rulenode.remove-current-relations-hint
\n \n {{ \'tb.rulenode.change-originator-to-related-entity\' | translate }}\n \n
tb.rulenode.change-originator-to-related-entity-hint
\n \n tb.rulenode.entity-cache-expiration\n \n \n {{ \'tb.rulenode.entity-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.entity-cache-expiration-range\' | translate }}\n \n tb.rulenode.entity-cache-expiration-hint\n \n
\n',dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Fe.EntityTypeSelectComponent,selector:"tb-entity-type-select",inputs:["allowedEntityTypes","useAliasEntityTypes","filterAllowedEntityTypes","showLabel","required","disabled"]},{kind:"component",type:J.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ht,decorators:[{type:n,args:[{selector:"tb-action-node-create-relation-config",template:'
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.entity-type-pattern\n \n \n {{ \'tb.rulenode.entity-type-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n
\n \n tb.rulenode.relation-type-pattern\n \n \n {{ \'tb.rulenode.relation-type-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n
\n \n {{ \'tb.rulenode.create-entity-if-not-exists\' | translate }}\n \n
tb.rulenode.create-entity-if-not-exists-hint
\n
\n \n {{ \'tb.rulenode.remove-current-relations\' | translate }}\n \n
tb.rulenode.remove-current-relations-hint
\n \n {{ \'tb.rulenode.change-originator-to-related-entity\' | translate }}\n \n
tb.rulenode.change-originator-to-related-entity-hint
\n \n tb.rulenode.entity-cache-expiration\n \n \n {{ \'tb.rulenode.entity-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.entity-cache-expiration-range\' | translate }}\n \n tb.rulenode.entity-cache-expiration-hint\n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class vt extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.directionTypes=Object.keys(C),this.directionTypeTranslations=F,this.entityType=k}configForm(){return this.deleteRelationConfigForm}onConfigurationSet(e){this.deleteRelationConfigForm=this.fb.group({deleteForSingleEntity:[!!e&&e.deleteForSingleEntity,[]],direction:[e?e.direction:null,[_.required]],entityType:[e?e.entityType:null,[]],entityNamePattern:[e?e.entityNamePattern:null,[]],relationType:[e?e.relationType:null,[_.required]],entityCacheExpiration:[e?e.entityCacheExpiration:null,[_.required,_.min(0)]]})}validatorTriggers(){return["deleteForSingleEntity","entityType"]}updateValidators(e){const t=this.deleteRelationConfigForm.get("deleteForSingleEntity").value,n=this.deleteRelationConfigForm.get("entityType").value;t?this.deleteRelationConfigForm.get("entityType").setValidators([_.required]):this.deleteRelationConfigForm.get("entityType").setValidators([]),t&&n?this.deleteRelationConfigForm.get("entityNamePattern").setValidators([_.required,_.pattern(/.*\S.*/)]):this.deleteRelationConfigForm.get("entityNamePattern").setValidators([]),this.deleteRelationConfigForm.get("entityType").updateValueAndValidity({emitEvent:!1}),this.deleteRelationConfigForm.get("entityNamePattern").updateValueAndValidity({emitEvent:e})}prepareOutputConfig(e){return e.entityNamePattern=e.entityNamePattern?e.entityNamePattern.trim():null,e}}e("DeleteRelationConfigComponent",vt),vt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:vt,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),vt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:vt,selector:"tb-action-node-delete-relation-config",usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.delete-relation-to-specific-entity\' | translate }}\n \n
tb.rulenode.delete-relation-hint
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n
\n \n tb.rulenode.relation-type-pattern\n \n \n {{ \'tb.rulenode.relation-type-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.entity-cache-expiration\n \n \n {{ \'tb.rulenode.entity-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.entity-cache-expiration-range\' | translate }}\n \n tb.rulenode.entity-cache-expiration-hint\n \n
\n',dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Fe.EntityTypeSelectComponent,selector:"tb-entity-type-select",inputs:["allowedEntityTypes","useAliasEntityTypes","filterAllowedEntityTypes","showLabel","required","disabled"]},{kind:"component",type:J.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:vt,decorators:[{type:n,args:[{selector:"tb-action-node-delete-relation-config",template:'
\n \n {{ \'tb.rulenode.delete-relation-to-specific-entity\' | translate }}\n \n
tb.rulenode.delete-relation-hint
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n
\n \n tb.rulenode.relation-type-pattern\n \n \n {{ \'tb.rulenode.relation-type-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.entity-cache-expiration\n \n \n {{ \'tb.rulenode.entity-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.entity-cache-expiration-range\' | translate }}\n \n tb.rulenode.entity-cache-expiration-hint\n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class Ct extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.deviceProfile}onConfigurationSet(e){this.deviceProfile=this.fb.group({persistAlarmRulesState:[!!e&&e.persistAlarmRulesState,_.required],fetchAlarmRulesStateOnStart:[!!e&&e.fetchAlarmRulesStateOnStart,_.required]})}}e("DeviceProfileConfigComponent",Ct),Ct.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Ct,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Ct.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Ct,selector:"tb-device-profile-config",usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.persist-alarm-rules\' | translate }}\n \n \n {{ \'tb.rulenode.fetch-alarm-rules\' | translate }}\n \n
\n',dependencies:[{kind:"component",type:J.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Ct,decorators:[{type:n,args:[{selector:"tb-device-profile-config",template:'
\n \n {{ \'tb.rulenode.persist-alarm-rules\' | translate }}\n \n \n {{ \'tb.rulenode.fetch-alarm-rules\' | translate }}\n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class Ft extends f{constructor(e,t,n,o){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=n,this.translate=o,this.tbelEnabled=ae(this.store).tbelEnabled,this.scriptLanguage=b,this.changeScript=new r,this.hasScript=!0,this.testScriptLabel="tb.rulenode.test-generator-function",this.serviceType=x.TB_RULE_ENGINE}configForm(){return this.generatorConfigForm}onConfigurationSet(e){this.generatorConfigForm=this.fb.group({msgCount:[e?e.msgCount:null,[_.required,_.min(0)]],periodInSeconds:[e?e.periodInSeconds:null,[_.required,_.min(1)]],originator:[e?e.originator:null,[]],scriptLang:[e?e.scriptLang:b.JS,[_.required]],jsScript:[e?e.jsScript:null,[]],tbelScript:[e?e.tbelScript:null,[]],queueName:[e?e.queueName:null,[]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.generatorConfigForm.get("scriptLang").value;t!==b.TBEL||this.tbelEnabled||(t=b.JS,this.generatorConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.generatorConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.generatorConfigForm.get("jsScript").setValidators(t===b.JS?[_.required]:[]),this.generatorConfigForm.get("jsScript").updateValueAndValidity({emitEvent:e}),this.generatorConfigForm.get("tbelScript").setValidators(t===b.TBEL?[_.required]:[]),this.generatorConfigForm.get("tbelScript").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=b.JS),e.originatorId&&e.originatorType?e.originator={id:e.originatorId,entityType:e.originatorType}:e.originator=null,delete e.originatorId,delete e.originatorType),e}prepareOutputConfig(e){return e.originator?(e.originatorId=e.originator.id,e.originatorType=e.originator.entityType):(e.originatorId=null,e.originatorType=null),delete e.originator,e}testScript(e){const t=this.generatorConfigForm.get("scriptLang").value,n=t===b.JS?"jsScript":"tbelScript",r=t===b.JS?"rulenode/generator_node_script_fn":"rulenode/tbel/generator_node_script_fn",o=this.generatorConfigForm.get(n).value;this.nodeScriptTestService.testNodeScript(o,"generate",this.translate.instant("tb.rulenode.generator"),"Generate",["prevMsg","prevMetadata","prevMsgType"],this.ruleNodeId,r,t,e).subscribe((e=>{e&&(this.generatorConfigForm.get(n).setValue(e),this.changeScript.emit())}))}onValidate(){this.generatorConfigForm.get("scriptLang").value===b.JS&&this.jsFuncComponent.validateOnSubmit()}}var kt;e("GeneratorConfigComponent",Ft),Ft.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Ft,deps:[{token:R.Store},{token:O.UntypedFormBuilder},{token:ie.NodeScriptTestService},{token:X.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Ft.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Ft,selector:"tb-action-node-generator-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.message-count\n \n \n {{ \'tb.rulenode.message-count-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-message-count-message\' | translate }}\n \n \n \n tb.rulenode.period-seconds\n \n \n {{ \'tb.rulenode.period-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-period-seconds-message\' | translate }}\n \n \n
\n \n \n \n
\n\n \n \n\n \n \n \n \n \n \n \n
\n \n
\n
\n',dependencies:[{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ke.EntitySelectComponent,selector:"tb-entity-select",inputs:["allowedEntityTypes","useAliasEntityTypes","required","disabled"]},{kind:"component",type:oe.QueueAutocompleteComponent,selector:"tb-queue-autocomplete",inputs:["labelText","requiredText","autocompleteHint","subscriptSizing","required","queueType","disabled"]},{kind:"component",type:de.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:ce.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ce.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:ye.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Ft,decorators:[{type:n,args:[{selector:"tb-action-node-generator-config",template:'
\n \n tb.rulenode.message-count\n \n \n {{ \'tb.rulenode.message-count-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-message-count-message\' | translate }}\n \n \n \n tb.rulenode.period-seconds\n \n \n {{ \'tb.rulenode.period-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-period-seconds-message\' | translate }}\n \n \n
\n \n \n \n
\n\n \n \n\n \n \n \n \n \n \n \n
\n \n
\n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder},{type:ie.NodeScriptTestService},{type:X.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}}),function(e){e.CUSTOMER="CUSTOMER",e.TENANT="TENANT",e.RELATED="RELATED",e.ALARM_ORIGINATOR="ALARM_ORIGINATOR",e.ENTITY="ENTITY"}(kt||(kt={}));const Lt=new Map([[kt.CUSTOMER,"tb.rulenode.originator-customer"],[kt.TENANT,"tb.rulenode.originator-tenant"],[kt.RELATED,"tb.rulenode.originator-related"],[kt.ALARM_ORIGINATOR,"tb.rulenode.originator-alarm-originator"],[kt.ENTITY,"tb.rulenode.originator-entity"]]),Tt=new Map([[kt.CUSTOMER,"tb.rulenode.originator-customer-desc"],[kt.TENANT,"tb.rulenode.originator-tenant-desc"],[kt.RELATED,"tb.rulenode.originator-related-entity-desc"],[kt.ALARM_ORIGINATOR,"tb.rulenode.originator-alarm-originator-desc"],[kt.ENTITY,"tb.rulenode.originator-entity-by-name-pattern-desc"]]),It=[L.createdTime,L.name,{value:"type",name:"tb.rulenode.profile-name",keyName:"originatorProfileName"},L.firstName,L.lastName,L.email,L.title,L.country,L.state,L.city,L.address,L.address2,L.zip,L.phone,L.label,{value:"id",name:"tb.rulenode.id",keyName:"id"},{value:"additionalInfo",name:"tb.rulenode.additional-info",keyName:"additionalInfo"}],Nt=new Map([["type","profileName"],["createdTime","createdTime"],["name","name"],["firstName","firstName"],["lastName","lastName"],["email","email"],["title","title"],["country","country"],["state","state"],["city","city"],["address","address"],["address2","address2"],["zip","zip"],["phone","phone"],["label","label"],["id","id"],["additionalInfo","additionalInfo"]]);var St;!function(e){e.CIRCLE="CIRCLE",e.POLYGON="POLYGON"}(St||(St={}));const qt=new Map([[St.CIRCLE,"tb.rulenode.perimeter-circle"],[St.POLYGON,"tb.rulenode.perimeter-polygon"]]);var At;!function(e){e.MILLISECONDS="MILLISECONDS",e.SECONDS="SECONDS",e.MINUTES="MINUTES",e.HOURS="HOURS",e.DAYS="DAYS"}(At||(At={}));const Mt=new Map([[At.MILLISECONDS,"tb.rulenode.time-unit-milliseconds"],[At.SECONDS,"tb.rulenode.time-unit-seconds"],[At.MINUTES,"tb.rulenode.time-unit-minutes"],[At.HOURS,"tb.rulenode.time-unit-hours"],[At.DAYS,"tb.rulenode.time-unit-days"]]);var Et;!function(e){e.METER="METER",e.KILOMETER="KILOMETER",e.FOOT="FOOT",e.MILE="MILE",e.NAUTICAL_MILE="NAUTICAL_MILE"}(Et||(Et={}));const Gt=new Map([[Et.METER,"tb.rulenode.range-unit-meter"],[Et.KILOMETER,"tb.rulenode.range-unit-kilometer"],[Et.FOOT,"tb.rulenode.range-unit-foot"],[Et.MILE,"tb.rulenode.range-unit-mile"],[Et.NAUTICAL_MILE,"tb.rulenode.range-unit-nautical-mile"]]);var Dt;!function(e){e.ID="ID",e.TITLE="TITLE",e.COUNTRY="COUNTRY",e.STATE="STATE",e.CITY="CITY",e.ZIP="ZIP",e.ADDRESS="ADDRESS",e.ADDRESS2="ADDRESS2",e.PHONE="PHONE",e.EMAIL="EMAIL",e.ADDITIONAL_INFO="ADDITIONAL_INFO"}(Dt||(Dt={}));const Vt=new Map([[Dt.ID,"tb.rulenode.entity-details-id"],[Dt.TITLE,"tb.rulenode.entity-details-title"],[Dt.COUNTRY,"tb.rulenode.entity-details-country"],[Dt.STATE,"tb.rulenode.entity-details-state"],[Dt.CITY,"tb.rulenode.entity-details-city"],[Dt.ZIP,"tb.rulenode.entity-details-zip"],[Dt.ADDRESS,"tb.rulenode.entity-details-address"],[Dt.ADDRESS2,"tb.rulenode.entity-details-address2"],[Dt.PHONE,"tb.rulenode.entity-details-phone"],[Dt.EMAIL,"tb.rulenode.entity-details-email"],[Dt.ADDITIONAL_INFO,"tb.rulenode.entity-details-additional_info"]]);var wt;!function(e){e.FIRST="FIRST",e.LAST="LAST",e.ALL="ALL"}(wt||(wt={}));const Pt=new Map([[wt.FIRST,"tb.rulenode.first"],[wt.LAST,"tb.rulenode.last"],[wt.ALL,"tb.rulenode.all"]]),Rt=new Map([[wt.FIRST,"tb.rulenode.first-mode-hint"],[wt.LAST,"tb.rulenode.last-mode-hint"],[wt.ALL,"tb.rulenode.all-mode-hint"]]);var Ot,_t;!function(e){e.ASC="ASC",e.DESC="DESC"}(Ot||(Ot={})),function(e){e.ATTRIBUTES="ATTRIBUTES",e.LATEST_TELEMETRY="LATEST_TELEMETRY",e.FIELDS="FIELDS"}(_t||(_t={}));const Bt=new Map([[_t.ATTRIBUTES,"tb.rulenode.attributes"],[_t.LATEST_TELEMETRY,"tb.rulenode.latest-telemetry"],[_t.FIELDS,"tb.rulenode.fields"]]),Kt=new Map([[_t.ATTRIBUTES,"tb.rulenode.add-mapped-attribute-to"],[_t.LATEST_TELEMETRY,"tb.rulenode.add-mapped-latest-telemetry-to"],[_t.FIELDS,"tb.rulenode.add-mapped-fields-to"]]),zt=new Map([[Ot.ASC,"tb.rulenode.ascending"],[Ot.DESC,"tb.rulenode.descending"]]);var Ut;!function(e){e.STANDARD="STANDARD",e.FIFO="FIFO"}(Ut||(Ut={}));const Ht=new Map([[Ut.STANDARD,"tb.rulenode.sqs-queue-standard"],[Ut.FIFO,"tb.rulenode.sqs-queue-fifo"]]),jt=["anonymous","basic","cert.PEM"],$t=new Map([["anonymous","tb.rulenode.credentials-anonymous"],["basic","tb.rulenode.credentials-basic"],["cert.PEM","tb.rulenode.credentials-pem"]]),Qt=["sas","cert.PEM"],Jt=new Map([["sas","tb.rulenode.credentials-sas"],["cert.PEM","tb.rulenode.credentials-pem"]]);var Yt;!function(e){e.GET="GET",e.POST="POST",e.PUT="PUT",e.DELETE="DELETE"}(Yt||(Yt={}));const Wt=["US-ASCII","ISO-8859-1","UTF-8","UTF-16BE","UTF-16LE","UTF-16"],Zt=new Map([["US-ASCII","tb.rulenode.charset-us-ascii"],["ISO-8859-1","tb.rulenode.charset-iso-8859-1"],["UTF-8","tb.rulenode.charset-utf-8"],["UTF-16BE","tb.rulenode.charset-utf-16be"],["UTF-16LE","tb.rulenode.charset-utf-16le"],["UTF-16","tb.rulenode.charset-utf-16"]]);var Xt;!function(e){e.CUSTOM="CUSTOM",e.ADD="ADD",e.SUB="SUB",e.MULT="MULT",e.DIV="DIV",e.SIN="SIN",e.SINH="SINH",e.COS="COS",e.COSH="COSH",e.TAN="TAN",e.TANH="TANH",e.ACOS="ACOS",e.ASIN="ASIN",e.ATAN="ATAN",e.ATAN2="ATAN2",e.EXP="EXP",e.EXPM1="EXPM1",e.SQRT="SQRT",e.CBRT="CBRT",e.GET_EXP="GET_EXP",e.HYPOT="HYPOT",e.LOG="LOG",e.LOG10="LOG10",e.LOG1P="LOG1P",e.CEIL="CEIL",e.FLOOR="FLOOR",e.FLOOR_DIV="FLOOR_DIV",e.FLOOR_MOD="FLOOR_MOD",e.ABS="ABS",e.MIN="MIN",e.MAX="MAX",e.POW="POW",e.SIGNUM="SIGNUM",e.RAD="RAD",e.DEG="DEG"}(Xt||(Xt={}));const en=new Map([[Xt.CUSTOM,{value:Xt.CUSTOM,name:"Custom Function",description:"Use this function to specify complex mathematical expression.",minArgs:1,maxArgs:16}],[Xt.ADD,{value:Xt.ADD,name:"Addition",description:"x + y",minArgs:2,maxArgs:2}],[Xt.SUB,{value:Xt.SUB,name:"Subtraction",description:"x - y",minArgs:2,maxArgs:2}],[Xt.MULT,{value:Xt.MULT,name:"Multiplication",description:"x * y",minArgs:2,maxArgs:2}],[Xt.DIV,{value:Xt.DIV,name:"Division",description:"x / y",minArgs:2,maxArgs:2}],[Xt.SIN,{value:Xt.SIN,name:"Sine",description:"Returns the trigonometric sine of an angle in radians.",minArgs:1,maxArgs:1}],[Xt.SINH,{value:Xt.SINH,name:"Hyperbolic sine",description:"Returns the hyperbolic sine of an argument.",minArgs:1,maxArgs:1}],[Xt.COS,{value:Xt.COS,name:"Cosine",description:"Returns the trigonometric cosine of an angle in radians.",minArgs:1,maxArgs:1}],[Xt.COSH,{value:Xt.COSH,name:"Hyperbolic cosine",description:"Returns the hyperbolic cosine of an argument.",minArgs:1,maxArgs:1}],[Xt.TAN,{value:Xt.TAN,name:"Tangent",description:"Returns the trigonometric tangent of an angle in radians",minArgs:1,maxArgs:1}],[Xt.TANH,{value:Xt.TANH,name:"Hyperbolic tangent",description:"Returns the hyperbolic tangent of an argument",minArgs:1,maxArgs:1}],[Xt.ACOS,{value:Xt.ACOS,name:"Arc cosine",description:"Returns the arc cosine of an argument",minArgs:1,maxArgs:1}],[Xt.ASIN,{value:Xt.ASIN,name:"Arc sine",description:"Returns the arc sine of an argument",minArgs:1,maxArgs:1}],[Xt.ATAN,{value:Xt.ATAN,name:"Arc tangent",description:"Returns the arc tangent of an argument",minArgs:1,maxArgs:1}],[Xt.ATAN2,{value:Xt.ATAN2,name:"2-argument arc tangent",description:"Returns the angle theta from the conversion of rectangular coordinates (x, y) to polar coordinates (r, theta)",minArgs:2,maxArgs:2}],[Xt.EXP,{value:Xt.EXP,name:"Exponential",description:"Returns Euler's number e raised to the power of an argument",minArgs:1,maxArgs:1}],[Xt.EXPM1,{value:Xt.EXPM1,name:"Exponential minus one",description:"Returns Euler's number e raised to the power of an argument minus one",minArgs:1,maxArgs:1}],[Xt.SQRT,{value:Xt.SQRT,name:"Square",description:"Returns the correctly rounded positive square root of an argument",minArgs:1,maxArgs:1}],[Xt.CBRT,{value:Xt.CBRT,name:"Cube root",description:"Returns the cube root of an argument",minArgs:1,maxArgs:1}],[Xt.GET_EXP,{value:Xt.GET_EXP,name:"Get exponent",description:"Returns the unbiased exponent used in the representation of an argument",minArgs:1,maxArgs:1}],[Xt.HYPOT,{value:Xt.HYPOT,name:"Square root",description:"Returns the square root of the squares of the arguments",minArgs:2,maxArgs:2}],[Xt.LOG,{value:Xt.LOG,name:"Logarithm",description:"Returns the natural logarithm of an argument",minArgs:1,maxArgs:1}],[Xt.LOG10,{value:Xt.LOG10,name:"Base 10 logarithm",description:"Returns the base 10 logarithm of an argument",minArgs:1,maxArgs:1}],[Xt.LOG1P,{value:Xt.LOG1P,name:"Logarithm of the sum",description:"Returns the natural logarithm of the sum of an argument",minArgs:1,maxArgs:1}],[Xt.CEIL,{value:Xt.CEIL,name:"Ceiling",description:"Returns the smallest (closest to negative infinity) of an argument",minArgs:1,maxArgs:1}],[Xt.FLOOR,{value:Xt.FLOOR,name:"Floor",description:"Returns the largest (closest to positive infinity) of an argument",minArgs:1,maxArgs:1}],[Xt.FLOOR_DIV,{value:Xt.FLOOR_DIV,name:"Floor division",description:"Returns the largest (closest to positive infinity) of the arguments",minArgs:2,maxArgs:2}],[Xt.FLOOR_MOD,{value:Xt.FLOOR_MOD,name:"Floor modulus",description:"Returns the floor modulus of the arguments",minArgs:2,maxArgs:2}],[Xt.ABS,{value:Xt.ABS,name:"Absolute",description:"Returns the absolute value of an argument",minArgs:1,maxArgs:1}],[Xt.MIN,{value:Xt.MIN,name:"Min",description:"Returns the smaller of the arguments",minArgs:2,maxArgs:2}],[Xt.MAX,{value:Xt.MAX,name:"Max",description:"Returns the greater of the arguments",minArgs:2,maxArgs:2}],[Xt.POW,{value:Xt.POW,name:"Raise to a power",description:"Returns the value of the first argument raised to the power of the second argument",minArgs:2,maxArgs:2}],[Xt.SIGNUM,{value:Xt.SIGNUM,name:"Sign of a real number",description:"Returns the signum function of the argument",minArgs:1,maxArgs:1}],[Xt.RAD,{value:Xt.RAD,name:"Radian",description:"Converts an angle measured in degrees to an approximately equivalent angle measured in radians",minArgs:1,maxArgs:1}],[Xt.DEG,{value:Xt.DEG,name:"Degrees",description:"Converts an angle measured in radians to an approximately equivalent angle measured in degrees.",minArgs:1,maxArgs:1}]]);var tn,nn,rn;!function(e){e.MESSAGE_BODY="MESSAGE_BODY",e.MESSAGE_METADATA="MESSAGE_METADATA",e.ATTRIBUTE="ATTRIBUTE",e.TIME_SERIES="TIME_SERIES",e.CONSTANT="CONSTANT"}(tn||(tn={})),function(e){e.MESSAGE_BODY="MESSAGE_BODY",e.MESSAGE_METADATA="MESSAGE_METADATA",e.ATTRIBUTE="ATTRIBUTE",e.TIME_SERIES="TIME_SERIES"}(nn||(nn={})),function(e){e.DATA="DATA",e.METADATA="METADATA"}(rn||(rn={}));const on=new Map([[rn.DATA,"tb.rulenode.message-to-metadata"],[rn.METADATA,"tb.rulenode.metadata-to-message"]]),an=(new Map([[rn.DATA,"tb.rulenode.from-message"],[rn.METADATA,"tb.rulenode.from-metadata"]]),new Map([[rn.DATA,"tb.rulenode.message"],[rn.METADATA,"tb.rulenode.metadata"]])),ln=new Map([[rn.DATA,"tb.rulenode.message"],[rn.METADATA,"tb.rulenode.message-metadata"]]),sn=new Map([[tn.MESSAGE_BODY,{name:"tb.rulenode.message-body-type",description:"Fetch argument value from incoming message"}],[tn.MESSAGE_METADATA,{name:"tb.rulenode.message-metadata-type",description:"Fetch argument value from incoming message metadata"}],[tn.ATTRIBUTE,{name:"tb.rulenode.attribute-type",description:"Fetch attribute value from database"}],[tn.TIME_SERIES,{name:"tb.rulenode.time-series-type",description:"Fetch latest time-series value from database"}],[tn.CONSTANT,{name:"tb.rulenode.constant-type",description:"Define constant value"}]]),mn=new Map([[nn.MESSAGE_BODY,{name:"tb.rulenode.message-body-type",description:"Add result to the outgoing message"}],[nn.MESSAGE_METADATA,{name:"tb.rulenode.message-metadata-type",description:"Add result to the outgoing message metadata"}],[nn.ATTRIBUTE,{name:"tb.rulenode.attribute-type",description:"Store result as an entity attribute in the database"}],[nn.TIME_SERIES,{name:"tb.rulenode.time-series-type",description:"Store result as an entity time-series in the database"}]]),pn=["x","y","z","a","b","c","d","k","l","m","n","o","p","r","s","t"];var un,dn;!function(e){e.SHARED_SCOPE="SHARED_SCOPE",e.SERVER_SCOPE="SERVER_SCOPE",e.CLIENT_SCOPE="CLIENT_SCOPE"}(un||(un={})),function(e){e.SHARED_SCOPE="SHARED_SCOPE",e.SERVER_SCOPE="SERVER_SCOPE"}(dn||(dn={}));const cn=new Map([[un.SHARED_SCOPE,"tb.rulenode.shared-scope"],[un.SERVER_SCOPE,"tb.rulenode.server-scope"],[un.CLIENT_SCOPE,"tb.rulenode.client-scope"]]);class fn extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.perimeterType=St,this.perimeterTypes=Object.keys(St),this.perimeterTypeTranslationMap=qt,this.rangeUnits=Object.keys(Et),this.rangeUnitTranslationMap=Gt,this.timeUnits=Object.keys(At),this.timeUnitsTranslationMap=Mt}configForm(){return this.geoActionConfigForm}onConfigurationSet(e){this.geoActionConfigForm=this.fb.group({latitudeKeyName:[e?e.latitudeKeyName:null,[_.required]],longitudeKeyName:[e?e.longitudeKeyName:null,[_.required]],perimeterType:[e?e.perimeterType:null,[_.required]],fetchPerimeterInfoFromMessageMetadata:[!!e&&e.fetchPerimeterInfoFromMessageMetadata,[]],perimeterKeyName:[e?e.perimeterKeyName:null,[]],centerLatitude:[e?e.centerLatitude:null,[]],centerLongitude:[e?e.centerLatitude:null,[]],range:[e?e.range:null,[]],rangeUnit:[e?e.rangeUnit:null,[]],polygonsDefinition:[e?e.polygonsDefinition:null,[]],minInsideDuration:[e?e.minInsideDuration:null,[_.required,_.min(1),_.max(2147483647)]],minInsideDurationTimeUnit:[e?e.minInsideDurationTimeUnit:null,[_.required]],minOutsideDuration:[e?e.minOutsideDuration:null,[_.required,_.min(1),_.max(2147483647)]],minOutsideDurationTimeUnit:[e?e.minOutsideDurationTimeUnit:null,[_.required]]})}validatorTriggers(){return["fetchPerimeterInfoFromMessageMetadata","perimeterType"]}updateValidators(e){const t=this.geoActionConfigForm.get("fetchPerimeterInfoFromMessageMetadata").value,n=this.geoActionConfigForm.get("perimeterType").value;t?this.geoActionConfigForm.get("perimeterKeyName").setValidators([_.required]):this.geoActionConfigForm.get("perimeterKeyName").setValidators([]),t||n!==St.CIRCLE?(this.geoActionConfigForm.get("centerLatitude").setValidators([]),this.geoActionConfigForm.get("centerLongitude").setValidators([]),this.geoActionConfigForm.get("range").setValidators([]),this.geoActionConfigForm.get("rangeUnit").setValidators([])):(this.geoActionConfigForm.get("centerLatitude").setValidators([_.required,_.min(-90),_.max(90)]),this.geoActionConfigForm.get("centerLongitude").setValidators([_.required,_.min(-180),_.max(180)]),this.geoActionConfigForm.get("range").setValidators([_.required,_.min(0)]),this.geoActionConfigForm.get("rangeUnit").setValidators([_.required])),t||n!==St.POLYGON?this.geoActionConfigForm.get("polygonsDefinition").setValidators([]):this.geoActionConfigForm.get("polygonsDefinition").setValidators([_.required]),this.geoActionConfigForm.get("perimeterKeyName").updateValueAndValidity({emitEvent:e}),this.geoActionConfigForm.get("centerLatitude").updateValueAndValidity({emitEvent:e}),this.geoActionConfigForm.get("centerLongitude").updateValueAndValidity({emitEvent:e}),this.geoActionConfigForm.get("range").updateValueAndValidity({emitEvent:e}),this.geoActionConfigForm.get("rangeUnit").updateValueAndValidity({emitEvent:e}),this.geoActionConfigForm.get("polygonsDefinition").updateValueAndValidity({emitEvent:e})}}e("GpsGeoActionConfigComponent",fn),fn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:fn,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),fn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:fn,selector:"tb-action-node-gps-geofencing-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.latitude-key-name\n \n \n {{ \'tb.rulenode.latitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.longitude-key-name\n \n \n {{ \'tb.rulenode.longitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.perimeter-type\n \n \n {{ perimeterTypeTranslationMap.get(type) | translate }}\n \n \n \n \n {{ \'tb.rulenode.fetch-perimeter-info-from-metadata\' | translate }}\n \n \n tb.rulenode.perimeter-key-name\n \n \n {{ \'tb.rulenode.perimeter-key-name-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.circle-center-latitude\n \n \n {{ \'tb.rulenode.circle-center-latitude-required\' | translate }}\n \n \n \n tb.rulenode.circle-center-longitude\n \n \n {{ \'tb.rulenode.circle-center-longitude-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.range\n \n \n {{ \'tb.rulenode.range-required\' | translate }}\n \n \n \n tb.rulenode.range-units\n \n \n {{ rangeUnitTranslationMap.get(type) | translate }}\n \n \n \n
\n
\n
\n \n tb.rulenode.polygon-definition\n \n \n {{ \'tb.rulenode.polygon-definition-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.min-inside-duration\n \n \n {{ \'tb.rulenode.min-inside-duration-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n tb.rulenode.min-inside-duration-time-unit\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n \n tb.rulenode.min-outside-duration\n \n \n {{ \'tb.rulenode.min-outside-duration-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n tb.rulenode.min-outside-duration-time-unit\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n',dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:J.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:fn,decorators:[{type:n,args:[{selector:"tb-action-node-gps-geofencing-config",template:'
\n \n tb.rulenode.latitude-key-name\n \n \n {{ \'tb.rulenode.latitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.longitude-key-name\n \n \n {{ \'tb.rulenode.longitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.perimeter-type\n \n \n {{ perimeterTypeTranslationMap.get(type) | translate }}\n \n \n \n \n {{ \'tb.rulenode.fetch-perimeter-info-from-metadata\' | translate }}\n \n \n tb.rulenode.perimeter-key-name\n \n \n {{ \'tb.rulenode.perimeter-key-name-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.circle-center-latitude\n \n \n {{ \'tb.rulenode.circle-center-latitude-required\' | translate }}\n \n \n \n tb.rulenode.circle-center-longitude\n \n \n {{ \'tb.rulenode.circle-center-longitude-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.range\n \n \n {{ \'tb.rulenode.range-required\' | translate }}\n \n \n \n tb.rulenode.range-units\n \n \n {{ rangeUnitTranslationMap.get(type) | translate }}\n \n \n \n
\n
\n
\n \n tb.rulenode.polygon-definition\n \n \n {{ \'tb.rulenode.polygon-definition-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.min-inside-duration\n \n \n {{ \'tb.rulenode.min-inside-duration-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n tb.rulenode.min-inside-duration-time-unit\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n \n tb.rulenode.min-outside-duration\n \n \n {{ \'tb.rulenode.min-outside-duration-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n tb.rulenode.min-outside-duration-time-unit\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class gn extends f{constructor(e,t,n,o){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=n,this.translate=o,this.tbelEnabled=ae(this.store).tbelEnabled,this.scriptLanguage=b,this.changeScript=new r,this.hasScript=!0,this.testScriptLabel="tb.rulenode.test-to-string-function"}configForm(){return this.logConfigForm}onConfigurationSet(e){this.logConfigForm=this.fb.group({scriptLang:[e?e.scriptLang:b.JS,[_.required]],jsScript:[e?e.jsScript:null,[]],tbelScript:[e?e.tbelScript:null,[]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.logConfigForm.get("scriptLang").value;t!==b.TBEL||this.tbelEnabled||(t=b.JS,this.logConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.logConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.logConfigForm.get("jsScript").setValidators(t===b.JS?[_.required]:[]),this.logConfigForm.get("jsScript").updateValueAndValidity({emitEvent:e}),this.logConfigForm.get("tbelScript").setValidators(t===b.TBEL?[_.required]:[]),this.logConfigForm.get("tbelScript").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=b.JS)),e}testScript(e){const t=this.logConfigForm.get("scriptLang").value,n=t===b.JS?"jsScript":"tbelScript",r=t===b.JS?"rulenode/log_node_script_fn":"rulenode/tbel/log_node_script_fn",o=this.logConfigForm.get(n).value;this.nodeScriptTestService.testNodeScript(o,"string",this.translate.instant("tb.rulenode.to-string"),"ToString",["msg","metadata","msgType"],this.ruleNodeId,r,t,e).subscribe((e=>{e&&(this.logConfigForm.get(n).setValue(e),this.changeScript.emit())}))}onValidate(){this.logConfigForm.get("scriptLang").value===b.JS&&this.jsFuncComponent.validateOnSubmit()}}e("LogConfigComponent",gn),gn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:gn,deps:[{token:R.Store},{token:O.UntypedFormBuilder},{token:ie.NodeScriptTestService},{token:X.TranslateService}],target:t.ɵɵFactoryTarget.Component}),gn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:gn,selector:"tb-action-node-log-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n \n \n
\n \n
\n
\n',dependencies:[{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:de.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:ce.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ce.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:ye.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:gn,decorators:[{type:n,args:[{selector:"tb-action-node-log-config",template:'
\n \n \n \n \n \n \n \n
\n \n
\n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder},{type:ie.NodeScriptTestService},{type:X.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}});class yn extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.msgCountConfigForm}onConfigurationSet(e){this.msgCountConfigForm=this.fb.group({interval:[e?e.interval:null,[_.required,_.min(1)]],telemetryPrefix:[e?e.telemetryPrefix:null,[_.required]]})}}e("MsgCountConfigComponent",yn),yn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:yn,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),yn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:yn,selector:"tb-action-node-msg-count-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.interval-seconds\n \n \n {{ \'tb.rulenode.interval-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-interval-seconds-message\' | translate }}\n \n \n \n tb.rulenode.output-timeseries-key-prefix\n \n \n {{ \'tb.rulenode.output-timeseries-key-prefix-required\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:yn,decorators:[{type:n,args:[{selector:"tb-action-node-msg-count-config",template:'
\n \n tb.rulenode.interval-seconds\n \n \n {{ \'tb.rulenode.interval-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-interval-seconds-message\' | translate }}\n \n \n \n tb.rulenode.output-timeseries-key-prefix\n \n \n {{ \'tb.rulenode.output-timeseries-key-prefix-required\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class xn extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.msgDelayConfigForm}onConfigurationSet(e){this.msgDelayConfigForm=this.fb.group({useMetadataPeriodInSecondsPatterns:[!!e&&e.useMetadataPeriodInSecondsPatterns,[]],periodInSeconds:[e?e.periodInSeconds:null,[]],periodInSecondsPattern:[e?e.periodInSecondsPattern:null,[]],maxPendingMsgs:[e?e.maxPendingMsgs:null,[_.required,_.min(1),_.max(1e5)]]})}validatorTriggers(){return["useMetadataPeriodInSecondsPatterns"]}updateValidators(e){this.msgDelayConfigForm.get("useMetadataPeriodInSecondsPatterns").value?(this.msgDelayConfigForm.get("periodInSecondsPattern").setValidators([_.required]),this.msgDelayConfigForm.get("periodInSeconds").setValidators([])):(this.msgDelayConfigForm.get("periodInSecondsPattern").setValidators([]),this.msgDelayConfigForm.get("periodInSeconds").setValidators([_.required,_.min(0)])),this.msgDelayConfigForm.get("periodInSecondsPattern").updateValueAndValidity({emitEvent:e}),this.msgDelayConfigForm.get("periodInSeconds").updateValueAndValidity({emitEvent:e})}}e("MsgDelayConfigComponent",xn),xn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:xn,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),xn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:xn,selector:"tb-action-node-msg-delay-config",usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.use-metadata-period-in-seconds-patterns\' | translate }}\n \n
tb.rulenode.use-metadata-period-in-seconds-patterns-hint
\n \n tb.rulenode.period-seconds\n \n \n {{ \'tb.rulenode.period-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-period-0-seconds-message\' | translate }}\n \n \n \n \n tb.rulenode.period-in-seconds-pattern\n \n \n {{ \'tb.rulenode.period-in-seconds-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n \n tb.rulenode.max-pending-messages\n \n \n {{ \'tb.rulenode.max-pending-messages-required\' | translate }}\n \n \n {{ \'tb.rulenode.max-pending-messages-range\' | translate }}\n \n \n {{ \'tb.rulenode.max-pending-messages-range\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:J.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:xn,decorators:[{type:n,args:[{selector:"tb-action-node-msg-delay-config",template:'
\n \n {{ \'tb.rulenode.use-metadata-period-in-seconds-patterns\' | translate }}\n \n
tb.rulenode.use-metadata-period-in-seconds-patterns-hint
\n \n tb.rulenode.period-seconds\n \n \n {{ \'tb.rulenode.period-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-period-0-seconds-message\' | translate }}\n \n \n \n \n tb.rulenode.period-in-seconds-pattern\n \n \n {{ \'tb.rulenode.period-in-seconds-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n \n tb.rulenode.max-pending-messages\n \n \n {{ \'tb.rulenode.max-pending-messages-required\' | translate }}\n \n \n {{ \'tb.rulenode.max-pending-messages-range\' | translate }}\n \n \n {{ \'tb.rulenode.max-pending-messages-range\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class bn extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.attributeScopes=Object.keys(g),this.telemetryTypeTranslationsMap=y}configForm(){return this.pushToCloudConfigForm}onConfigurationSet(e){this.pushToCloudConfigForm=this.fb.group({scope:[e?e.scope:null,[_.required]]})}}e("PushToCloudConfigComponent",bn),bn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:bn,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),bn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:bn,selector:"tb-action-node-push-to-cloud-config",usesInheritance:!0,ngImport:t,template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n',dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:bn,decorators:[{type:n,args:[{selector:"tb-action-node-push-to-cloud-config",template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class hn extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.attributeScopes=Object.keys(g),this.telemetryTypeTranslationsMap=y}configForm(){return this.pushToEdgeConfigForm}onConfigurationSet(e){this.pushToEdgeConfigForm=this.fb.group({scope:[e?e.scope:null,[_.required]]})}}e("PushToEdgeConfigComponent",hn),hn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:hn,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),hn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:hn,selector:"tb-action-node-push-to-edge-config",usesInheritance:!0,ngImport:t,template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n',dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:hn,decorators:[{type:n,args:[{selector:"tb-action-node-push-to-edge-config",template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class vn extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.rpcReplyConfigForm}onConfigurationSet(e){this.rpcReplyConfigForm=this.fb.group({requestIdMetaDataAttribute:[e?e.requestIdMetaDataAttribute:null,[]]})}}e("RpcReplyConfigComponent",vn),vn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:vn,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),vn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:vn,selector:"tb-action-node-rpc-reply-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.request-id-metadata-attribute\n \n \n
\n',dependencies:[{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:vn,decorators:[{type:n,args:[{selector:"tb-action-node-rpc-reply-config",template:'
\n \n tb.rulenode.request-id-metadata-attribute\n \n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class Cn extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.rpcRequestConfigForm}onConfigurationSet(e){this.rpcRequestConfigForm=this.fb.group({timeoutInSeconds:[e?e.timeoutInSeconds:null,[_.required,_.min(0)]]})}}e("RpcRequestConfigComponent",Cn),Cn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Cn,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Cn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Cn,selector:"tb-action-node-rpc-request-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.timeout-sec\n \n \n {{ \'tb.rulenode.timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-timeout-message\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Cn,decorators:[{type:n,args:[{selector:"tb-action-node-rpc-request-config",template:'
\n \n tb.rulenode.timeout-sec\n \n \n {{ \'tb.rulenode.timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-timeout-message\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class Fn extends T{get required(){return this.requiredValue}set required(e){this.requiredValue=Le(e)}constructor(e,t,n,r){super(e),this.store=e,this.translate=t,this.injector=n,this.fb=r,this.propagateChange=null,this.valueChangeSubscription=null}ngOnInit(){this.ngControl=this.injector.get(B),null!=this.ngControl&&(this.ngControl.valueAccessor=this),this.kvListFormGroup=this.fb.group({}),this.kvListFormGroup.addControl("keyVals",this.fb.array([]))}keyValsFormArray(){return this.kvListFormGroup.get("keyVals")}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.kvListFormGroup.disable({emitEvent:!1}):this.kvListFormGroup.enable({emitEvent:!1})}writeValue(e){this.valueChangeSubscription&&this.valueChangeSubscription.unsubscribe();const t=[];if(e)for(const n of Object.keys(e))Object.prototype.hasOwnProperty.call(e,n)&&t.push(this.fb.group({key:[n,[_.required]],value:[e[n],[_.required]]}));this.kvListFormGroup.setControl("keyVals",this.fb.array(t)),this.valueChangeSubscription=this.kvListFormGroup.valueChanges.subscribe((()=>{this.updateModel()}))}removeKeyVal(e){this.kvListFormGroup.get("keyVals").removeAt(e)}addKeyVal(){this.kvListFormGroup.get("keyVals").push(this.fb.group({key:["",[_.required]],value:["",[_.required]]}))}validate(e){const t=this.kvListFormGroup.get("keyVals").value;if(!t.length&&this.required)return{kvMapRequired:!0};if(!this.kvListFormGroup.valid)return{kvFieldsRequired:!0};if(this.uniqueKeyValuePairValidator)for(const e of t)if(e.key===e.value)return{uniqueKeyValuePair:!0};return null}updateModel(){const e=this.kvListFormGroup.get("keyVals").value;if(this.required&&!e.length||!this.kvListFormGroup.valid)this.propagateChange(null);else{const t={};e.forEach((e=>{t[e.key]=e.value})),this.propagateChange(t)}}}e("KvMapConfigOldComponent",Fn),Fn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Fn,deps:[{token:R.Store},{token:X.TranslateService},{token:t.Injector},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Fn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Fn,selector:"tb-kv-map-config-old",inputs:{disabled:"disabled",uniqueKeyValuePairValidator:"uniqueKeyValuePairValidator",requiredText:"requiredText",keyText:"keyText",keyRequiredText:"keyRequiredText",valText:"valText",valRequiredText:"valRequiredText",hintText:"hintText",required:"required"},providers:[{provide:K,useExisting:a((()=>Fn)),multi:!0},{provide:z,useExisting:a((()=>Fn)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n
\n {{ keyText | translate }}\n {{ valText | translate }}\n \n
\n
\n
\n \n \n \n {{ keyRequiredText | translate }}\n \n \n \n \n \n {{ valRequiredText | translate }}\n \n \n \n
\n
\n
\n \n
\n \n
\n
\n',styles:[":host .tb-kv-map-config{margin-bottom:16px}:host .tb-kv-map-config .header{padding-left:5px;padding-right:5px;padding-bottom:5px}:host .tb-kv-map-config .header .cell{padding-left:5px;padding-right:5px;color:#757575;font-size:12px;font-weight:700;white-space:nowrap}:host .tb-kv-map-config .body{padding-left:5px;padding-right:5px;padding-bottom:0;max-height:300px;overflow:auto}:host .tb-kv-map-config .body .cell{padding-left:5px;padding-right:5px}:host .tb-kv-map-config tb-error{display:block;margin-top:-12px}\n"],dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Ne.TbErrorComponent,selector:"tb-error",inputs:["noMargin","error"]},{kind:"component",type:ce.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ce.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:Z.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:Se.DefaultShowHideDirective,selector:" [fxShow], [fxShow.print], [fxShow.xs], [fxShow.sm], [fxShow.md], [fxShow.lg], [fxShow.xl], [fxShow.lt-sm], [fxShow.lt-md], [fxShow.lt-lg], [fxShow.lt-xl], [fxShow.gt-xs], [fxShow.gt-sm], [fxShow.gt-md], [fxShow.gt-lg], [fxHide], [fxHide.print], [fxHide.xs], [fxHide.sm], [fxHide.md], [fxHide.lg], [fxHide.xl], [fxHide.lt-sm], [fxHide.lt-md], [fxHide.lt-lg], [fxHide.lt-xl], [fxHide.gt-xs], [fxHide.gt-sm], [fxHide.gt-md], [fxHide.gt-lg]",inputs:["fxShow","fxShow.print","fxShow.xs","fxShow.sm","fxShow.md","fxShow.lg","fxShow.xl","fxShow.lt-sm","fxShow.lt-md","fxShow.lt-lg","fxShow.lt-xl","fxShow.gt-xs","fxShow.gt-sm","fxShow.gt-md","fxShow.gt-lg","fxHide","fxHide.print","fxHide.xs","fxHide.sm","fxHide.md","fxHide.lg","fxHide.xl","fxHide.lt-sm","fxHide.lt-md","fxHide.lt-lg","fxHide.lt-xl","fxHide.gt-xs","fxHide.gt-sm","fxHide.gt-md","fxHide.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormControlDirective,selector:"[formControl]",inputs:["formControl","disabled","ngModel"],outputs:["ngModelChange"],exportAs:["ngForm"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormArrayName,selector:"[formArrayName]",inputs:["formArrayName"]},{kind:"pipe",type:j.AsyncPipe,name:"async"},{kind:"pipe",type:Ce.SafePipe,name:"safe"},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Fn,decorators:[{type:n,args:[{selector:"tb-kv-map-config-old",providers:[{provide:K,useExisting:a((()=>Fn)),multi:!0},{provide:z,useExisting:a((()=>Fn)),multi:!0}],template:'
\n
\n {{ keyText | translate }}\n {{ valText | translate }}\n \n
\n
\n
\n \n \n \n {{ keyRequiredText | translate }}\n \n \n \n \n \n {{ valRequiredText | translate }}\n \n \n \n
\n
\n
\n \n
\n \n
\n
\n',styles:[":host .tb-kv-map-config{margin-bottom:16px}:host .tb-kv-map-config .header{padding-left:5px;padding-right:5px;padding-bottom:5px}:host .tb-kv-map-config .header .cell{padding-left:5px;padding-right:5px;color:#757575;font-size:12px;font-weight:700;white-space:nowrap}:host .tb-kv-map-config .body{padding-left:5px;padding-right:5px;padding-bottom:0;max-height:300px;overflow:auto}:host .tb-kv-map-config .body .cell{padding-left:5px;padding-right:5px}:host .tb-kv-map-config tb-error{display:block;margin-top:-12px}\n"]}]}],ctorParameters:function(){return[{type:R.Store},{type:X.TranslateService},{type:t.Injector},{type:O.FormBuilder}]},propDecorators:{disabled:[{type:i}],uniqueKeyValuePairValidator:[{type:i}],requiredText:[{type:i}],keyText:[{type:i}],keyRequiredText:[{type:i}],valText:[{type:i}],valRequiredText:[{type:i}],hintText:[{type:i}],required:[{type:i}]}});class kn extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.saveToCustomTableConfigForm}onConfigurationSet(e){this.saveToCustomTableConfigForm=this.fb.group({tableName:[e?e.tableName:null,[_.required,_.pattern(/.*\S.*/)]],fieldsMapping:[e?e.fieldsMapping:null,[_.required]]})}prepareOutputConfig(e){return e.tableName=e.tableName.trim(),e}}e("SaveToCustomTableConfigComponent",kn),kn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:kn,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),kn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:kn,selector:"tb-action-node-custom-table-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.custom-table-name\n \n \n {{ \'tb.rulenode.custom-table-name-required\' | translate }}\n \n tb.rulenode.custom-table-hint\n \n \n \n \n
\n',dependencies:[{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Fn,selector:"tb-kv-map-config-old",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:kn,decorators:[{type:n,args:[{selector:"tb-action-node-custom-table-config",template:'
\n \n tb.rulenode.custom-table-name\n \n \n {{ \'tb.rulenode.custom-table-name-required\' | translate }}\n \n tb.rulenode.custom-table-hint\n \n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class Ln extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.timeseriesConfigForm}onConfigurationSet(e){this.timeseriesConfigForm=this.fb.group({defaultTTL:[e?e.defaultTTL:null,[_.required,_.min(0)]],skipLatestPersistence:[!!e&&e.skipLatestPersistence,[]],useServerTs:[!!e&&e.useServerTs,[]]})}}e("TimeseriesConfigComponent",Ln),Ln.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Ln,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Ln.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Ln,selector:"tb-action-node-timeseries-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.default-ttl\n \n \n {{ \'tb.rulenode.default-ttl-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-default-ttl-message\' | translate }}\n \n \n \n {{ \'tb.rulenode.skip-latest-persistence\' | translate }}\n \n \n {{ \'tb.rulenode.use-server-ts\' | translate }}\n \n
tb.rulenode.use-server-ts-hint
\n
\n',dependencies:[{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:J.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Ln,decorators:[{type:n,args:[{selector:"tb-action-node-timeseries-config",template:'
\n \n tb.rulenode.default-ttl\n \n \n {{ \'tb.rulenode.default-ttl-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-default-ttl-message\' | translate }}\n \n \n \n {{ \'tb.rulenode.skip-latest-persistence\' | translate }}\n \n \n {{ \'tb.rulenode.use-server-ts\' | translate }}\n \n
tb.rulenode.use-server-ts-hint
\n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class Tn extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.unassignCustomerConfigForm}onConfigurationSet(e){this.unassignCustomerConfigForm=this.fb.group({customerNamePattern:[e?e.customerNamePattern:null,[_.required,_.pattern(/.*\S.*/)]],customerCacheExpiration:[e?e.customerCacheExpiration:null,[_.required,_.min(0)]]})}prepareOutputConfig(e){return e.customerNamePattern=e.customerNamePattern.trim(),e}}e("UnassignCustomerConfigComponent",Tn),Tn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Tn,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Tn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Tn,selector:"tb-action-node-un-assign-to-customer-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.customer-name-pattern\n \n \n {{ \'tb.rulenode.customer-name-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.customer-cache-expiration\n \n \n {{ \'tb.rulenode.customer-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.customer-cache-expiration-range\' | translate }}\n \n tb.rulenode.customer-cache-expiration-hint\n \n
\n',dependencies:[{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Tn,decorators:[{type:n,args:[{selector:"tb-action-node-un-assign-to-customer-config",template:'
\n \n tb.rulenode.customer-name-pattern\n \n \n {{ \'tb.rulenode.customer-name-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.customer-cache-expiration\n \n \n {{ \'tb.rulenode.customer-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.customer-cache-expiration-range\' | translate }}\n \n tb.rulenode.customer-cache-expiration-hint\n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class In extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.attributeScopeMap=g,this.attributeScopes=Object.keys(g),this.telemetryTypeTranslationsMap=y,this.separatorKeysCodes=[xe,be,he]}configForm(){return this.deleteAttributesConfigForm}onConfigurationSet(e){this.deleteAttributesConfigForm=this.fb.group({scope:[e?e.scope:null,[_.required]],keys:[e?e.keys:null,[_.required]],sendAttributesDeletedNotification:[!!e&&e.sendAttributesDeletedNotification,[]],notifyDevice:[!!e&&e.notifyDevice,[]]}),this.deleteAttributesConfigForm.get("scope").valueChanges.subscribe((e=>{e!==g.SHARED_SCOPE&&this.deleteAttributesConfigForm.get("notifyDevice").patchValue(!1,{emitEvent:!1})}))}removeKey(e){const t=this.deleteAttributesConfigForm.get("keys").value,n=t.indexOf(e);n>=0&&(t.splice(n,1),this.deleteAttributesConfigForm.get("keys").patchValue(t,{emitEvent:!0}))}addKey(e){const t=e.input;let n=e.value;if((n||"").trim()){n=n.trim();let e=this.deleteAttributesConfigForm.get("keys").value;e&&-1!==e.indexOf(n)||(e||(e=[]),e.push(n),this.deleteAttributesConfigForm.get("keys").patchValue(e,{emitEvent:!0}))}t&&(t.value="")}}e("DeleteAttributesConfigComponent",In),In.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:In,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),In.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:In,selector:"tb-action-node-delete-attributes-config",viewQueries:[{propertyName:"attributeChipList",first:!0,predicate:["attributeChipList"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'attribute.attributes-scope\' | translate }}\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n \n \n \n {{key}}\n close\n \n \n \n {{ \'tb.rulenode.attributes-keys-required\' | translate }}\n tb.rulenode.general-pattern-hint\n \n \n {{ \'tb.rulenode.send-attributes-deleted-notification\' | translate }}\n \n
tb.rulenode.send-attributes-deleted-notification-hint
\n
\n \n {{ \'tb.rulenode.notify-device\' | translate }}\n \n
tb.rulenode.notify-device-on-delete-hint
\n
\n
\n',dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:J.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:ve.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:ve.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:ve.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:ve.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:In,decorators:[{type:n,args:[{selector:"tb-action-node-delete-attributes-config",template:'
\n \n {{ \'attribute.attributes-scope\' | translate }}\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n \n \n \n {{key}}\n close\n \n \n \n {{ \'tb.rulenode.attributes-keys-required\' | translate }}\n tb.rulenode.general-pattern-hint\n \n \n {{ \'tb.rulenode.send-attributes-deleted-notification\' | translate }}\n \n
tb.rulenode.send-attributes-deleted-notification-hint
\n
\n \n {{ \'tb.rulenode.notify-device\' | translate }}\n \n
tb.rulenode.notify-device-on-delete-hint
\n
\n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]},propDecorators:{attributeChipList:[{type:o,args:["attributeChipList"]}]}});class Nn extends T{get function(){return this.functionValue}set function(e){e&&this.functionValue!==e&&(this.functionValue=e,this.setupArgumentsFormGroup(!0))}constructor(e,t){super(e),this.store=e,this.fb=t,this.maxArgs=16,this.minArgs=1,this.displayArgumentName=!1,this.mathFunctionMap=en,this.ArgumentType=tn,this.attributeScopeMap=cn,this.argumentTypeMap=sn,this.arguments=Object.values(tn),this.attributeScope=Object.values(un),this.propagateChange=null,this.valueChangeSubscription=[]}ngOnInit(){this.argumentsFormGroup=this.fb.group({arguments:this.fb.array([])}),this.valueChangeSubscription.push(this.argumentsFormGroup.valueChanges.subscribe((()=>{this.updateModel()}))),this.setupArgumentsFormGroup()}onDrop(e){const t=this.argumentsFormArray,n=t.at(e.previousIndex);t.removeAt(e.previousIndex),t.insert(e.currentIndex,n),this.updateArgumentNames()}get argumentsFormArray(){return this.argumentsFormGroup.get("arguments")}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.argumentsFormGroup.disable({emitEvent:!1}):(this.argumentsFormGroup.enable({emitEvent:!1}),this.argumentsFormArray.controls.forEach((e=>this.updateArgumentControlValidators(e))))}ngOnDestroy(){this.valueChangeSubscription.length&&this.valueChangeSubscription.forEach((e=>e.unsubscribe()))}writeValue(e){const t=[];e&&e.forEach(((e,n)=>{t.push(this.createArgumentControl(e,n))})),this.argumentsFormGroup.setControl("arguments",this.fb.array(t),{emitEvent:!1}),this.setupArgumentsFormGroup()}removeArgument(e){this.argumentsFormArray.removeAt(e),this.updateArgumentNames()}addArgument(e=!0){const t=this.argumentsFormArray,n=this.createArgumentControl(null,t.length);t.push(n,{emitEvent:e})}validate(e){return this.argumentsFormGroup.valid?null:{argumentsRequired:!0}}setupArgumentsFormGroup(e=!1){if(this.function&&(this.maxArgs=this.mathFunctionMap.get(this.function).maxArgs,this.minArgs=this.mathFunctionMap.get(this.function).minArgs,this.displayArgumentName=this.function===Xt.CUSTOM),this.argumentsFormGroup){for(this.argumentsFormGroup.get("arguments").setValidators([_.minLength(this.minArgs),_.maxLength(this.maxArgs)]);this.argumentsFormArray.length>this.maxArgs;)this.removeArgument(this.maxArgs-1);for(;this.argumentsFormArray.length{this.updateArgumentControlValidators(n),n.get("attributeScope").updateValueAndValidity({emitEvent:!1}),n.get("defaultValue").updateValueAndValidity({emitEvent:!1})}))),n}updateArgumentControlValidators(e){const t=e.get("type").value;t===tn.ATTRIBUTE?e.get("attributeScope").enable({emitEvent:!1}):e.get("attributeScope").disable({emitEvent:!1}),t&&t!==tn.CONSTANT?e.get("defaultValue").enable({emitEvent:!1}):e.get("defaultValue").disable({emitEvent:!1})}updateArgumentNames(){this.argumentsFormArray.controls.forEach(((e,t)=>{e.get("name").setValue(pn[t])}))}updateModel(){const e=this.argumentsFormArray.value;e.length&&this.argumentsFormGroup.valid?this.propagateChange(e):this.propagateChange(null)}}e("ArgumentsMapConfigComponent",Nn),Nn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Nn,deps:[{token:R.Store},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Nn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Nn,selector:"tb-arguments-map-config",inputs:{disabled:"disabled",function:"function"},providers:[{provide:K,useExisting:a((()=>Nn)),multi:!0},{provide:z,useExisting:a((()=>Nn)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n\n
\n \n \n
\n \n
\n {{argumentControl.get(\'name\').value}}.\n
\n \n tb.rulenode.argument-source-field-input\n \n \n {{ argumentTypeMap.get(argumentControl.get(\'type\').value)?.name | translate }}\n \n \n {{ argumentTypeMap.get(argument).name | translate }}\n \n {{ argumentTypeMap.get(argument).description }}\n \n \n \n \n tb.rulenode.argument-source-field-input-required\n \n \n
\n \n tb.rulenode.argument-key-field-input\n \n \n help\n \n \n tb.rulenode.argument-key-field-input-required\n \n \n \n tb.rulenode.constant-value-field-input\n \n \n tb.rulenode.constant-value-field-input-required\n \n \n \n tb.rulenode.default-value-field-input\n \n \n
\n \n tb.rulenode.attribute-scope-field-input\n \n \n {{ attributeScopeMap.get(scope) | translate }}\n \n \n \n tb.rulenode.attribute-scope-field-input-required\n \n \n
\n \n
\n
\n
\n
\n
\n
\n tb.rulenode.no-arguments-prompt\n
\n \n
\n',styles:[":host .mat-mdc-list-item.tb-argument{border:solid rgba(0,0,0,.25) 1px;border-radius:4px;padding:10px 0;margin-bottom:16px}:host .arguments-list{padding:0}\n"],dependencies:[{kind:"directive",type:j.NgClass,selector:"[ngClass]",inputs:["class","ngClass"]},{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ce.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ce.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:W.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"directive",type:ee.MatSelectTrigger,selector:"mat-select-trigger"},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:qe.MatList,selector:"mat-list",exportAs:["matList"]},{kind:"component",type:qe.MatListItem,selector:"mat-list-item, a[mat-list-item], button[mat-list-item]",inputs:["activated"],exportAs:["matListItem"]},{kind:"directive",type:Ae.CdkDropList,selector:"[cdkDropList], cdk-drop-list",inputs:["cdkDropListConnectedTo","cdkDropListData","cdkDropListOrientation","id","cdkDropListLockAxis","cdkDropListDisabled","cdkDropListSortingDisabled","cdkDropListEnterPredicate","cdkDropListSortPredicate","cdkDropListAutoScrollDisabled","cdkDropListAutoScrollStep"],outputs:["cdkDropListDropped","cdkDropListEntered","cdkDropListExited","cdkDropListSorted"],exportAs:["cdkDropList"]},{kind:"directive",type:Ae.CdkDrag,selector:"[cdkDrag]",inputs:["cdkDragData","cdkDragLockAxis","cdkDragRootElement","cdkDragBoundary","cdkDragStartDelay","cdkDragFreeDragPosition","cdkDragDisabled","cdkDragConstrainPosition","cdkDragPreviewClass","cdkDragPreviewContainer"],outputs:["cdkDragStarted","cdkDragReleased","cdkDragEnded","cdkDragEntered","cdkDragExited","cdkDragDropped","cdkDragMoved"],exportAs:["cdkDrag"]},{kind:"directive",type:Ae.CdkDragHandle,selector:"[cdkDragHandle]",inputs:["cdkDragHandleDisabled"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:Z.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:Se.DefaultClassDirective,selector:" [ngClass], [ngClass.xs], [ngClass.sm], [ngClass.md], [ngClass.lg], [ngClass.xl], [ngClass.lt-sm], [ngClass.lt-md], [ngClass.lt-lg], [ngClass.lt-xl], [ngClass.gt-xs], [ngClass.gt-sm], [ngClass.gt-md], [ngClass.gt-lg]",inputs:["ngClass","ngClass.xs","ngClass.sm","ngClass.md","ngClass.lg","ngClass.xl","ngClass.lt-sm","ngClass.lt-md","ngClass.lt-lg","ngClass.lt-xl","ngClass.gt-xs","ngClass.gt-sm","ngClass.gt-md","ngClass.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.FormControlDirective,selector:"[formControl]",inputs:["formControl","disabled","ngModel"],outputs:["ngModelChange"],exportAs:["ngForm"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormArrayName,selector:"[formArrayName]",inputs:["formArrayName"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Nn,decorators:[{type:n,args:[{selector:"tb-arguments-map-config",providers:[{provide:K,useExisting:a((()=>Nn)),multi:!0},{provide:z,useExisting:a((()=>Nn)),multi:!0}],template:'
\n\n
\n \n \n
\n \n
\n {{argumentControl.get(\'name\').value}}.\n
\n \n tb.rulenode.argument-source-field-input\n \n \n {{ argumentTypeMap.get(argumentControl.get(\'type\').value)?.name | translate }}\n \n \n {{ argumentTypeMap.get(argument).name | translate }}\n \n {{ argumentTypeMap.get(argument).description }}\n \n \n \n \n tb.rulenode.argument-source-field-input-required\n \n \n
\n \n tb.rulenode.argument-key-field-input\n \n \n help\n \n \n tb.rulenode.argument-key-field-input-required\n \n \n \n tb.rulenode.constant-value-field-input\n \n \n tb.rulenode.constant-value-field-input-required\n \n \n \n tb.rulenode.default-value-field-input\n \n \n
\n \n tb.rulenode.attribute-scope-field-input\n \n \n {{ attributeScopeMap.get(scope) | translate }}\n \n \n \n tb.rulenode.attribute-scope-field-input-required\n \n \n
\n \n
\n
\n
\n
\n
\n
\n tb.rulenode.no-arguments-prompt\n
\n \n
\n',styles:[":host .mat-mdc-list-item.tb-argument{border:solid rgba(0,0,0,.25) 1px;border-radius:4px;padding:10px 0;margin-bottom:16px}:host .arguments-list{padding:0}\n"]}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder}]},propDecorators:{disabled:[{type:i}],function:[{type:i}]}});class Sn extends T{get required(){return this.requiredValue}set required(e){this.requiredValue=Le(e)}constructor(e,t,n,r){super(e),this.store=e,this.translate=t,this.injector=n,this.fb=r,this.searchText="",this.dirty=!1,this.mathOperation=[...en.values()],this.propagateChange=null}ngOnInit(){this.mathFunctionForm=this.fb.group({operation:[""]}),this.filteredOptions=this.mathFunctionForm.get("operation").valueChanges.pipe(Me((e=>{let t;t="string"==typeof e&&Xt[e]?Xt[e]:null,this.updateView(t)})),Ee((e=>(this.searchText=e||"",e?this._filter(e):this.mathOperation.slice()))))}_filter(e){const t=e.toLowerCase();return this.mathOperation.filter((e=>e.name.toLowerCase().includes(t)||e.value.toLowerCase().includes(t)))}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.mathFunctionForm.disable({emitEvent:!1}):this.mathFunctionForm.enable({emitEvent:!1})}mathFunctionDisplayFn(e){if(e){const t=en.get(e);return t.value+" | "+t.name}return""}writeValue(e){this.modelValue=e,this.mathFunctionForm.get("operation").setValue(e,{emitEvent:!1}),this.dirty=!0}updateView(e){this.modelValue!==e&&(this.modelValue=e,this.propagateChange(this.modelValue))}onFocus(){this.dirty&&(this.mathFunctionForm.get("operation").updateValueAndValidity({onlySelf:!0}),this.dirty=!1)}clear(){this.mathFunctionForm.get("operation").patchValue(""),setTimeout((()=>{this.operationInput.nativeElement.blur(),this.operationInput.nativeElement.focus()}),0)}}e("MathFunctionAutocompleteComponent",Sn),Sn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Sn,deps:[{token:R.Store},{token:X.TranslateService},{token:t.Injector},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Sn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Sn,selector:"tb-math-function-autocomplete",inputs:{required:"required",disabled:"disabled"},providers:[{provide:K,useExisting:a((()=>Sn)),multi:!0}],viewQueries:[{propertyName:"operationInput",first:!0,predicate:["operationInput"],descendants:!0,static:!0}],usesInheritance:!0,ngImport:t,template:'\n tb.rulenode.functions-field-input\n \n \n \n \n \n \n {{ option.description }}\n \n \n \n tb.rulenode.no-option-found\n \n \n\n',dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ce.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:Re.MatAutocomplete,selector:"mat-autocomplete",inputs:["disableRipple","hideSingleSelectionIndicator"],exportAs:["matAutocomplete"]},{kind:"directive",type:Re.MatAutocompleteTrigger,selector:"input[matAutocomplete], textarea[matAutocomplete]",exportAs:["matAutocompleteTrigger"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:j.AsyncPipe,name:"async"},{kind:"pipe",type:Oe.HighlightPipe,name:"highlight"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Sn,decorators:[{type:n,args:[{selector:"tb-math-function-autocomplete",providers:[{provide:K,useExisting:a((()=>Sn)),multi:!0}],template:'\n tb.rulenode.functions-field-input\n \n \n \n \n \n \n {{ option.description }}\n \n \n \n tb.rulenode.no-option-found\n \n \n\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:X.TranslateService},{type:t.Injector},{type:O.UntypedFormBuilder}]},propDecorators:{required:[{type:i}],disabled:[{type:i}],operationInput:[{type:o,args:["operationInput",{static:!0}]}]}});class qn extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.MathFunction=Xt,this.ArgumentTypeResult=nn,this.argumentTypeResultMap=mn,this.attributeScopeMap=cn,this.argumentsResult=Object.values(nn),this.attributeScopeResult=Object.values(dn)}configForm(){return this.mathFunctionConfigForm}onConfigurationSet(e){this.mathFunctionConfigForm=this.fb.group({operation:[e?e.operation:null,[_.required]],arguments:[e?e.arguments:null,[_.required]],customFunction:[e?e.customFunction:"",[_.required]],result:this.fb.group({type:[e?e.result.type:null,[_.required]],attributeScope:[e?e.result.attributeScope:null,[_.required]],key:[e?e.result.key:"",[_.required]],resultValuePrecision:[e?e.result.resultValuePrecision:0],addToBody:[!!e&&e.result.addToBody],addToMetadata:[!!e&&e.result.addToMetadata]})})}updateValidators(e){const t=this.mathFunctionConfigForm.get("operation").value,n=this.mathFunctionConfigForm.get("result.type").value;t===Xt.CUSTOM?(this.mathFunctionConfigForm.get("customFunction").enable({emitEvent:!1}),null===this.mathFunctionConfigForm.get("customFunction").value&&this.mathFunctionConfigForm.get("customFunction").patchValue("(x - 32) / 1.8",{emitEvent:!1})):this.mathFunctionConfigForm.get("customFunction").disable({emitEvent:!1}),n===nn.ATTRIBUTE?this.mathFunctionConfigForm.get("result.attributeScope").enable({emitEvent:!1}):this.mathFunctionConfigForm.get("result.attributeScope").disable({emitEvent:!1}),this.mathFunctionConfigForm.get("customFunction").updateValueAndValidity({emitEvent:e}),this.mathFunctionConfigForm.get("result.attributeScope").updateValueAndValidity({emitEvent:e})}validatorTriggers(){return["operation","result.type"]}}e("MathFunctionConfigComponent",qn),qn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:qn,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),qn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:qn,selector:"tb-action-node-math-function-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n
\n tb.rulenode.argument-tile\n \n \n
\n
\n {{\'tb.rulenode.custom-expression-field-input\' | translate }} *\n \n \n \n tb.rulenode.custom-expression-field-input-required\n \n tb.rulenode.custom-expression-field-input-hint\n \n
\n
\n tb.rulenode.result-title\n
\n \n tb.rulenode.type-field-input\n \n \n {{ argumentTypeResultMap.get(mathFunctionConfigForm.get(\'result.type\').value)?.name | translate }}\n \n \n {{ argumentTypeResultMap.get(argument).name | translate }}\n \n {{ argumentTypeResultMap.get(argument).description }}\n \n \n \n \n tb.rulenode.type-field-input-required\n \n \n
\n \n tb.rulenode.attribute-scope-field-input\n \n \n {{ attributeScopeMap.get(scope) | translate }}\n \n \n \n \n tb.rulenode.key-field-input\n \n help\n \n tb.rulenode.key-field-input-required\n \n \n
\n
\n \n tb.rulenode.number-floating-point-field-input\n \n \n \n
\n
\n \n {{\'tb.rulenode.add-to-message-field-input\' | translate }}\n \n \n {{\'tb.rulenode.add-to-metadata-field-input\' | translate}}\n \n
\n
\n
\n
\n',styles:[":host ::ng-deep .fields-group{padding:0 16px 8px;margin:10px 0;border:1px groove rgba(0,0,0,.25);border-radius:4px}:host ::ng-deep .fields-group .mat-mdc-form-field .mat-mdc-form-field-infix{width:100%}:host ::ng-deep .fields-group legend{color:#000000b3;width:-moz-fit-content;width:fit-content}:host ::ng-deep .fields-group legend+*{display:block}:host ::ng-deep .fields-group legend+*.no-margin-top{margin-top:0}\n"],dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:J.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:W.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"directive",type:ee.MatSelectTrigger,selector:"mat-select-trigger"},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:Z.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:O.FormGroupName,selector:"[formGroupName]",inputs:["formGroupName"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Nn,selector:"tb-arguments-map-config",inputs:["disabled","function"]},{kind:"component",type:Sn,selector:"tb-math-function-autocomplete",inputs:["required","disabled"]},{kind:"pipe",type:Ce.SafePipe,name:"safe"},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:qn,decorators:[{type:n,args:[{selector:"tb-action-node-math-function-config",template:'
\n \n \n
\n tb.rulenode.argument-tile\n \n \n
\n
\n {{\'tb.rulenode.custom-expression-field-input\' | translate }} *\n \n \n \n tb.rulenode.custom-expression-field-input-required\n \n tb.rulenode.custom-expression-field-input-hint\n \n
\n
\n tb.rulenode.result-title\n
\n \n tb.rulenode.type-field-input\n \n \n {{ argumentTypeResultMap.get(mathFunctionConfigForm.get(\'result.type\').value)?.name | translate }}\n \n \n {{ argumentTypeResultMap.get(argument).name | translate }}\n \n {{ argumentTypeResultMap.get(argument).description }}\n \n \n \n \n tb.rulenode.type-field-input-required\n \n \n
\n \n tb.rulenode.attribute-scope-field-input\n \n \n {{ attributeScopeMap.get(scope) | translate }}\n \n \n \n \n tb.rulenode.key-field-input\n \n help\n \n tb.rulenode.key-field-input-required\n \n \n
\n
\n \n tb.rulenode.number-floating-point-field-input\n \n \n \n
\n
\n \n {{\'tb.rulenode.add-to-message-field-input\' | translate }}\n \n \n {{\'tb.rulenode.add-to-metadata-field-input\' | translate}}\n \n
\n
\n
\n
\n',styles:[":host ::ng-deep .fields-group{padding:0 16px 8px;margin:10px 0;border:1px groove rgba(0,0,0,.25);border-radius:4px}:host ::ng-deep .fields-group .mat-mdc-form-field .mat-mdc-form-field-infix{width:100%}:host ::ng-deep .fields-group legend{color:#000000b3;width:-moz-fit-content;width:fit-content}:host ::ng-deep .fields-group legend+*{display:block}:host ::ng-deep .fields-group legend+*.no-margin-top{margin-top:0}\n"]}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class An{constructor(){this.textAlign="left"}}e("ExampleHintComponent",An),An.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:An,deps:[],target:t.ɵɵFactoryTarget.Component}),An.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:An,selector:"tb-example-hint",inputs:{hintText:"hintText",popupHelpLink:"popupHelpLink",textAlign:"textAlign"},ngImport:t,template:'
\n
\n
\n
\n
\n',styles:[":host .space-between{display:flex;justify-content:space-between;gap:20px}:host .space-between .see-example{display:flex;flex-shrink:0}:host .hint-text{width:100%}\n"],dependencies:[{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:$e.HelpPopupComponent,selector:"[tb-help-popup], [tb-help-popup-content]",inputs:["tb-help-popup","tb-help-popup-content","trigger-text","trigger-style","tb-help-popup-placement","tb-help-popup-style","hintMode"]},{kind:"pipe",type:Ce.SafePipe,name:"safe"},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:An,decorators:[{type:n,args:[{selector:"tb-example-hint",template:'
\n
\n
\n
\n
\n',styles:[":host .space-between{display:flex;justify-content:space-between;gap:20px}:host .space-between .see-example{display:flex;flex-shrink:0}:host .hint-text{width:100%}\n"]}]}],propDecorators:{hintText:[{type:i}],popupHelpLink:[{type:i}],textAlign:[{type:i}]}});class Mn{constructor(e,t){this.injector=e,this.fb=t,this.propagateChange=()=>{},this.destroy$=new Ke,this.disabled=!1,this.uniqueKeyValuePairValidator=!1,this.required=!1,this.duplicateValuesValidator=e=>e.controls.key.value===e.controls.value.value&&e.controls.key.value&&e.controls.value.value?{uniqueKeyValuePair:!0}:null,this.oneMapRequiredValidator=e=>e.get("keyVals").value.length,this.propagateNestedErrors=e=>{if(this.kvListFormGroup&&this.kvListFormGroup.get("keyVals")&&"VALID"===this.kvListFormGroup.get("keyVals")?.status)return null;const t={};if(this.kvListFormGroup&&this.kvListFormGroup.setErrors(null),e instanceof U||e instanceof H){if(e.errors)for(const n of Object.keys(e.errors))t[n]=!0;for(const n of Object.keys(e.controls)){const r=this.propagateNestedErrors(e.controls[n]);if(r&&Object.keys(r).length)for(const e of Object.keys(r))t[e]=!0}return t}if(e.errors)for(const n of Object.keys(e.errors))t[n]=!0;return le(t,{})?null:t}}ngOnInit(){this.ngControl=this.injector.get(B),null!=this.ngControl&&(this.ngControl.valueAccessor=this),this.kvListFormGroup=this.fb.group({keyVals:this.fb.array([])},{validators:[this.propagateNestedErrors,this.oneMapRequiredValidator]}),this.kvListFormGroup.valueChanges.pipe(ze(this.destroy$)).subscribe((()=>{this.updateModel()}))}ngOnDestroy(){this.destroy$.next(),this.destroy$.complete()}keyValsFormArray(){return this.kvListFormGroup.get("keyVals")}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.kvListFormGroup.disable({emitEvent:!1}):this.kvListFormGroup.enable({emitEvent:!1})}writeValue(e){const t=Object.keys(e).map((t=>({key:t,value:e[t]})));if(this.keyValsFormArray().length===t.length)this.keyValsFormArray().patchValue(t,{emitEvent:!1});else{const e=[];t.forEach((t=>{e.push(this.fb.group({key:[t.key,[_.required,_.pattern(/(?:.|\s)*\S(&:.|\s)*/)]],value:[t.value,[_.required,_.pattern(/(?:.|\s)*\S(&:.|\s)*/)]]},{validators:this.uniqueKeyValuePairValidator?[this.duplicateValuesValidator]:[]}))})),this.kvListFormGroup.setControl("keyVals",this.fb.array(e,this.propagateNestedErrors),{emitEvent:!1})}}removeKeyVal(e){this.keyValsFormArray().removeAt(e)}addKeyVal(){this.keyValsFormArray().push(this.fb.group({key:["",[_.required,_.pattern(/(?:.|\s)*\S(&:.|\s)*/)]],value:["",[_.required,_.pattern(/(?:.|\s)*\S(&:.|\s)*/)]]},{validators:this.uniqueKeyValuePairValidator?[this.duplicateValuesValidator]:[]}))}validate(){const e=this.kvListFormGroup.get("keyVals").value;if(!e.length&&this.required)return{kvMapRequired:!0};if(!this.kvListFormGroup.valid)return{kvFieldsRequired:!0};if(this.uniqueKeyValuePairValidator)for(const t of e)if(t.key===t.value)return{uniqueKeyValuePair:!0};return null}updateModel(){const e=this.kvListFormGroup.get("keyVals").value;if(this.required&&!e.length||!this.kvListFormGroup.valid)this.propagateChange(null);else{const t={};e.forEach((e=>{t[e.key]=e.value})),this.propagateChange(t)}}}e("KvMapConfigComponent",Mn),Mn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Mn,deps:[{token:t.Injector},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Mn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Mn,selector:"tb-kv-map-config",inputs:{disabled:"disabled",uniqueKeyValuePairValidator:"uniqueKeyValuePairValidator",labelText:"labelText",requiredText:"requiredText",keyText:"keyText",keyRequiredText:"keyRequiredText",valText:"valText",valRequiredText:"valRequiredText",hintText:"hintText",popupHelpLink:"popupHelpLink",required:"required"},providers:[{provide:K,useExisting:a((()=>Mn)),multi:!0},{provide:z,useExisting:a((()=>Mn)),multi:!0}],ngImport:t,template:'
\n
\n
{{ labelText }}
\n
\n {{ requiredText }}\n
\n
\n tb.rulenode.map-fields-required\n
\n
\n {{ \'tb.key-val.unique-key-value-pair-error\' | translate:\n {\n valText: valText,\n keyText: keyText\n } }}\n
\n
\n
\n
\n
\n
{{ keyText }}
\n
{{ valText }}
\n
\n
\n
\n
\n \n \n \n \n \n \n
\n \n
\n
\n
\n
\n
\n
\n \n
\n \n
\n',styles:[":host .field-space{flex:1 1 50%}:host .actions-header{width:40px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ce.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ce.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.FormControlDirective,selector:"[formControl]",inputs:["formControl","disabled","ngModel"],outputs:["ngModelChange"],exportAs:["ngForm"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:An,selector:"tb-example-hint",inputs:["hintText","popupHelpLink","textAlign"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),Be([I()],Mn.prototype,"disabled",void 0),Be([I()],Mn.prototype,"uniqueKeyValuePairValidator",void 0),Be([I()],Mn.prototype,"required",void 0),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Mn,decorators:[{type:n,args:[{selector:"tb-kv-map-config",providers:[{provide:K,useExisting:a((()=>Mn)),multi:!0},{provide:z,useExisting:a((()=>Mn)),multi:!0}],template:'
\n
\n
{{ labelText }}
\n
\n {{ requiredText }}\n
\n
\n tb.rulenode.map-fields-required\n
\n
\n {{ \'tb.key-val.unique-key-value-pair-error\' | translate:\n {\n valText: valText,\n keyText: keyText\n } }}\n
\n
\n
\n
\n
\n
{{ keyText }}
\n
{{ valText }}
\n
\n
\n
\n
\n \n \n \n \n \n \n
\n \n
\n
\n
\n
\n
\n
\n \n
\n \n
\n',styles:[":host .field-space{flex:1 1 50%}:host .actions-header{width:40px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:t.Injector},{type:O.FormBuilder}]},propDecorators:{disabled:[{type:i}],uniqueKeyValuePairValidator:[{type:i}],labelText:[{type:i}],requiredText:[{type:i}],keyText:[{type:i}],keyRequiredText:[{type:i}],valText:[{type:i}],valRequiredText:[{type:i}],hintText:[{type:i}],popupHelpLink:[{type:i}],required:[{type:i}]}});class En extends T{get required(){return this.requiredValue}set required(e){this.requiredValue=Le(e)}constructor(e,t){super(e),this.store=e,this.fb=t,this.directionTypes=Object.values(C),this.directionTypeTranslations=F,this.entityType=k,this.propagateChange=null}ngOnInit(){this.deviceRelationsQueryFormGroup=this.fb.group({fetchLastLevelOnly:[!1,[]],direction:[null,[_.required]],maxLevel:[null,[_.min(1)]],relationType:[null],deviceTypes:[null,[_.required]]}),this.deviceRelationsQueryFormGroup.valueChanges.subscribe((e=>{this.deviceRelationsQueryFormGroup.valid?this.propagateChange(e):this.propagateChange(null)}))}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.deviceRelationsQueryFormGroup.disable({emitEvent:!1}):this.deviceRelationsQueryFormGroup.enable({emitEvent:!1})}writeValue(e){this.deviceRelationsQueryFormGroup.reset(e,{emitEvent:!1})}}e("DeviceRelationsQueryConfigComponent",En),En.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:En,deps:[{token:R.Store},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),En.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:En,selector:"tb-device-relations-query-config",inputs:{disabled:"disabled",required:"required"},providers:[{provide:K,useExisting:a((()=>En)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }} tb.rulenode.relations-query-config-direction-suffix\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n {{ \'tb.rulenode.max-relation-level-error\' | translate }}\n \n \n
\n
\n \n {{ \'alias.last-level-relation\' | translate }}\n \n
\n \n \n \n help\n \n
\n',styles:[":host .last-level-slide-toggle{margin:8px 0 24px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Qe.EntitySubTypeListComponent,selector:"tb-entity-subtype-list",inputs:["required","floatLabel","label","disabled","entityType","emptyInputPlaceholder","filledInputPlaceholder","appearance","subscriptSizing","additionalClasses"]},{kind:"component",type:Je.RelationTypeAutocompleteComponent,selector:"tb-relation-type-autocomplete",inputs:["showLabel","additionalClasses","appearance","required","disabled","subscriptSizing"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:W.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:ne.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:re.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:En,decorators:[{type:n,args:[{selector:"tb-device-relations-query-config",providers:[{provide:K,useExisting:a((()=>En)),multi:!0}],template:'
\n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }} tb.rulenode.relations-query-config-direction-suffix\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n {{ \'tb.rulenode.max-relation-level-error\' | translate }}\n \n \n
\n
\n \n {{ \'alias.last-level-relation\' | translate }}\n \n
\n \n \n \n help\n \n
\n',styles:[":host .last-level-slide-toggle{margin:8px 0 24px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder}]},propDecorators:{disabled:[{type:i}],required:[{type:i}]}});class Gn extends T{get required(){return this.requiredValue}set required(e){this.requiredValue=Le(e)}constructor(e,t){super(e),this.store=e,this.fb=t,this.directionTypes=Object.values(C),this.directionTypeTranslations=F,this.propagateChange=null}ngOnInit(){this.relationsQueryFormGroup=this.fb.group({fetchLastLevelOnly:[!1,[]],direction:[null,[_.required]],maxLevel:[null,[_.min(1)]],filters:[null]}),this.relationsQueryFormGroup.valueChanges.subscribe((e=>{this.relationsQueryFormGroup.valid?this.propagateChange(e):this.propagateChange(null)}))}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.relationsQueryFormGroup.disable({emitEvent:!1}):this.relationsQueryFormGroup.enable({emitEvent:!1})}writeValue(e){this.relationsQueryFormGroup.reset(e||{},{emitEvent:!1})}}e("RelationsQueryConfigComponent",Gn),Gn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Gn,deps:[{token:R.Store},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Gn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Gn,selector:"tb-relations-query-config",inputs:{disabled:"disabled",required:"required"},providers:[{provide:K,useExisting:a((()=>Gn)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n
tb.rulenode.relations-query
\n
\n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }} tb.rulenode.relations-query-config-direction-suffix\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n {{ \'tb.rulenode.max-relation-level-error\' | translate }}\n \n \n
\n
\n \n {{ \'alias.last-level-relation\' | translate }}\n \n
\n
\n
\n
relation.relation-filters
\n \n \n
\n
\n',dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:ne.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:re.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"component",type:Ye.RelationFiltersComponent,selector:"tb-relation-filters",inputs:["disabled","allowedEntityTypes"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Gn,decorators:[{type:n,args:[{selector:"tb-relations-query-config",providers:[{provide:K,useExisting:a((()=>Gn)),multi:!0}],template:'
\n
tb.rulenode.relations-query
\n
\n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }} tb.rulenode.relations-query-config-direction-suffix\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n {{ \'tb.rulenode.max-relation-level-error\' | translate }}\n \n \n
\n
\n \n {{ \'alias.last-level-relation\' | translate }}\n \n
\n
\n
\n
relation.relation-filters
\n \n \n
\n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder}]},propDecorators:{disabled:[{type:i}],required:[{type:i}]}});class Dn extends T{get required(){return this.requiredValue}set required(e){this.requiredValue=Le(e)}constructor(e,t,n,r){super(e),this.store=e,this.translate=t,this.truncate=n,this.fb=r,this.placeholder="tb.rulenode.add-message-type",this.separatorKeysCodes=[xe,be,he],this.messageTypes=[],this.messageTypesList=[],this.searchText="",this.propagateChange=e=>{},this.messageTypeConfigForm=this.fb.group({messageType:[null]});for(const e of Object.keys(N))this.messageTypesList.push({name:S.get(N[e]),value:e})}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}ngOnInit(){this.filteredMessageTypes=this.messageTypeConfigForm.get("messageType").valueChanges.pipe(Ge(""),Ee((e=>e||"")),De((e=>this.fetchMessageTypes(e))),Ve())}setDisabledState(e){this.disabled=e,this.disabled?this.messageTypeConfigForm.disable({emitEvent:!1}):this.messageTypeConfigForm.enable({emitEvent:!1})}writeValue(e){this.searchText="",this.messageTypes.length=0,e&&e.forEach((e=>{const t=this.messageTypesList.find((t=>t.value===e));t?this.messageTypes.push({name:t.name,value:t.value}):this.messageTypes.push({name:e,value:e})}))}displayMessageTypeFn(e){return e?e.name:void 0}textIsNotEmpty(e){return e&&e.length>0}createMessageType(e,t){e.preventDefault(),this.transformMessageType(t)}add(e){this.transformMessageType(e.value)}fetchMessageTypes(e){if(this.searchText=e,this.searchText&&this.searchText.length){const e=this.searchText.toUpperCase();return Ue(this.messageTypesList.filter((t=>t.name.toUpperCase().includes(e))))}return Ue(this.messageTypesList)}transformMessageType(e){if((e||"").trim()){let t;const n=e.trim(),r=this.messageTypesList.find((e=>e.name===n));t=r?{name:r.name,value:r.value}:{name:n,value:n},t&&this.addMessageType(t)}this.clear("")}remove(e){const t=this.messageTypes.indexOf(e);t>=0&&(this.messageTypes.splice(t,1),this.updateModel())}selected(e){this.addMessageType(e.option.value),this.clear("")}addMessageType(e){-1===this.messageTypes.findIndex((t=>t.value===e.value))&&(this.messageTypes.push(e),this.updateModel())}onFocus(){this.messageTypeConfigForm.get("messageType").updateValueAndValidity({onlySelf:!0,emitEvent:!0})}clear(e=""){this.messageTypeInput.nativeElement.value=e,this.messageTypeConfigForm.get("messageType").patchValue(null,{emitEvent:!0}),setTimeout((()=>{this.messageTypeInput.nativeElement.blur(),this.messageTypeInput.nativeElement.focus()}),0)}updateModel(){const e=this.messageTypes.map((e=>e.value));this.required?(this.chipList.errorState=!e.length,this.propagateChange(e.length>0?e:null)):(this.chipList.errorState=!1,this.propagateChange(e))}}e("MessageTypesConfigComponent",Dn),Dn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Dn,deps:[{token:R.Store},{token:X.TranslateService},{token:q.TruncatePipe},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Dn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Dn,selector:"tb-message-types-config",inputs:{required:"required",label:"label",placeholder:"placeholder",disabled:"disabled"},providers:[{provide:K,useExisting:a((()=>Dn)),multi:!0}],viewQueries:[{propertyName:"chipList",first:!0,predicate:["chipList"],descendants:!0},{propertyName:"matAutocomplete",first:!0,predicate:["messageTypeAutocomplete"],descendants:!0},{propertyName:"messageTypeInput",first:!0,predicate:["messageTypeInput"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'\n {{ label }}\n \n \n {{messageType.name}}\n close\n \n \n \n \n \n \n \n \n
\n
\n tb.rulenode.no-message-types-found\n
\n \n \n {{ \'tb.rulenode.no-message-type-matching\' | translate :\n {messageType: truncate.transform(searchText, true, 6, '...')}\n }}\n \n \n \n tb.rulenode.create-new-message-type\n \n
\n
\n
\n help\n \n {{ \'tb.rulenode.select-message-types-required\' | translate }}\n \n
\n',dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:W.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:Re.MatAutocomplete,selector:"mat-autocomplete",inputs:["disableRipple","hideSingleSelectionIndicator"],exportAs:["matAutocomplete"]},{kind:"directive",type:Re.MatAutocompleteTrigger,selector:"input[matAutocomplete], textarea[matAutocomplete]",exportAs:["matAutocompleteTrigger"]},{kind:"directive",type:Re.MatAutocompleteOrigin,selector:"[matAutocompleteOrigin]",exportAs:["matAutocompleteOrigin"]},{kind:"component",type:ve.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:ve.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:ve.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:ve.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:j.AsyncPipe,name:"async"},{kind:"pipe",type:Oe.HighlightPipe,name:"highlight"},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Dn,decorators:[{type:n,args:[{selector:"tb-message-types-config",providers:[{provide:K,useExisting:a((()=>Dn)),multi:!0}],template:'\n {{ label }}\n \n \n {{messageType.name}}\n close\n \n \n \n \n \n \n \n \n
\n
\n tb.rulenode.no-message-types-found\n
\n \n \n {{ \'tb.rulenode.no-message-type-matching\' | translate :\n {messageType: truncate.transform(searchText, true, 6, '...')}\n }}\n \n \n \n tb.rulenode.create-new-message-type\n \n
\n
\n
\n help\n \n {{ \'tb.rulenode.select-message-types-required\' | translate }}\n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:X.TranslateService},{type:q.TruncatePipe},{type:O.FormBuilder}]},propDecorators:{required:[{type:i}],label:[{type:i}],placeholder:[{type:i}],disabled:[{type:i}],chipList:[{type:o,args:["chipList",{static:!1}]}],matAutocomplete:[{type:o,args:["messageTypeAutocomplete",{static:!1}]}],messageTypeInput:[{type:o,args:["messageTypeInput",{static:!1}]}]}});class Vn extends T{get required(){return this.requiredValue}set required(e){this.requiredValue=Le(e)}constructor(e,t){super(e),this.store=e,this.fb=t,this.subscriptions=[],this.disableCertPemCredentials=!1,this.passwordFieldRequired=!0,this.allCredentialsTypes=jt,this.credentialsTypeTranslationsMap=$t,this.propagateChange=e=>{}}ngOnInit(){this.credentialsConfigFormGroup=this.fb.group({type:[null,[_.required]],username:[null,[]],password:[null,[]],caCert:[null,[]],caCertFileName:[null,[]],privateKey:[null,[]],privateKeyFileName:[null,[]],cert:[null,[]],certFileName:[null,[]]}),this.subscriptions.push(this.credentialsConfigFormGroup.valueChanges.subscribe((()=>{this.updateView()}))),this.subscriptions.push(this.credentialsConfigFormGroup.get("type").valueChanges.subscribe((()=>{this.credentialsTypeChanged()})))}ngOnChanges(e){for(const t of Object.keys(e)){const n=e[t];if(!n.firstChange&&n.currentValue!==n.previousValue&&n.currentValue&&"disableCertPemCredentials"===t){"cert.PEM"===this.credentialsConfigFormGroup.get("type").value&&setTimeout((()=>{this.credentialsConfigFormGroup.get("type").patchValue("anonymous",{emitEvent:!0})}))}}}ngOnDestroy(){this.subscriptions.forEach((e=>e.unsubscribe()))}writeValue(e){se(e)&&(this.credentialsConfigFormGroup.reset(e,{emitEvent:!1}),this.updateValidators())}setDisabledState(e){e?this.credentialsConfigFormGroup.disable({emitEvent:!1}):(this.credentialsConfigFormGroup.enable({emitEvent:!1}),this.updateValidators())}updateView(){let e=this.credentialsConfigFormGroup.value;const t=e.type;switch(t){case"anonymous":e={type:t};break;case"basic":e={type:t,username:e.username,password:e.password};break;case"cert.PEM":delete e.username}this.propagateChange(e)}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}validate(e){return this.credentialsConfigFormGroup.valid?null:{credentialsConfig:{valid:!1}}}credentialsTypeChanged(){this.credentialsConfigFormGroup.patchValue({username:null,password:null,caCert:null,caCertFileName:null,privateKey:null,privateKeyFileName:null,cert:null,certFileName:null}),this.updateValidators()}updateValidators(e=!1){const t=this.credentialsConfigFormGroup.get("type").value;switch(e&&this.credentialsConfigFormGroup.reset({type:t},{emitEvent:!1}),this.credentialsConfigFormGroup.setValidators([]),this.credentialsConfigFormGroup.get("username").setValidators([]),this.credentialsConfigFormGroup.get("password").setValidators([]),t){case"anonymous":break;case"basic":this.credentialsConfigFormGroup.get("username").setValidators([_.required]),this.credentialsConfigFormGroup.get("password").setValidators(this.passwordFieldRequired?[_.required]:[]);break;case"cert.PEM":this.credentialsConfigFormGroup.setValidators([this.requiredFilesSelected(_.required,[["caCert","caCertFileName"],["privateKey","privateKeyFileName","cert","certFileName"]])])}this.credentialsConfigFormGroup.get("username").updateValueAndValidity({emitEvent:e}),this.credentialsConfigFormGroup.get("password").updateValueAndValidity({emitEvent:e}),this.credentialsConfigFormGroup.updateValueAndValidity({emitEvent:e})}requiredFilesSelected(e,t=null){return n=>{t||(t=[Object.keys(n.controls)]);return n?.controls&&t.some((t=>t.every((t=>!e(n.controls[t])))))?null:{notAllRequiredFilesSelected:!0}}}}e("CredentialsConfigComponent",Vn),Vn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Vn,deps:[{token:R.Store},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Vn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Vn,selector:"tb-credentials-config",inputs:{required:"required",disableCertPemCredentials:"disableCertPemCredentials",passwordFieldRequired:"passwordFieldRequired"},providers:[{provide:K,useExisting:a((()=>Vn)),multi:!0},{provide:z,useExisting:a((()=>Vn)),multi:!0}],usesInheritance:!0,usesOnChanges:!0,ngImport:t,template:'
\n \n \n tb.rulenode.credentials\n \n {{ credentialsTypeTranslationsMap.get(credentialsConfigFormGroup.get(\'type\').value) | translate }}\n \n \n \n \n tb.rulenode.credentials-type\n \n \n {{ credentialsTypeTranslationsMap.get(credentialsType) | translate }}\n \n \n \n {{ \'tb.rulenode.credentials-type-required\' | translate }}\n \n \n
\n \n \n \n \n tb.rulenode.username\n \n \n {{ \'tb.rulenode.username-required\' | translate }}\n \n \n \n tb.rulenode.password\n \n \n \n {{ \'tb.rulenode.password-required\' | translate }}\n \n \n \n \n
{{ \'tb.rulenode.credentials-pem-hint\' | translate }}
\n \n \n \n \n \n \n \n tb.rulenode.private-key-password\n \n \n \n
\n
\n
\n
\n
\n',dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:j.NgSwitch,selector:"[ngSwitch]",inputs:["ngSwitch"]},{kind:"directive",type:j.NgSwitchCase,selector:"[ngSwitchCase]",inputs:["ngSwitchCase"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:W.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:We.MatExpansionPanel,selector:"mat-expansion-panel",inputs:["disabled","expanded","hideToggle","togglePosition"],outputs:["opened","closed","expandedChange","afterExpand","afterCollapse"],exportAs:["matExpansionPanel"]},{kind:"component",type:We.MatExpansionPanelHeader,selector:"mat-expansion-panel-header",inputs:["tabIndex","expandedHeight","collapsedHeight"]},{kind:"directive",type:We.MatExpansionPanelTitle,selector:"mat-panel-title"},{kind:"directive",type:We.MatExpansionPanelDescription,selector:"mat-panel-description"},{kind:"directive",type:We.MatExpansionPanelContent,selector:"ng-template[matExpansionPanelContent]"},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:Ze.FileInputComponent,selector:"tb-file-input",inputs:["label","hint","accept","noFileText","inputId","allowedExtensions","dropLabel","contentConvertFunction","required","requiredAsError","disabled","existingFileName","readAsBinary","workFromFileObj","multipleFile"],outputs:["fileNameChanged"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Xe.TogglePasswordComponent,selector:"tb-toggle-password"},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Vn,decorators:[{type:n,args:[{selector:"tb-credentials-config",providers:[{provide:K,useExisting:a((()=>Vn)),multi:!0},{provide:z,useExisting:a((()=>Vn)),multi:!0}],template:'
\n \n \n tb.rulenode.credentials\n \n {{ credentialsTypeTranslationsMap.get(credentialsConfigFormGroup.get(\'type\').value) | translate }}\n \n \n \n \n tb.rulenode.credentials-type\n \n \n {{ credentialsTypeTranslationsMap.get(credentialsType) | translate }}\n \n \n \n {{ \'tb.rulenode.credentials-type-required\' | translate }}\n \n \n
\n \n \n \n \n tb.rulenode.username\n \n \n {{ \'tb.rulenode.username-required\' | translate }}\n \n \n \n tb.rulenode.password\n \n \n \n {{ \'tb.rulenode.password-required\' | translate }}\n \n \n \n \n
{{ \'tb.rulenode.credentials-pem-hint\' | translate }}
\n \n \n \n \n \n \n \n tb.rulenode.private-key-password\n \n \n \n
\n
\n
\n
\n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder}]},propDecorators:{required:[{type:i}],disableCertPemCredentials:[{type:i}],passwordFieldRequired:[{type:i}]}});const wn=new l("WindowToken","undefined"!=typeof window&&window.document?{providedIn:"root",factory:()=>window}:{providedIn:"root",factory:()=>{}});class Pn{constructor(e,t,n){this.ngZone=e,this.document=t,this.window=n,this.copySubject=new Ke,this.copyResponse$=this.copySubject.asObservable(),this.config={}}configure(e){this.config=e}copy(e){if(!this.isSupported||!e)return this.pushCopyResponse({isSuccess:!1,content:e});const t=this.copyFromContent(e);return t?this.pushCopyResponse({content:e,isSuccess:t}):this.pushCopyResponse({isSuccess:!1,content:e})}get isSupported(){return!!this.document.queryCommandSupported&&!!this.document.queryCommandSupported("copy")&&!!this.window}isTargetValid(e){if(e instanceof HTMLInputElement||e instanceof HTMLTextAreaElement){if(e.hasAttribute("disabled"))throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');return!0}throw new Error("Target should be input or textarea")}copyFromInputElement(e,t=!0){try{this.selectTarget(e);const n=this.copyText();return this.clearSelection(t?e:void 0,this.window),n&&this.isCopySuccessInIE11()}catch(e){return!1}}isCopySuccessInIE11(){const e=this.window.clipboardData;return!(e&&e.getData&&!e.getData("Text"))}copyFromContent(e,t=this.document.body){if(this.tempTextArea&&!t.contains(this.tempTextArea)&&this.destroy(this.tempTextArea.parentElement||void 0),!this.tempTextArea){this.tempTextArea=this.createTempTextArea(this.document,this.window);try{t.appendChild(this.tempTextArea)}catch(e){throw new Error("Container should be a Dom element")}}this.tempTextArea.value=e;const n=this.copyFromInputElement(this.tempTextArea,!1);return this.config.cleanUpAfterCopy&&this.destroy(this.tempTextArea.parentElement||void 0),n}destroy(e=this.document.body){this.tempTextArea&&(e.removeChild(this.tempTextArea),this.tempTextArea=void 0)}selectTarget(e){return e.select(),e.setSelectionRange(0,e.value.length),e.value.length}copyText(){return this.document.execCommand("copy")}clearSelection(e,t){e&&e.focus(),t.getSelection()?.removeAllRanges()}createTempTextArea(e,t){const n="rtl"===e.documentElement.getAttribute("dir");let r;r=e.createElement("textarea"),r.style.fontSize="12pt",r.style.border="0",r.style.padding="0",r.style.margin="0",r.style.position="absolute",r.style[n?"right":"left"]="-9999px";const o=t.pageYOffset||e.documentElement.scrollTop;return r.style.top=o+"px",r.setAttribute("readonly",""),r}pushCopyResponse(e){this.copySubject.observers.length>0&&this.ngZone.run((()=>{this.copySubject.next(e)}))}pushCopyReponse(e){this.pushCopyResponse(e)}}Pn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"13.0.1",ngImport:t,type:Pn,deps:[{token:t.NgZone},{token:$},{token:wn,optional:!0}],target:t.ɵɵFactoryTarget.Injectable}),Pn.ɵprov=t.ɵɵngDeclareInjectable({minVersion:"12.0.0",version:"13.0.1",ngImport:t,type:Pn,providedIn:"root"}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"13.0.1",ngImport:t,type:Pn,decorators:[{type:s,args:[{providedIn:"root"}]}],ctorParameters:function(){return[{type:t.NgZone},{type:void 0,decorators:[{type:m,args:[$]}]},{type:void 0,decorators:[{type:p},{type:m,args:[wn]}]}]}});class Rn{constructor(e,t,n,o){this.ngZone=e,this.host=t,this.renderer=n,this.clipboardSrv=o,this.cbOnSuccess=new r,this.cbOnError=new r,this.onClick=e=>{this.clipboardSrv.isSupported?this.targetElm&&this.clipboardSrv.isTargetValid(this.targetElm)?this.handleResult(this.clipboardSrv.copyFromInputElement(this.targetElm),this.targetElm.value,e):this.cbContent&&this.handleResult(this.clipboardSrv.copyFromContent(this.cbContent,this.container),this.cbContent,e):this.handleResult(!1,void 0,e)}}ngOnInit(){this.ngZone.runOutsideAngular((()=>{this.clickListener=this.renderer.listen(this.host.nativeElement,"click",this.onClick)}))}ngOnDestroy(){this.clickListener&&this.clickListener(),this.clipboardSrv.destroy(this.container)}handleResult(e,t,n){let r={isSuccess:e,content:t,successMessage:this.cbSuccessMsg,event:n};e?this.cbOnSuccess.observed&&this.ngZone.run((()=>{this.cbOnSuccess.emit(r)})):this.cbOnError.observed&&this.ngZone.run((()=>{this.cbOnError.emit(r)})),this.clipboardSrv.pushCopyResponse(r)}}Rn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"13.0.1",ngImport:t,type:Rn,deps:[{token:t.NgZone},{token:t.ElementRef},{token:t.Renderer2},{token:Pn}],target:t.ɵɵFactoryTarget.Directive}),Rn.ɵdir=t.ɵɵngDeclareDirective({minVersion:"12.0.0",version:"13.0.1",type:Rn,selector:"[ngxClipboard]",inputs:{targetElm:["ngxClipboard","targetElm"],container:"container",cbContent:"cbContent",cbSuccessMsg:"cbSuccessMsg"},outputs:{cbOnSuccess:"cbOnSuccess",cbOnError:"cbOnError"},ngImport:t}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"13.0.1",ngImport:t,type:Rn,decorators:[{type:u,args:[{selector:"[ngxClipboard]"}]}],ctorParameters:function(){return[{type:t.NgZone},{type:t.ElementRef},{type:t.Renderer2},{type:Pn}]},propDecorators:{targetElm:[{type:i,args:["ngxClipboard"]}],container:[{type:i}],cbContent:[{type:i}],cbSuccessMsg:[{type:i}],cbOnSuccess:[{type:d}],cbOnError:[{type:d}]}});class On{constructor(e,t,n){this._clipboardService=e,this._viewContainerRef=t,this._templateRef=n}ngOnInit(){this._clipboardService.isSupported&&this._viewContainerRef.createEmbeddedView(this._templateRef)}}On.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"13.0.1",ngImport:t,type:On,deps:[{token:Pn},{token:t.ViewContainerRef},{token:t.TemplateRef}],target:t.ɵɵFactoryTarget.Directive}),On.ɵdir=t.ɵɵngDeclareDirective({minVersion:"12.0.0",version:"13.0.1",type:On,selector:"[ngxClipboardIfSupported]",ngImport:t}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"13.0.1",ngImport:t,type:On,decorators:[{type:u,args:[{selector:"[ngxClipboardIfSupported]"}]}],ctorParameters:function(){return[{type:Pn},{type:t.ViewContainerRef},{type:t.TemplateRef}]}});class _n{}_n.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"13.0.1",ngImport:t,type:_n,deps:[],target:t.ɵɵFactoryTarget.NgModule}),_n.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"12.0.0",version:"13.0.1",ngImport:t,type:_n,declarations:[Rn,On],imports:[Q],exports:[Rn,On]}),_n.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"13.0.1",ngImport:t,type:_n,imports:[[Q]]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"13.0.1",ngImport:t,type:_n,decorators:[{type:c,args:[{imports:[Q],declarations:[Rn,On],exports:[Rn,On]}]}]});class Bn{set required(e){this.requiredValue!==e&&(this.requiredValue=e,this.updateValidators())}get required(){return this.requiredValue}constructor(e){this.fb=e,this.subscriptSizing="fixed",this.messageTypes=[{name:"Post attributes",value:"POST_ATTRIBUTES_REQUEST"},{name:"Post telemetry",value:"POST_TELEMETRY_REQUEST"},{name:"Custom",value:""}],this.propagateChange=()=>{},this.destroy$=new Ke,this.messageTypeFormGroup=this.fb.group({messageTypeAlias:[null,[_.required]],messageType:[{value:null,disabled:!0},[_.maxLength(255)]]}),this.messageTypeFormGroup.get("messageTypeAlias").valueChanges.pipe(ze(this.destroy$)).subscribe((e=>this.updateMessageTypeValue(e))),this.messageTypeFormGroup.valueChanges.pipe(ze(this.destroy$)).subscribe((()=>this.updateView()))}ngOnDestroy(){this.destroy$.next(),this.destroy$.complete()}registerOnTouched(e){}registerOnChange(e){this.propagateChange=e}writeValue(e){this.modelValue=e;let t=this.messageTypes.find((t=>t.value===e));t||(t=this.messageTypes.find((e=>""===e.value))),this.messageTypeFormGroup.get("messageTypeAlias").patchValue(t,{emitEvent:!1}),this.messageTypeFormGroup.get("messageType").patchValue(e,{emitEvent:!1})}validate(){return this.messageTypeFormGroup.valid?null:{messageTypeInvalid:!0}}setDisabledState(e){this.disabled=e,e?this.messageTypeFormGroup.disable({emitEvent:!1}):(this.messageTypeFormGroup.enable({emitEvent:!1}),"Custom"!==this.messageTypeFormGroup.get("messageTypeAlias").value?.name&&this.messageTypeFormGroup.get("messageType").disable({emitEvent:!1}))}updateView(){const e=this.messageTypeFormGroup.getRawValue().messageType;this.modelValue!==e&&(this.modelValue=e,this.propagateChange(this.modelValue))}updateValidators(){this.messageTypeFormGroup.get("messageType").setValidators(this.required?[_.required,_.maxLength(255)]:[_.maxLength(255)]),this.messageTypeFormGroup.get("messageType").updateValueAndValidity({emitEvent:!1})}updateMessageTypeValue(e){"Custom"!==e?.name?this.messageTypeFormGroup.get("messageType").disable({emitEvent:!1}):this.messageTypeFormGroup.get("messageType").enable({emitEvent:!1}),this.messageTypeFormGroup.get("messageType").patchValue(e.value??null)}}e("OutputMessageTypeAutocompleteComponent",Bn),Bn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Bn,deps:[{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Bn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Bn,selector:"tb-output-message-type-autocomplete",inputs:{subscriptSizing:"subscriptSizing",disabled:"disabled",required:"required"},providers:[{provide:K,useExisting:a((()=>Bn)),multi:!0},{provide:z,useExisting:a((()=>Bn)),multi:!0}],ngImport:t,template:'
\n \n {{\'tb.rulenode.output-message-type\' | translate}}\n \n \n {{msgType.name}}\n \n \n \n \n {{\'tb.rulenode.message-type-value\' | translate}}\n \n \n \n {{ \'tb.rulenode.message-type-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.message-type-value-max-length\' | translate }}\n \n \n
\n\n',dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ce.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:W.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:Rn,selector:"[ngxClipboard]",inputs:["ngxClipboard","container","cbContent","cbSuccessMsg"],outputs:["cbOnSuccess","cbOnError"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),Be([I()],Bn.prototype,"disabled",void 0),Be([I()],Bn.prototype,"required",null),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Bn,decorators:[{type:n,args:[{selector:"tb-output-message-type-autocomplete",providers:[{provide:K,useExisting:a((()=>Bn)),multi:!0},{provide:z,useExisting:a((()=>Bn)),multi:!0}],template:'
\n \n {{\'tb.rulenode.output-message-type\' | translate}}\n \n \n {{msgType.name}}\n \n \n \n \n {{\'tb.rulenode.message-type-value\' | translate}}\n \n \n \n {{ \'tb.rulenode.message-type-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.message-type-value-max-length\' | translate }}\n \n \n
\n\n'}]}],ctorParameters:function(){return[{type:O.FormBuilder}]},propDecorators:{subscriptSizing:[{type:i}],disabled:[{type:i}],required:[{type:i}]}});class Kn{constructor(e,t){this.fb=e,this.translate=t,this.translation=an,this.propagateChange=()=>{},this.destroy$=new Ke,this.selectOptions=[]}ngOnInit(){this.initOptions(),this.chipControlGroup=this.fb.group({chipControl:[null,[]]}),this.chipControlGroup.get("chipControl").valueChanges.pipe(we(this.destroy$)).subscribe((e=>{e&&this.propagateChange(e)}))}ngOnDestroy(){this.destroy$.next(),this.destroy$.complete()}initOptions(){for(const e of this.translation.keys())this.selectOptions.push({value:e,name:this.translate.instant(this.translation.get(e))})}writeValue(e){this.chipControlGroup.get("chipControl").patchValue(e,{emitEvent:!1})}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){e?this.chipControlGroup.disable({emitEvent:!1}):this.chipControlGroup.enable({emitEvent:!1})}}e("MsgMetadataChipComponent",Kn),Kn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Kn,deps:[{token:O.FormBuilder},{token:X.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Kn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Kn,selector:"tb-msg-metadata-chip",inputs:{labelText:"labelText",translation:"translation"},providers:[{provide:K,useExisting:a((()=>Kn)),multi:!0}],ngImport:t,template:'
\n
{{ labelText }}
\n \n {{ option.name }}\n \n
\n',dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"component",type:ve.MatChipListbox,selector:"mat-chip-listbox",inputs:["tabIndex","multiple","aria-orientation","selectable","compareWith","required","hideSingleSelectionIndicator","value"],outputs:["change"]},{kind:"component",type:ve.MatChipOption,selector:"mat-basic-chip-option, [mat-basic-chip-option], mat-chip-option, [mat-chip-option]",inputs:["color","disabled","disableRipple","tabIndex","selectable","selected"],outputs:["selectionChange"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Kn,decorators:[{type:n,args:[{selector:"tb-msg-metadata-chip",providers:[{provide:K,useExisting:a((()=>Kn)),multi:!0}],template:'
\n
{{ labelText }}
\n \n {{ option.name }}\n \n
\n'}]}],ctorParameters:function(){return[{type:O.FormBuilder},{type:X.TranslateService}]},propDecorators:{labelText:[{type:i}],translation:[{type:i}]}});class zn extends T{constructor(e,t,n,r){super(e),this.store=e,this.translate=t,this.injector=n,this.fb=r,this.destroy$=new Ke,this.sourceFieldSubcritption=[],this.propagateChange=null,this.disabled=!1,this.required=!1,this.oneMapRequiredValidator=e=>e.get("keyVals").value.length,this.propagateNestedErrors=e=>{if(this.svListFormGroup&&this.svListFormGroup.get("keyVals")&&"VALID"===this.svListFormGroup.get("keyVals")?.status)return null;const t={};if(this.svListFormGroup&&this.svListFormGroup.setErrors(null),e instanceof U||e instanceof H){if(e.errors)for(const n of Object.keys(e.errors))t[n]=!0;for(const n of Object.keys(e.controls)){const r=this.propagateNestedErrors(e.controls[n]);if(r&&Object.keys(r).length)for(const e of Object.keys(r))t[e]=!0}return t}if(e.errors)for(const n of Object.keys(e.errors))t[n]=!0;return le(t,{})?null:t}}ngOnInit(){this.ngControl=this.injector.get(B),null!=this.ngControl&&(this.ngControl.valueAccessor=this),this.svListFormGroup=this.fb.group({keyVals:this.fb.array([])},{validators:[this.propagateNestedErrors,this.oneMapRequiredValidator]}),this.svListFormGroup.valueChanges.pipe(we(this.destroy$)).subscribe((()=>{this.updateModel()}))}ngOnDestroy(){this.destroy$.next(),this.destroy$.complete()}keyValsFormArray(){return this.svListFormGroup.get("keyVals")}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.svListFormGroup.disable({emitEvent:!1}):this.svListFormGroup.enable({emitEvent:!1})}writeValue(e){const t=Object.keys(e).map((t=>({key:t,value:e[t]})));if(this.keyValsFormArray().length===t.length)this.keyValsFormArray().patchValue(t,{emitEvent:!1});else{const e=[];t.forEach((t=>{e.push(this.fb.group({key:[t.key,[_.required]],value:[t.value,[_.required,_.pattern(/(?:.|\s)*\S(&:.|\s)*/)]]}))})),this.svListFormGroup.setControl("keyVals",this.fb.array(e,this.propagateNestedErrors),{emitEvent:!1});for(const e of this.keyValsFormArray().controls)this.keyChangeSubscribe(e)}}filterSelectOptions(e){const t=[];for(const e of this.svListFormGroup.get("keyVals").value){const n=this.selectOptions.find((t=>t.value===e.key));n&&t.push(n)}const n=[];for(const r of this.selectOptions)se(t.find((e=>e.value===r.value)))&&r.value!==e?.get("key").value||n.push(r);return n}removeKeyVal(e){this.keyValsFormArray().removeAt(e),this.sourceFieldSubcritption[e].unsubscribe(),this.sourceFieldSubcritption.splice(e,1)}addKeyVal(){this.keyValsFormArray().push(this.fb.group({key:["",[_.required]],value:["",[_.required,_.pattern(/(?:.|\s)*\S(&:.|\s)*/)]]})),this.keyChangeSubscribe(this.keyValsFormArray().at(this.keyValsFormArray().length-1))}keyChangeSubscribe(e){this.sourceFieldSubcritption.push(e.get("key").valueChanges.pipe(we(this.destroy$)).subscribe((t=>{const n=Nt.get(t);e.get("value").patchValue(this.targetKeyPrefix+n[0].toUpperCase()+n.slice(1))})))}validate(e){return!this.svListFormGroup.get("keyVals").value.length&&this.required?{svMapRequired:!0}:this.svListFormGroup.valid?null:{svFieldsRequired:!0}}updateModel(){const e=this.svListFormGroup.get("keyVals").value;if(this.required&&!e.length||!this.svListFormGroup.valid)this.propagateChange(null);else{const t={};e.forEach((e=>{t[e.key]=e.value})),this.propagateChange(t)}}}e("SvMapConfigComponent",zn),zn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:zn,deps:[{token:R.Store},{token:X.TranslateService},{token:t.Injector},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),zn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:zn,selector:"tb-sv-map-config",inputs:{selectOptions:"selectOptions",disabled:"disabled",labelText:"labelText",requiredText:"requiredText",targetKeyPrefix:"targetKeyPrefix",selectText:"selectText",selectRequiredText:"selectRequiredText",valText:"valText",valRequiredText:"valRequiredText",hintText:"hintText",popupHelpLink:"popupHelpLink",required:"required"},providers:[{provide:K,useExisting:a((()=>zn)),multi:!0},{provide:z,useExisting:a((()=>zn)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n
\n
{{ labelText }}
\n
\n tb.rulenode.map-fields-required\n
\n
\n {{ requiredText }}\n
\n
\n
\n
\n
\n
{{ selectText }}
\n
{{ valText }}
\n
\n
\n
\n
\n \n \n \n {{option.name}}\n \n \n \n \n \n \n
\n \n
\n
\n
\n
\n
\n
\n \n
\n \n
\n',styles:[":host .field-space{flex:1 1 50%}:host .actions-header{width:40px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:j.NgClass,selector:"[ngClass]",inputs:["class","ngClass"]},{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ce.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ce.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:Se.DefaultClassDirective,selector:" [ngClass], [ngClass.xs], [ngClass.sm], [ngClass.md], [ngClass.lg], [ngClass.xl], [ngClass.lt-sm], [ngClass.lt-md], [ngClass.lt-lg], [ngClass.lt-xl], [ngClass.gt-xs], [ngClass.gt-sm], [ngClass.gt-md], [ngClass.gt-lg]",inputs:["ngClass","ngClass.xs","ngClass.sm","ngClass.md","ngClass.lg","ngClass.xl","ngClass.lt-sm","ngClass.lt-md","ngClass.lt-lg","ngClass.lt-xl","ngClass.gt-xs","ngClass.gt-sm","ngClass.gt-md","ngClass.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormControlDirective,selector:"[formControl]",inputs:["formControl","disabled","ngModel"],outputs:["ngModelChange"],exportAs:["ngForm"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:An,selector:"tb-example-hint",inputs:["hintText","popupHelpLink","textAlign"]},{kind:"pipe",type:j.AsyncPipe,name:"async"},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),Be([I()],zn.prototype,"disabled",void 0),Be([I()],zn.prototype,"required",void 0),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:zn,decorators:[{type:n,args:[{selector:"tb-sv-map-config",providers:[{provide:K,useExisting:a((()=>zn)),multi:!0},{provide:z,useExisting:a((()=>zn)),multi:!0}],template:'
\n
\n
{{ labelText }}
\n
\n tb.rulenode.map-fields-required\n
\n
\n {{ requiredText }}\n
\n
\n
\n
\n
\n
{{ selectText }}
\n
{{ valText }}
\n
\n
\n
\n
\n \n \n \n {{option.name}}\n \n \n \n \n \n \n
\n \n
\n
\n
\n
\n
\n
\n \n
\n \n
\n',styles:[":host .field-space{flex:1 1 50%}:host .actions-header{width:40px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:R.Store},{type:X.TranslateService},{type:t.Injector},{type:O.FormBuilder}]},propDecorators:{selectOptions:[{type:i}],disabled:[{type:i}],labelText:[{type:i}],requiredText:[{type:i}],targetKeyPrefix:[{type:i}],selectText:[{type:i}],selectRequiredText:[{type:i}],valText:[{type:i}],valRequiredText:[{type:i}],hintText:[{type:i}],popupHelpLink:[{type:i}],required:[{type:i}]}});class Un extends T{get required(){return this.requiredValue}set required(e){this.requiredValue=Le(e)}constructor(e,t){super(e),this.store=e,this.fb=t,this.directionTypes=Object.keys(C),this.directionTypeTranslations=F,this.propagateChange=null}ngOnInit(){this.relationsQueryFormGroup=this.fb.group({fetchLastLevelOnly:[!1,[]],direction:[null,[_.required]],maxLevel:[null,[]],filters:[null]}),this.relationsQueryFormGroup.valueChanges.subscribe((e=>{this.relationsQueryFormGroup.valid?this.propagateChange(e):this.propagateChange(null)}))}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.relationsQueryFormGroup.disable({emitEvent:!1}):this.relationsQueryFormGroup.enable({emitEvent:!1})}writeValue(e){this.relationsQueryFormGroup.reset(e||{},{emitEvent:!1})}}e("RelationsQueryConfigOldComponent",Un),Un.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Un,deps:[{token:R.Store},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Un.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Un,selector:"tb-relations-query-config-old",inputs:{disabled:"disabled",required:"required"},providers:[{provide:K,useExisting:a((()=>Un)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'alias.last-level-relation\' | translate }}\n \n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n
\n
relation.relation-filters
\n \n
\n',dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"component",type:J.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Ye.RelationFiltersComponent,selector:"tb-relation-filters",inputs:["disabled","allowedEntityTypes"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Un,decorators:[{type:n,args:[{selector:"tb-relations-query-config-old",providers:[{provide:K,useExisting:a((()=>Un)),multi:!0}],template:'
\n \n {{ \'alias.last-level-relation\' | translate }}\n \n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n
\n
relation.relation-filters
\n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder}]},propDecorators:{disabled:[{type:i}],required:[{type:i}]}});class Hn{constructor(e,t){this.translate=e,this.fb=t,this.propagateChange=e=>{},this.destroy$=new Ke,this.separatorKeysCodes=[xe,be,he],this.onTouched=()=>{}}ngOnInit(){this.attributeControlGroup=this.fb.group({clientAttributeNames:[[],[]],sharedAttributeNames:[[],[]],serverAttributeNames:[[],[]],latestTsKeyNames:[[],[]],getLatestValueWithTs:[!1,[]]},{validators:this.atLeastOne(_.required,["clientAttributeNames","sharedAttributeNames","serverAttributeNames","latestTsKeyNames"])}),this.attributeControlGroup.valueChanges.pipe(we(this.destroy$)).subscribe((e=>{this.propagateChange(this.preparePropagateValue(e))}))}preparePropagateValue(e){const t={};for(const n in e)t[n]="getLatestValueWithTs"===n||se(e[n])?e[n]:[];return t}validate(){return this.attributeControlGroup.valid?null:{atLeastOneRequired:!0}}atLeastOne(e,t=null){return n=>{t||(t=Object.keys(n.controls));return n?.controls&&t.some((t=>!e(n.controls[t])))?null:{atLeastOne:!0}}}writeValue(e){this.attributeControlGroup.setValue(e,{emitEvent:!1})}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){this.onTouched=e}setDisabledState(e){e?this.attributeControlGroup.disable({emitEvent:!1}):this.attributeControlGroup.enable({emitEvent:!1})}ngOnDestroy(){this.destroy$.next(null),this.destroy$.complete()}}e("SelectAttributesComponent",Hn),Hn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Hn,deps:[{token:X.TranslateService},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Hn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Hn,selector:"tb-select-attributes",inputs:{popupHelpLink:"popupHelpLink"},providers:[{provide:K,useExisting:a((()=>Hn)),multi:!0},{provide:z,useExisting:Hn,multi:!0}],ngImport:t,template:'
\n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n \n {{ \'tb.rulenode.fetch-latest-telemetry-with-timestamp\' | translate }}\n \n
\n
\n\n\n help\n\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:j.NgTemplateOutlet,selector:"[ngTemplateOutlet]",inputs:["ngTemplateOutletContext","ngTemplateOutlet","ngTemplateOutletInjector"]},{kind:"component",type:et.StringItemsListComponent,selector:"tb-string-items-list",inputs:["required","disabled","label","placeholder","hint","requiredText","floatLabel","appearance","editable","subscriptSizing","predefinedValues"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:W.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:ne.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:re.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"component",type:An,selector:"tb-example-hint",inputs:["hintText","popupHelpLink","textAlign"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Hn,decorators:[{type:n,args:[{selector:"tb-select-attributes",providers:[{provide:K,useExisting:a((()=>Hn)),multi:!0},{provide:z,useExisting:Hn,multi:!0}],template:'
\n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n \n {{ \'tb.rulenode.fetch-latest-telemetry-with-timestamp\' | translate }}\n \n
\n
\n\n\n help\n\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:X.TranslateService},{type:O.FormBuilder}]},propDecorators:{popupHelpLink:[{type:i}]}});class jn extends T{constructor(e,t){super(e),this.store=e,this.fb=t,this.propagateChange=null,this.destroy$=new Ke,this.alarmStatus=A,this.alarmStatusTranslations=M}ngOnInit(){this.alarmStatusGroup=this.fb.group({alarmStatus:[null,[]]}),this.alarmStatusGroup.get("alarmStatus").valueChanges.pipe(we(this.destroy$)).subscribe((e=>{this.propagateChange(e)}))}setDisabledState(e){e?this.alarmStatusGroup.disable({emitEvent:!1}):this.alarmStatusGroup.enable({emitEvent:!1})}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}ngOnDestroy(){this.destroy$.next(),this.destroy$.complete()}writeValue(e){this.alarmStatusGroup.get("alarmStatus").patchValue(e,{emitEvent:!1})}}e("AlarmStatusSelectComponent",jn),jn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:jn,deps:[{token:R.Store},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),jn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:jn,selector:"tb-alarm-status-select",providers:[{provide:K,useExisting:a((()=>jn)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n
\n \n {{ alarmStatusTranslations.get(alarmStatus.ACTIVE_UNACK) | translate }}\n \n \n {{ alarmStatusTranslations.get(alarmStatus.ACTIVE_ACK) | translate }}\n \n
\n
\n \n {{ alarmStatusTranslations.get(alarmStatus.CLEARED_UNACK) | translate }}\n \n \n {{ alarmStatusTranslations.get(alarmStatus.CLEARED_ACK) | translate }}\n \n
\n
\n
\n',styles:[":host .chip-listbox{max-width:460px;width:100%}:host .chip-listbox .toggle-column{display:flex;flex:1 1 100%;gap:8px}:host .chip-listbox .option{margin:0}@media screen and (max-width: 959px){:host .chip-listbox{max-width:360px}:host .chip-listbox .toggle-column{flex-direction:column}}:host ::ng-deep .chip-listbox .mdc-evolution-chip-set__chips{gap:8px}:host ::ng-deep .chip-listbox .option button{flex-basis:100%;justify-content:start}:host ::ng-deep .chip-listbox .option .mdc-evolution-chip__graphic{flex-grow:0}\n"],dependencies:[{kind:"component",type:ve.MatChipListbox,selector:"mat-chip-listbox",inputs:["tabIndex","multiple","aria-orientation","selectable","compareWith","required","hideSingleSelectionIndicator","value"],outputs:["change"]},{kind:"component",type:ve.MatChipOption,selector:"mat-basic-chip-option, [mat-basic-chip-option], mat-chip-option, [mat-chip-option]",inputs:["color","disabled","disableRipple","tabIndex","selectable","selected"],outputs:["selectionChange"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:jn,decorators:[{type:n,args:[{selector:"tb-alarm-status-select",providers:[{provide:K,useExisting:a((()=>jn)),multi:!0}],template:'
\n \n
\n \n {{ alarmStatusTranslations.get(alarmStatus.ACTIVE_UNACK) | translate }}\n \n \n {{ alarmStatusTranslations.get(alarmStatus.ACTIVE_ACK) | translate }}\n \n
\n
\n \n {{ alarmStatusTranslations.get(alarmStatus.CLEARED_UNACK) | translate }}\n \n \n {{ alarmStatusTranslations.get(alarmStatus.CLEARED_ACK) | translate }}\n \n
\n
\n
\n',styles:[":host .chip-listbox{max-width:460px;width:100%}:host .chip-listbox .toggle-column{display:flex;flex:1 1 100%;gap:8px}:host .chip-listbox .option{margin:0}@media screen and (max-width: 959px){:host .chip-listbox{max-width:360px}:host .chip-listbox .toggle-column{flex-direction:column}}:host ::ng-deep .chip-listbox .mdc-evolution-chip-set__chips{gap:8px}:host ::ng-deep .chip-listbox .option button{flex-basis:100%;justify-content:start}:host ::ng-deep .chip-listbox .option .mdc-evolution-chip__graphic{flex-grow:0}\n"]}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder}]}});class $n{}e("RulenodeCoreConfigCommonModule",$n),$n.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:$n,deps:[],target:t.ɵɵFactoryTarget.NgModule}),$n.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.10",ngImport:t,type:$n,declarations:[Mn,En,Gn,Dn,Vn,Nn,Sn,Bn,Fn,Kn,zn,Un,Hn,jn,An],imports:[Q,E,_e],exports:[Mn,En,Gn,Dn,Vn,Nn,Sn,Bn,Fn,Kn,zn,Un,Hn,jn,An]}),$n.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:$n,imports:[Q,E,_e]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:$n,decorators:[{type:c,args:[{declarations:[Mn,En,Gn,Dn,Vn,Nn,Sn,Bn,Fn,Kn,zn,Un,Hn,jn,An],imports:[Q,E,_e],exports:[Mn,En,Gn,Dn,Vn,Nn,Sn,Bn,Fn,Kn,zn,Un,Hn,jn,An]}]}]});class Qn{}e("RuleNodeCoreConfigActionModule",Qn),Qn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Qn,deps:[],target:t.ɵɵFactoryTarget.NgModule}),Qn.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.10",ngImport:t,type:Qn,declarations:[In,gt,Ln,Cn,gn,ft,xt,bt,ht,xn,vt,Ft,fn,yn,vn,kn,Tn,yt,Ct,hn,bn,qn],imports:[Q,E,_e,$n],exports:[In,gt,Ln,Cn,gn,ft,xt,bt,ht,xn,vt,Ft,fn,yn,vn,kn,Tn,yt,Ct,hn,bn,qn]}),Qn.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Qn,imports:[Q,E,_e,$n]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Qn,decorators:[{type:c,args:[{declarations:[In,gt,Ln,Cn,gn,ft,xt,bt,ht,xn,vt,Ft,fn,yn,vn,kn,Tn,yt,Ct,hn,bn,qn],imports:[Q,E,_e,$n],exports:[In,gt,Ln,Cn,gn,ft,xt,bt,ht,xn,vt,Ft,fn,yn,vn,kn,Tn,yt,Ct,hn,bn,qn]}]}]});class Jn extends f{constructor(e,t,n){super(e),this.store=e,this.translate=t,this.fb=n,this.separatorKeysCodes=[xe,be,he]}configForm(){return this.calculateDeltaConfigForm}onConfigurationSet(e){this.calculateDeltaConfigForm=this.fb.group({inputValueKey:[e.inputValueKey,[_.required,_.pattern(/(?:.|\s)*\S(&:.|\s)*/)]],outputValueKey:[e.outputValueKey,[_.required,_.pattern(/(?:.|\s)*\S(&:.|\s)*/)]],useCache:[e.useCache,[]],addPeriodBetweenMsgs:[e.addPeriodBetweenMsgs,[]],periodValueKey:[e.periodValueKey,[]],round:[e.round,[_.min(0),_.max(15)]],tellFailureIfDeltaIsNegative:[e.tellFailureIfDeltaIsNegative,[]]})}prepareInputConfig(e){return{inputValueKey:se(e?.inputValueKey)?e.inputValueKey:null,outputValueKey:se(e?.outputValueKey)?e.outputValueKey:null,useCache:!se(e?.useCache)||e.useCache,addPeriodBetweenMsgs:!!se(e?.addPeriodBetweenMsgs)&&e.addPeriodBetweenMsgs,periodValueKey:se(e?.periodValueKey)?e.periodValueKey:null,round:se(e?.round)?e.round:null,tellFailureIfDeltaIsNegative:!se(e?.tellFailureIfDeltaIsNegative)||e.tellFailureIfDeltaIsNegative}}prepareOutputConfig(e){return me(e)}updateValidators(e){this.calculateDeltaConfigForm.get("addPeriodBetweenMsgs").value?this.calculateDeltaConfigForm.get("periodValueKey").setValidators([_.required]):this.calculateDeltaConfigForm.get("periodValueKey").setValidators([]),this.calculateDeltaConfigForm.get("periodValueKey").updateValueAndValidity({emitEvent:e})}validatorTriggers(){return["addPeriodBetweenMsgs"]}}e("CalculateDeltaConfigComponent",Jn),Jn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Jn,deps:[{token:R.Store},{token:X.TranslateService},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Jn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Jn,selector:"tb-enrichment-node-calculate-delta-config",usesInheritance:!0,ngImport:t,template:"
\n
\n \n {{ 'tb.rulenode.input-value-key' | translate }}\n \n \n {{ 'tb.rulenode.input-value-key-required' | translate }}\n \n \n \n {{ 'tb.rulenode.output-value-key' | translate }}\n \n \n {{ 'tb.rulenode.output-value-key-required' | translate }}\n \n \n
\n \n {{ 'tb.rulenode.number-of-digits-after-floating-point' | translate }}\n \n \n {{ 'tb.rulenode.number-of-digits-after-floating-point-range' | translate }}\n \n \n {{ 'tb.rulenode.number-of-digits-after-floating-point-range' | translate }}\n \n \n
\n
\n \n {{ 'tb.rulenode.failure-if-delta-negative' | translate }}\n \n
\n
\n \n {{ 'tb.rulenode.use-caching' | translate }}\n \n
\n
\n
\n \n {{ 'tb.rulenode.add-time-difference-between-readings' | translate:\n { inputValueKey: calculateDeltaConfigForm.get('inputValueKey').valid ?\n calculateDeltaConfigForm.get('inputValueKey').value : 'tb.rulenode.input-value-key' | translate } }}\n \n
\n \n {{ 'tb.rulenode.period-value-key' | translate }}\n \n \n {{ 'tb.rulenode.period-value-key-required' | translate }}\n \n \n
\n
\n
\n",dependencies:[{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:ne.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:re.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Jn,decorators:[{type:n,args:[{selector:"tb-enrichment-node-calculate-delta-config",template:"
\n
\n \n {{ 'tb.rulenode.input-value-key' | translate }}\n \n \n {{ 'tb.rulenode.input-value-key-required' | translate }}\n \n \n \n {{ 'tb.rulenode.output-value-key' | translate }}\n \n \n {{ 'tb.rulenode.output-value-key-required' | translate }}\n \n \n
\n \n {{ 'tb.rulenode.number-of-digits-after-floating-point' | translate }}\n \n \n {{ 'tb.rulenode.number-of-digits-after-floating-point-range' | translate }}\n \n \n {{ 'tb.rulenode.number-of-digits-after-floating-point-range' | translate }}\n \n \n
\n
\n \n {{ 'tb.rulenode.failure-if-delta-negative' | translate }}\n \n
\n
\n \n {{ 'tb.rulenode.use-caching' | translate }}\n \n
\n
\n
\n \n {{ 'tb.rulenode.add-time-difference-between-readings' | translate:\n { inputValueKey: calculateDeltaConfigForm.get('inputValueKey').valid ?\n calculateDeltaConfigForm.get('inputValueKey').value : 'tb.rulenode.input-value-key' | translate } }}\n \n
\n \n {{ 'tb.rulenode.period-value-key' | translate }}\n \n \n {{ 'tb.rulenode.period-value-key-required' | translate }}\n \n \n
\n
\n
\n"}]}],ctorParameters:function(){return[{type:R.Store},{type:X.TranslateService},{type:O.FormBuilder}]}});class Yn extends f{constructor(e,t,n){super(e),this.store=e,this.fb=t,this.translate=n,this.fetchToData=[],this.DataToFetch=_t;for(const e of Bt.keys())e!==_t.FIELDS&&this.fetchToData.push({value:e,name:this.translate.instant(Bt.get(e))})}configForm(){return this.customerAttributesConfigForm}prepareOutputConfig(e){const t={};for(const n of Object.keys(e.dataMapping))t[n.trim()]=e.dataMapping[n];return e.dataMapping=t,me(e)}prepareInputConfig(e){let t,n;return t=se(e?.telemetry)?e.telemetry?_t.LATEST_TELEMETRY:_t.ATTRIBUTES:se(e?.dataToFetch)?e.dataToFetch:_t.ATTRIBUTES,n=se(e?.attrMapping)?e.attrMapping:se(e?.dataMapping)?e.dataMapping:null,{dataToFetch:t,dataMapping:n,fetchTo:se(e?.fetchTo)?e.fetchTo:rn.METADATA}}selectTranslation(e,t){return this.customerAttributesConfigForm.get("dataToFetch").value===_t.LATEST_TELEMETRY?e:t}onConfigurationSet(e){this.customerAttributesConfigForm=this.fb.group({dataToFetch:[e.dataToFetch,[]],dataMapping:[e.dataMapping,[_.required]],fetchTo:[e.fetchTo]})}}e("CustomerAttributesConfigComponent",Yn),Yn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Yn,deps:[{token:R.Store},{token:O.FormBuilder},{token:X.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Yn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Yn,selector:"tb-enrichment-node-customer-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n
tb.rulenode.mapping-of-customers
\n
\n
\n \n \n {{ data.name }}\n \n \n
\n
\n \n \n \n \n
\n',styles:[":host .fetch-to-data-toggle{max-width:420px;width:100%}\n"],dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:Z.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"directive",type:tt.ToggleOption,selector:"tb-toggle-option",inputs:["value"]},{kind:"component",type:nt.ToggleSelectComponent,selector:"tb-toggle-select",inputs:["disabled","selectMediaBreakpoint","appearance","disablePagination"]},{kind:"component",type:Mn,selector:"tb-kv-map-config",inputs:["disabled","uniqueKeyValuePairValidator","labelText","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","popupHelpLink","required"]},{kind:"component",type:Kn,selector:"tb-msg-metadata-chip",inputs:["labelText","translation"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Yn,decorators:[{type:n,args:[{selector:"tb-enrichment-node-customer-attributes-config",template:'
\n
tb.rulenode.mapping-of-customers
\n
\n
\n \n \n {{ data.name }}\n \n \n
\n
\n \n \n \n \n
\n',styles:[":host .fetch-to-data-toggle{max-width:420px;width:100%}\n"]}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder},{type:X.TranslateService}]}});class Wn extends f{constructor(e,t,n){super(e),this.store=e,this.translate=t,this.fb=n}configForm(){return this.deviceAttributesConfigForm}onConfigurationSet(e){this.deviceAttributesConfigForm=this.fb.group({deviceRelationsQuery:[e.deviceRelationsQuery,[_.required]],tellFailureIfAbsent:[e.tellFailureIfAbsent,[]],fetchTo:[e.fetchTo,[]],attributesControl:[e.attributesControl,[]]})}prepareInputConfig(e){return pe(e)&&(e.attributesControl={clientAttributeNames:se(e?.clientAttributeNames)?e.clientAttributeNames:[],latestTsKeyNames:se(e?.latestTsKeyNames)?e.latestTsKeyNames:[],serverAttributeNames:se(e?.serverAttributeNames)?e.serverAttributeNames:[],sharedAttributeNames:se(e?.sharedAttributeNames)?e.sharedAttributeNames:[],getLatestValueWithTs:!!se(e?.getLatestValueWithTs)&&e.getLatestValueWithTs}),{deviceRelationsQuery:se(e?.deviceRelationsQuery)?e.deviceRelationsQuery:null,tellFailureIfAbsent:!se(e?.tellFailureIfAbsent)||e.tellFailureIfAbsent,fetchTo:se(e?.fetchTo)?e.fetchTo:rn.METADATA,attributesControl:e?e.attributesControl:null}}prepareOutputConfig(e){for(const t of Object.keys(e.attributesControl))e[t]=e.attributesControl[t];return delete e.attributesControl,e}}e("DeviceAttributesConfigComponent",Wn),Wn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Wn,deps:[{token:R.Store},{token:X.TranslateService},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Wn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Wn,selector:"tb-enrichment-node-device-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n
\n
tb.rulenode.device-relations-query
\n \n \n
\n
\n
\n
tb.rulenode.related-device-attributes
\n
\n tb.rulenode.at-least-one-field-required\n
\n
\n \n \n
\n
\n \n {{ \'tb.rulenode.tell-failure\' | translate }}\n \n
\n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"component",type:ne.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:re.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"component",type:En,selector:"tb-device-relations-query-config",inputs:["disabled","required"]},{kind:"component",type:Kn,selector:"tb-msg-metadata-chip",inputs:["labelText","translation"]},{kind:"component",type:Hn,selector:"tb-select-attributes",inputs:["popupHelpLink"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Wn,decorators:[{type:n,args:[{selector:"tb-enrichment-node-device-attributes-config",template:'
\n
\n
tb.rulenode.device-relations-query
\n \n \n
\n
\n
\n
tb.rulenode.related-device-attributes
\n
\n tb.rulenode.at-least-one-field-required\n
\n
\n \n \n
\n
\n \n {{ \'tb.rulenode.tell-failure\' | translate }}\n \n
\n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:R.Store},{type:X.TranslateService},{type:O.FormBuilder}]}});class Zn extends f{constructor(e,t,n){super(e),this.store=e,this.translate=t,this.fb=n,this.predefinedValues=[];for(const e of Object.keys(Dt))this.predefinedValues.push({value:Dt[e],name:this.translate.instant(Vt.get(Dt[e]))})}ngOnInit(){super.ngOnInit()}configForm(){return this.entityDetailsConfigForm}prepareInputConfig(e){let t;return t=se(e?.addToMetadata)?e.addToMetadata?rn.METADATA:rn.DATA:e?.fetchTo?e.fetchTo:rn.DATA,{detailsList:se(e?.detailsList)?e.detailsList:null,fetchTo:t}}onConfigurationSet(e){this.entityDetailsConfigForm=this.fb.group({detailsList:[e.detailsList,[_.required]],fetchTo:[e.fetchTo,[]]})}}e("EntityDetailsConfigComponent",Zn),Zn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Zn,deps:[{token:R.Store},{token:X.TranslateService},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Zn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Zn,selector:"tb-enrichment-node-entity-details-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n help\n \n \n \n \n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"component",type:et.StringItemsListComponent,selector:"tb-string-items-list",inputs:["required","disabled","label","placeholder","hint","requiredText","floatLabel","appearance","editable","subscriptSizing","predefinedValues"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:W.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:Kn,selector:"tb-msg-metadata-chip",inputs:["labelText","translation"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Zn,decorators:[{type:n,args:[{selector:"tb-enrichment-node-entity-details-config",template:'
\n \n \n help\n \n \n \n \n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:R.Store},{type:X.TranslateService},{type:O.FormBuilder}]}});class Xn extends f{constructor(e,t,n){super(e),this.store=e,this.translate=t,this.fb=n,this.separatorKeysCodes=[xe,be,he],this.aggregationTypes=G,this.aggregations=Object.values(G),this.aggregationTypesTranslations=D,this.fetchMode=wt,this.samplingOrders=Object.values(Ot),this.samplingOrdersTranslate=zt,this.timeUnits=Object.values(At),this.timeUnitsTranslationMap=Mt,this.deduplicationStrategiesHintTranslations=Rt,this.headerOptions=[],this.timeUnitMap={[At.MILLISECONDS]:1,[At.SECONDS]:1e3,[At.MINUTES]:6e4,[At.HOURS]:36e5,[At.DAYS]:864e5},this.intervalValidator=()=>e=>e.get("startInterval").value*this.timeUnitMap[e.get("startIntervalTimeUnit").value]<=e.get("endInterval").value*this.timeUnitMap[e.get("endIntervalTimeUnit").value]?{intervalError:!0}:null;for(const e of Pt.keys())this.headerOptions.push({value:e,name:this.translate.instant(Pt.get(e))})}configForm(){return this.getTelemetryFromDatabaseConfigForm}onConfigurationSet(e){this.getTelemetryFromDatabaseConfigForm=this.fb.group({latestTsKeyNames:[e.latestTsKeyNames,[_.required]],aggregation:[e.aggregation,[_.required]],fetchMode:[e.fetchMode,[_.required]],orderBy:[e.orderBy,[]],limit:[e.limit,[]],useMetadataIntervalPatterns:[e.useMetadataIntervalPatterns,[]],interval:this.fb.group({startInterval:[e.interval.startInterval,[]],startIntervalTimeUnit:[e.interval.startIntervalTimeUnit,[]],endInterval:[e.interval.endInterval,[]],endIntervalTimeUnit:[e.interval.endIntervalTimeUnit,[]]}),startIntervalPattern:[e.startIntervalPattern,[]],endIntervalPattern:[e.endIntervalPattern,[]]})}validatorTriggers(){return["fetchMode","useMetadataIntervalPatterns"]}toggleChange(e){this.getTelemetryFromDatabaseConfigForm.get("fetchMode").patchValue(e,{emitEvent:!0})}prepareOutputConfig(e){return e.startInterval=e.interval.startInterval,e.startIntervalTimeUnit=e.interval.startIntervalTimeUnit,e.endInterval=e.interval.endInterval,e.endIntervalTimeUnit=e.interval.endIntervalTimeUnit,delete e.interval,me(e)}prepareInputConfig(e){return pe(e)&&(e.interval={startInterval:e.startInterval,startIntervalTimeUnit:e.startIntervalTimeUnit,endInterval:e.endInterval,endIntervalTimeUnit:e.endIntervalTimeUnit}),{latestTsKeyNames:se(e?.latestTsKeyNames)?e.latestTsKeyNames:null,aggregation:se(e?.aggregation)?e.aggregation:G.NONE,fetchMode:se(e?.fetchMode)?e.fetchMode:wt.FIRST,orderBy:se(e?.orderBy)?e.orderBy:Ot.ASC,limit:se(e?.limit)?e.limit:1e3,useMetadataIntervalPatterns:!!se(e?.useMetadataIntervalPatterns)&&e.useMetadataIntervalPatterns,interval:{startInterval:se(e?.interval?.startInterval)?e.interval.startInterval:2,startIntervalTimeUnit:se(e?.interval?.startIntervalTimeUnit)?e.interval.startIntervalTimeUnit:At.MINUTES,endInterval:se(e?.interval?.endInterval)?e.interval.endInterval:1,endIntervalTimeUnit:se(e?.interval?.endIntervalTimeUnit)?e.interval.endIntervalTimeUnit:At.MINUTES},startIntervalPattern:se(e?.startIntervalPattern)?e.startIntervalPattern:null,endIntervalPattern:se(e?.endIntervalPattern)?e.endIntervalPattern:null}}updateValidators(e){const t=this.getTelemetryFromDatabaseConfigForm.get("fetchMode").value,n=this.getTelemetryFromDatabaseConfigForm.get("useMetadataIntervalPatterns").value;t&&t===wt.ALL?(this.getTelemetryFromDatabaseConfigForm.get("aggregation").setValidators([_.required]),this.getTelemetryFromDatabaseConfigForm.get("orderBy").setValidators([_.required]),this.getTelemetryFromDatabaseConfigForm.get("limit").setValidators([_.required,_.min(2),_.max(1e3)])):(this.getTelemetryFromDatabaseConfigForm.get("aggregation").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("orderBy").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("limit").setValidators([])),n?(this.getTelemetryFromDatabaseConfigForm.get("interval.startInterval").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("interval.startIntervalTimeUnit").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("interval.endInterval").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("interval.endIntervalTimeUnit").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("interval").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("startIntervalPattern").setValidators([_.required,_.pattern(/(?:.|\s)*\S(&:.|\s)*/)]),this.getTelemetryFromDatabaseConfigForm.get("endIntervalPattern").setValidators([_.required,_.pattern(/(?:.|\s)*\S(&:.|\s)*/)])):(this.getTelemetryFromDatabaseConfigForm.get("interval.startInterval").setValidators([_.required,_.min(1),_.max(2147483647)]),this.getTelemetryFromDatabaseConfigForm.get("interval.startIntervalTimeUnit").setValidators([_.required]),this.getTelemetryFromDatabaseConfigForm.get("interval.endInterval").setValidators([_.required,_.min(1),_.max(2147483647)]),this.getTelemetryFromDatabaseConfigForm.get("interval.endIntervalTimeUnit").setValidators([_.required]),this.getTelemetryFromDatabaseConfigForm.get("interval").setValidators([this.intervalValidator()]),this.getTelemetryFromDatabaseConfigForm.get("startIntervalPattern").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("endIntervalPattern").setValidators([])),this.getTelemetryFromDatabaseConfigForm.get("aggregation").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("orderBy").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("limit").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("interval.startInterval").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("interval.startIntervalTimeUnit").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("interval.endInterval").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("interval.endIntervalTimeUnit").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("interval").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("startIntervalPattern").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("endIntervalPattern").updateValueAndValidity({emitEvent:e})}removeKey(e,t){const n=this.getTelemetryFromDatabaseConfigForm.get(t).value,r=n.indexOf(e);r>=0&&(n.splice(r,1),this.getTelemetryFromDatabaseConfigForm.get(t).setValue(n,{emitEvent:!0}))}clearChipGrid(){this.getTelemetryFromDatabaseConfigForm.get("latestTsKeyNames").patchValue([],{emitEvent:!0})}addKey(e,t){const n=e.input;let r=e.value;if((r||"").trim()){r=r.trim();let e=this.getTelemetryFromDatabaseConfigForm.get(t).value;e&&-1!==e.indexOf(r)||(e||(e=[]),e.push(r),this.getTelemetryFromDatabaseConfigForm.get(t).setValue(e,{emitEvent:!0}))}n&&(n.value="")}defaultPaddingEnable(){return this.getTelemetryFromDatabaseConfigForm.get("fetchMode").value===wt.ALL&&this.getTelemetryFromDatabaseConfigForm.get("aggregation").value===G.NONE}}e("GetTelemetryFromDatabaseConfigComponent",Xn),Xn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Xn,deps:[{token:R.Store},{token:X.TranslateService},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Xn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Xn,selector:"tb-enrichment-node-get-telemetry-from-database",usesInheritance:!0,ngImport:t,template:'
\n \n
\n help\n \n
\n
\n
tb.rulenode.fetch-interval
\n
\n \n {{ \'tb.rulenode.use-metadata-dynamic-interval\' | translate }}\n \n
\n
\n
\n \n {{ \'tb.rulenode.interval-start\' | translate }}\n \n \n {{ \'tb.rulenode.start-interval-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n {{ \'tb.rulenode.time-unit\' | translate }}\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n \n {{ \'tb.rulenode.interval-end\' | translate }}\n \n \n {{ \'tb.rulenode.end-interval-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n {{ \'tb.rulenode.time-unit\' | translate }}\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n error_outline\n
\n \n {{ \'tb.rulenode.fetch-timeseries-from-to\' | translate:\n {\n startInterval: getTelemetryFromDatabaseConfigForm.get(\'interval.startInterval\').value,\n endInterval: getTelemetryFromDatabaseConfigForm.get(\'interval.endInterval\').value,\n startIntervalTimeUnit: getTelemetryFromDatabaseConfigForm.get(\'interval.startIntervalTimeUnit\').value.toLowerCase(),\n endIntervalTimeUnit: getTelemetryFromDatabaseConfigForm.get(\'interval.endIntervalTimeUnit\').value.toLowerCase()\n } }}\n \n \n {{ "tb.rulenode.fetch-timeseries-from-to-invalid" | translate }}\n \n
\n
\n
\n \n
\n \n {{ \'tb.rulenode.start-interval\' | translate }}\n \n \n {{ \'tb.rulenode.start-interval-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.end-interval\' | translate }}\n \n \n {{ \'tb.rulenode.end-interval-required\' | translate }}\n \n \n \n \n
\n
\n
\n
\n
tb.rulenode.fetch-strategy
\n
\n
\n \n \n {{ data.name }}\n \n \n
\n
\n {{ deduplicationStrategiesHintTranslations.get(getTelemetryFromDatabaseConfigForm.get(\'fetchMode\').value) | translate }}\n
\n
\n
\n \n {{ \'aggregation.function\' | translate }}\n \n \n {{ aggregationTypesTranslations.get(aggregationTypes[aggregation]) | translate }}\n \n \n \n
\n \n {{ "tb.rulenode.order-by-timestamp" | translate }} \n \n \n {{ samplingOrdersTranslate.get(order) | translate }}\n \n \n \n \n {{ "tb.rulenode.limit" | translate }}\n \n {{ "tb.rulenode.limit-hint" | translate }}\n \n {{ \'tb.rulenode.limit-required\' | translate }}\n \n \n {{ \'tb.rulenode.limit-range\' | translate }}\n \n \n {{ \'tb.rulenode.limit-range\' | translate }}\n \n \n
\n
\n
\n
\n',styles:[":host .see-example{display:inline-block}:host .description-block{display:flex;align-items:center;border-radius:6px;border:1px solid #EAEAEA}:host .description-block .description-icon{font-size:24px;height:24px;min-height:24px;width:24px;min-width:24px;line-height:24px;color:#d9d9d9;margin:4px}:host .description-block .description-text{font-size:12px;line-height:16px;letter-spacing:.25px;margin:6px}:host .description-block.error{color:var(--mdc-theme-error, #f44336)}:host .description-block.error .description-icon{color:var(--mdc-theme-error, #f44336)}:host .item-center{align-items:center}:host .item-center .fetch-mod-toggle{width:100%}:host .hint-container{width:100%}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:$e.HelpPopupComponent,selector:"[tb-help-popup], [tb-help-popup-content]",inputs:["tb-help-popup","tb-help-popup-content","trigger-text","trigger-style","tb-help-popup-placement","tb-help-popup-style","hintMode"]},{kind:"component",type:et.StringItemsListComponent,selector:"tb-string-items-list",inputs:["required","disabled","label","placeholder","hint","requiredText","floatLabel","appearance","editable","subscriptSizing","predefinedValues"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:W.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:ne.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:O.FormGroupName,selector:"[formGroupName]",inputs:["formGroupName"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"directive",type:tt.ToggleOption,selector:"tb-toggle-option",inputs:["value"]},{kind:"component",type:nt.ToggleSelectComponent,selector:"tb-toggle-select",inputs:["disabled","selectMediaBreakpoint","appearance","disablePagination"]},{kind:"component",type:re.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"component",type:An,selector:"tb-example-hint",inputs:["hintText","popupHelpLink","textAlign"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Xn,decorators:[{type:n,args:[{selector:"tb-enrichment-node-get-telemetry-from-database",template:'
\n \n
\n help\n \n
\n
\n
tb.rulenode.fetch-interval
\n
\n \n {{ \'tb.rulenode.use-metadata-dynamic-interval\' | translate }}\n \n
\n
\n
\n \n {{ \'tb.rulenode.interval-start\' | translate }}\n \n \n {{ \'tb.rulenode.start-interval-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n {{ \'tb.rulenode.time-unit\' | translate }}\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n \n {{ \'tb.rulenode.interval-end\' | translate }}\n \n \n {{ \'tb.rulenode.end-interval-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n {{ \'tb.rulenode.time-unit\' | translate }}\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n error_outline\n
\n \n {{ \'tb.rulenode.fetch-timeseries-from-to\' | translate:\n {\n startInterval: getTelemetryFromDatabaseConfigForm.get(\'interval.startInterval\').value,\n endInterval: getTelemetryFromDatabaseConfigForm.get(\'interval.endInterval\').value,\n startIntervalTimeUnit: getTelemetryFromDatabaseConfigForm.get(\'interval.startIntervalTimeUnit\').value.toLowerCase(),\n endIntervalTimeUnit: getTelemetryFromDatabaseConfigForm.get(\'interval.endIntervalTimeUnit\').value.toLowerCase()\n } }}\n \n \n {{ "tb.rulenode.fetch-timeseries-from-to-invalid" | translate }}\n \n
\n
\n
\n \n
\n \n {{ \'tb.rulenode.start-interval\' | translate }}\n \n \n {{ \'tb.rulenode.start-interval-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.end-interval\' | translate }}\n \n \n {{ \'tb.rulenode.end-interval-required\' | translate }}\n \n \n \n \n
\n
\n
\n
\n
tb.rulenode.fetch-strategy
\n
\n
\n \n \n {{ data.name }}\n \n \n
\n
\n {{ deduplicationStrategiesHintTranslations.get(getTelemetryFromDatabaseConfigForm.get(\'fetchMode\').value) | translate }}\n
\n
\n
\n \n {{ \'aggregation.function\' | translate }}\n \n \n {{ aggregationTypesTranslations.get(aggregationTypes[aggregation]) | translate }}\n \n \n \n
\n \n {{ "tb.rulenode.order-by-timestamp" | translate }} \n \n \n {{ samplingOrdersTranslate.get(order) | translate }}\n \n \n \n \n {{ "tb.rulenode.limit" | translate }}\n \n {{ "tb.rulenode.limit-hint" | translate }}\n \n {{ \'tb.rulenode.limit-required\' | translate }}\n \n \n {{ \'tb.rulenode.limit-range\' | translate }}\n \n \n {{ \'tb.rulenode.limit-range\' | translate }}\n \n \n
\n
\n
\n
\n',styles:[":host .see-example{display:inline-block}:host .description-block{display:flex;align-items:center;border-radius:6px;border:1px solid #EAEAEA}:host .description-block .description-icon{font-size:24px;height:24px;min-height:24px;width:24px;min-width:24px;line-height:24px;color:#d9d9d9;margin:4px}:host .description-block .description-text{font-size:12px;line-height:16px;letter-spacing:.25px;margin:6px}:host .description-block.error{color:var(--mdc-theme-error, #f44336)}:host .description-block.error .description-icon{color:var(--mdc-theme-error, #f44336)}:host .item-center{align-items:center}:host .item-center .fetch-mod-toggle{width:100%}:host .hint-container{width:100%}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:R.Store},{type:X.TranslateService},{type:O.FormBuilder}]}});class er extends f{constructor(e,t,n){super(e),this.store=e,this.translate=t,this.fb=n}configForm(){return this.originatorAttributesConfigForm}onConfigurationSet(e){this.originatorAttributesConfigForm=this.fb.group({tellFailureIfAbsent:[e.tellFailureIfAbsent,[]],fetchTo:[e.fetchTo,[]],attributesControl:[e.attributesControl,[]]})}prepareInputConfig(e){return pe(e)&&(e.attributesControl={clientAttributeNames:se(e?.clientAttributeNames)?e.clientAttributeNames:[],latestTsKeyNames:se(e?.latestTsKeyNames)?e.latestTsKeyNames:[],serverAttributeNames:se(e?.serverAttributeNames)?e.serverAttributeNames:[],sharedAttributeNames:se(e?.sharedAttributeNames)?e.sharedAttributeNames:[],getLatestValueWithTs:!!se(e?.getLatestValueWithTs)&&e.getLatestValueWithTs}),{fetchTo:se(e?.fetchTo)?e.fetchTo:rn.METADATA,tellFailureIfAbsent:!!se(e?.tellFailureIfAbsent)&&e.tellFailureIfAbsent,attributesControl:se(e?.attributesControl)?e.attributesControl:null}}prepareOutputConfig(e){for(const t of Object.keys(e.attributesControl))e[t]=e.attributesControl[t];return delete e.attributesControl,e}}e("OriginatorAttributesConfigComponent",er),er.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:er,deps:[{token:R.Store},{token:X.TranslateService},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),er.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:er,selector:"tb-enrichment-node-originator-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n
\n
\n
tb.rulenode.originator-attributes
\n
\n tb.rulenode.at-least-one-field-required\n
\n
\n \n \n \n \n
\n
\n \n {{ \'tb.rulenode.tell-failure\' | translate }}\n \n
\n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"component",type:ne.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:re.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"component",type:Kn,selector:"tb-msg-metadata-chip",inputs:["labelText","translation"]},{kind:"component",type:Hn,selector:"tb-select-attributes",inputs:["popupHelpLink"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:er,decorators:[{type:n,args:[{selector:"tb-enrichment-node-originator-attributes-config",template:'
\n
\n
\n
tb.rulenode.originator-attributes
\n
\n tb.rulenode.at-least-one-field-required\n
\n
\n \n \n \n \n
\n
\n \n {{ \'tb.rulenode.tell-failure\' | translate }}\n \n
\n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:R.Store},{type:X.TranslateService},{type:O.FormBuilder}]}});class tr extends f{constructor(e,t,n){super(e),this.store=e,this.fb=t,this.translate=n,this.originatorFields=[];for(const e of It)this.originatorFields.push({value:e.value,name:this.translate.instant(e.name)})}configForm(){return this.originatorFieldsConfigForm}prepareOutputConfig(e){return me(e)}prepareInputConfig(e){return{dataMapping:se(e?.dataMapping)?e.dataMapping:null,ignoreNullStrings:se(e?.ignoreNullStrings)?e.ignoreNullStrings:null,fetchTo:se(e?.fetchTo)?e.fetchTo:rn.METADATA}}onConfigurationSet(e){this.originatorFieldsConfigForm=this.fb.group({dataMapping:[e.dataMapping,[_.required]],ignoreNullStrings:[e.ignoreNullStrings,[]],fetchTo:[e.fetchTo,[]]})}}e("OriginatorFieldsConfigComponent",tr),tr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:tr,deps:[{token:R.Store},{token:O.FormBuilder},{token:X.TranslateService}],target:t.ɵɵFactoryTarget.Component}),tr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:tr,selector:"tb-enrichment-node-originator-fields-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n
\n \n {{ \'tb.rulenode.skip-empty-fields\' | translate }}\n \n
\n
\n',dependencies:[{kind:"component",type:ne.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:re.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"component",type:Kn,selector:"tb-msg-metadata-chip",inputs:["labelText","translation"]},{kind:"component",type:zn,selector:"tb-sv-map-config",inputs:["selectOptions","disabled","labelText","requiredText","targetKeyPrefix","selectText","selectRequiredText","valText","valRequiredText","hintText","popupHelpLink","required"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:tr,decorators:[{type:n,args:[{selector:"tb-enrichment-node-originator-fields-config",template:'
\n \n \n \n \n
\n \n {{ \'tb.rulenode.skip-empty-fields\' | translate }}\n \n
\n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder},{type:X.TranslateService}]}});class nr extends f{constructor(e,t,n){super(e),this.store=e,this.fb=t,this.translate=n,this.DataToFetch=_t,this.msgMetadataLabelTranslations=Kt,this.originatorFields=[],this.fetchToData=[];for(const e of Object.keys(It))this.originatorFields.push({value:It[e].value,name:this.translate.instant(It[e].name)});for(const e of Bt.keys())this.fetchToData.push({value:e,name:this.translate.instant(Bt.get(e))})}configForm(){return this.relatedAttributesConfigForm}prepareOutputConfig(e){e.dataToFetch===_t.FIELDS?(e.dataMapping=e.svMap,delete e.svMap):(e.dataMapping=e.kvMap,delete e.kvMap);const t={};if(e&&e.dataMapping)for(const n of Object.keys(e.dataMapping))t[n.trim()]=e.dataMapping[n];return e.dataMapping=t,delete e.svMap,delete e.kvMap,me(e)}prepareInputConfig(e){let t,n,r={[L.name.value]:`relatedEntity${this.translate.instant(L.name.name)}`},o={serialNumber:"sn"};return t=se(e?.telemetry)?e.telemetry?_t.LATEST_TELEMETRY:_t.ATTRIBUTES:se(e?.dataToFetch)?e.dataToFetch:_t.ATTRIBUTES,n=se(e?.attrMapping)?e.attrMapping:se(e?.dataMapping)?e.dataMapping:null,t===_t.FIELDS?r=n:o=n,{relationsQuery:se(e?.relationsQuery)?e.relationsQuery:null,dataToFetch:t,svMap:r,kvMap:o,fetchTo:se(e?.fetchTo)?e.fetchTo:rn.METADATA}}selectTranslation(e,t){return this.relatedAttributesConfigForm.get("dataToFetch").value===_t.LATEST_TELEMETRY?e:t}onConfigurationSet(e){this.relatedAttributesConfigForm=this.fb.group({relationsQuery:[e.relationsQuery,[_.required]],dataToFetch:[e.dataToFetch,[]],kvMap:[e.kvMap,[_.required]],svMap:[e.svMap,[_.required]],fetchTo:[e.fetchTo,[]]})}validatorTriggers(){return["dataToFetch"]}updateValidators(e){this.relatedAttributesConfigForm.get("dataToFetch").value===_t.FIELDS?(this.relatedAttributesConfigForm.get("svMap").enable({emitEvent:!1}),this.relatedAttributesConfigForm.get("kvMap").disable({emitEvent:!1}),this.relatedAttributesConfigForm.get("svMap").updateValueAndValidity()):(this.relatedAttributesConfigForm.get("svMap").disable({emitEvent:!1}),this.relatedAttributesConfigForm.get("kvMap").enable({emitEvent:!1}),this.relatedAttributesConfigForm.get("kvMap").updateValueAndValidity())}}e("RelatedAttributesConfigComponent",nr),nr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:nr,deps:[{token:R.Store},{token:O.FormBuilder},{token:X.TranslateService}],target:t.ɵɵFactoryTarget.Component}),nr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:nr,selector:"tb-enrichment-node-related-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n
\n
tb.rulenode.data-to-fetch
\n \n \n {{ data.name }}\n \n \n \n \n \n \n \n \n
\n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"directive",type:tt.ToggleOption,selector:"tb-toggle-option",inputs:["value"]},{kind:"component",type:nt.ToggleSelectComponent,selector:"tb-toggle-select",inputs:["disabled","selectMediaBreakpoint","appearance","disablePagination"]},{kind:"component",type:Mn,selector:"tb-kv-map-config",inputs:["disabled","uniqueKeyValuePairValidator","labelText","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","popupHelpLink","required"]},{kind:"component",type:Gn,selector:"tb-relations-query-config",inputs:["disabled","required"]},{kind:"component",type:Kn,selector:"tb-msg-metadata-chip",inputs:["labelText","translation"]},{kind:"component",type:zn,selector:"tb-sv-map-config",inputs:["selectOptions","disabled","labelText","requiredText","targetKeyPrefix","selectText","selectRequiredText","valText","valRequiredText","hintText","popupHelpLink","required"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:nr,decorators:[{type:n,args:[{selector:"tb-enrichment-node-related-attributes-config",template:'
\n \n \n
\n
tb.rulenode.data-to-fetch
\n \n \n {{ data.name }}\n \n \n \n \n \n \n \n \n
\n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder},{type:X.TranslateService}]}});class rr extends f{constructor(e,t,n){super(e),this.store=e,this.fb=t,this.translate=n,this.fetchToData=[],this.DataToFetch=_t;for(const e of Bt.keys())e!==_t.FIELDS&&this.fetchToData.push({value:e,name:this.translate.instant(Bt.get(e))})}configForm(){return this.tenantAttributesConfigForm}prepareInputConfig(e){let t,n;return t=se(e?.telemetry)?e.telemetry?_t.LATEST_TELEMETRY:_t.ATTRIBUTES:se(e?.dataToFetch)?e.dataToFetch:_t.ATTRIBUTES,n=se(e?.attrMapping)?e.attrMapping:se(e?.dataMapping)?e.dataMapping:null,{dataToFetch:t,dataMapping:n,fetchTo:se(e?.fetchTo)?e.fetchTo:rn.METADATA}}selectTranslation(e,t){return this.tenantAttributesConfigForm.get("dataToFetch").value===_t.LATEST_TELEMETRY?e:t}onConfigurationSet(e){this.tenantAttributesConfigForm=this.fb.group({dataToFetch:[e.dataToFetch,[]],dataMapping:[e.dataMapping,[_.required]],fetchTo:[e.fetchTo,[]]})}}e("TenantAttributesConfigComponent",rr),rr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:rr,deps:[{token:R.Store},{token:O.FormBuilder},{token:X.TranslateService}],target:t.ɵɵFactoryTarget.Component}),rr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:rr,selector:"tb-enrichment-node-tenant-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n
tb.rulenode.mapping-of-tenant
\n
\n
\n \n \n {{ data.name }}\n \n \n
\n
\n \n \n \n \n
\n',styles:[":host .fetch-to-data-toggle{max-width:420px;width:100%}\n"],dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:Z.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"directive",type:tt.ToggleOption,selector:"tb-toggle-option",inputs:["value"]},{kind:"component",type:nt.ToggleSelectComponent,selector:"tb-toggle-select",inputs:["disabled","selectMediaBreakpoint","appearance","disablePagination"]},{kind:"component",type:Mn,selector:"tb-kv-map-config",inputs:["disabled","uniqueKeyValuePairValidator","labelText","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","popupHelpLink","required"]},{kind:"component",type:Kn,selector:"tb-msg-metadata-chip",inputs:["labelText","translation"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:rr,decorators:[{type:n,args:[{selector:"tb-enrichment-node-tenant-attributes-config",template:'
\n
tb.rulenode.mapping-of-tenant
\n
\n
\n \n \n {{ data.name }}\n \n \n
\n
\n \n \n \n \n
\n',styles:[":host .fetch-to-data-toggle{max-width:420px;width:100%}\n"]}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder},{type:X.TranslateService}]}});class or extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.fetchDeviceCredentialsConfigForm}prepareInputConfig(e){return{fetchTo:se(e?.fetchTo)?e.fetchTo:rn.METADATA}}onConfigurationSet(e){this.fetchDeviceCredentialsConfigForm=this.fb.group({fetchTo:[e.fetchTo,[]]})}}e("FetchDeviceCredentialsConfigComponent",or),or.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:or,deps:[{token:R.Store},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),or.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:or,selector:"./tb-enrichment-node-fetch-device-credentials-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n
\n',dependencies:[{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:Kn,selector:"tb-msg-metadata-chip",inputs:["labelText","translation"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:or,decorators:[{type:n,args:[{selector:"./tb-enrichment-node-fetch-device-credentials-config",template:'
\n \n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder}]}});class ar{}e("RulenodeCoreConfigEnrichmentModule",ar),ar.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ar,deps:[],target:t.ɵɵFactoryTarget.NgModule}),ar.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.10",ngImport:t,type:ar,declarations:[Yn,Zn,Wn,er,tr,Xn,nr,rr,Jn,or],imports:[Q,E,$n],exports:[Yn,Zn,Wn,er,tr,Xn,nr,rr,Jn,or]}),ar.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ar,imports:[Q,E,$n]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ar,decorators:[{type:c,args:[{declarations:[Yn,Zn,Wn,er,tr,Xn,nr,rr,Jn,or],imports:[Q,E,$n],exports:[Yn,Zn,Wn,er,tr,Xn,nr,rr,Jn,or]}]}]});class ir extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.allAzureIotHubCredentialsTypes=Qt,this.azureIotHubCredentialsTypeTranslationsMap=Jt}configForm(){return this.azureIotHubConfigForm}onConfigurationSet(e){this.azureIotHubConfigForm=this.fb.group({topicPattern:[e?e.topicPattern:null,[_.required]],host:[e?e.host:null,[_.required]],port:[e?e.port:null,[_.required,_.min(1),_.max(65535)]],connectTimeoutSec:[e?e.connectTimeoutSec:null,[_.required,_.min(1),_.max(200)]],clientId:[e?e.clientId:null,[_.required]],cleanSession:[!!e&&e.cleanSession,[]],ssl:[!!e&&e.ssl,[]],credentials:this.fb.group({type:[e&&e.credentials?e.credentials.type:null,[_.required]],sasKey:[e&&e.credentials?e.credentials.sasKey:null,[]],caCert:[e&&e.credentials?e.credentials.caCert:null,[]],caCertFileName:[e&&e.credentials?e.credentials.caCertFileName:null,[]],privateKey:[e&&e.credentials?e.credentials.privateKey:null,[]],privateKeyFileName:[e&&e.credentials?e.credentials.privateKeyFileName:null,[]],cert:[e&&e.credentials?e.credentials.cert:null,[]],certFileName:[e&&e.credentials?e.credentials.certFileName:null,[]],password:[e&&e.credentials?e.credentials.password:null,[]]})})}prepareOutputConfig(e){const t=e.credentials.type;return"sas"===t&&(e.credentials={type:t,sasKey:e.credentials.sasKey,caCert:e.credentials.caCert,caCertFileName:e.credentials.caCertFileName}),e}validatorTriggers(){return["credentials.type"]}updateValidators(e){const t=this.azureIotHubConfigForm.get("credentials"),n=t.get("type").value;switch(e&&t.reset({type:n},{emitEvent:!1}),t.get("sasKey").setValidators([]),t.get("privateKey").setValidators([]),t.get("privateKeyFileName").setValidators([]),t.get("cert").setValidators([]),t.get("certFileName").setValidators([]),n){case"sas":t.get("sasKey").setValidators([_.required]);break;case"cert.PEM":t.get("privateKey").setValidators([_.required]),t.get("privateKeyFileName").setValidators([_.required]),t.get("cert").setValidators([_.required]),t.get("certFileName").setValidators([_.required])}t.get("sasKey").updateValueAndValidity({emitEvent:e}),t.get("privateKey").updateValueAndValidity({emitEvent:e}),t.get("privateKeyFileName").updateValueAndValidity({emitEvent:e}),t.get("cert").updateValueAndValidity({emitEvent:e}),t.get("certFileName").updateValueAndValidity({emitEvent:e})}}e("AzureIotHubConfigComponent",ir),ir.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ir,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),ir.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:ir,selector:"tb-external-node-azure-iot-hub-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.topic\n \n \n {{ \'tb.rulenode.topic-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.hostname\n \n \n {{ \'tb.rulenode.hostname-required\' | translate }}\n \n \n \n tb.rulenode.device-id\n \n \n {{ \'tb.rulenode.device-id-required\' | translate }}\n \n \n \n \n \n tb.rulenode.credentials\n \n {{ azureIotHubCredentialsTypeTranslationsMap.get(azureIotHubConfigForm.get(\'credentials.type\').value) | translate }}\n \n \n
\n \n tb.rulenode.credentials-type\n \n \n {{ azureIotHubCredentialsTypeTranslationsMap.get(credentialsType) | translate }}\n \n \n \n {{ \'tb.rulenode.credentials-type-required\' | translate }}\n \n \n
\n \n \n \n \n tb.rulenode.sas-key\n \n \n \n {{ \'tb.rulenode.sas-key-required\' | translate }}\n \n \n \n \n \n \n \n \n \n \n \n \n \n tb.rulenode.private-key-password\n \n \n \n \n
\n
\n
\n
\n
\n',styles:[":host .tb-mqtt-credentials-panel-group{margin:0 6px}\n"],dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:j.NgSwitch,selector:"[ngSwitch]",inputs:["ngSwitch"]},{kind:"directive",type:j.NgSwitchCase,selector:"[ngSwitchCase]",inputs:["ngSwitchCase"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:W.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:We.MatAccordion,selector:"mat-accordion",inputs:["multi","hideToggle","displayMode","togglePosition"],exportAs:["matAccordion"]},{kind:"component",type:We.MatExpansionPanel,selector:"mat-expansion-panel",inputs:["disabled","expanded","hideToggle","togglePosition"],outputs:["opened","closed","expandedChange","afterExpand","afterCollapse"],exportAs:["matExpansionPanel"]},{kind:"component",type:We.MatExpansionPanelHeader,selector:"mat-expansion-panel-header",inputs:["tabIndex","expandedHeight","collapsedHeight"]},{kind:"directive",type:We.MatExpansionPanelTitle,selector:"mat-panel-title"},{kind:"directive",type:We.MatExpansionPanelDescription,selector:"mat-panel-description"},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:O.FormGroupName,selector:"[formGroupName]",inputs:["formGroupName"]},{kind:"component",type:Ze.FileInputComponent,selector:"tb-file-input",inputs:["label","hint","accept","noFileText","inputId","allowedExtensions","dropLabel","contentConvertFunction","required","requiredAsError","disabled","existingFileName","readAsBinary","workFromFileObj","multipleFile"],outputs:["fileNameChanged"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Xe.TogglePasswordComponent,selector:"tb-toggle-password"},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ir,decorators:[{type:n,args:[{selector:"tb-external-node-azure-iot-hub-config",template:'
\n \n tb.rulenode.topic\n \n \n {{ \'tb.rulenode.topic-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.hostname\n \n \n {{ \'tb.rulenode.hostname-required\' | translate }}\n \n \n \n tb.rulenode.device-id\n \n \n {{ \'tb.rulenode.device-id-required\' | translate }}\n \n \n \n \n \n tb.rulenode.credentials\n \n {{ azureIotHubCredentialsTypeTranslationsMap.get(azureIotHubConfigForm.get(\'credentials.type\').value) | translate }}\n \n \n
\n \n tb.rulenode.credentials-type\n \n \n {{ azureIotHubCredentialsTypeTranslationsMap.get(credentialsType) | translate }}\n \n \n \n {{ \'tb.rulenode.credentials-type-required\' | translate }}\n \n \n
\n \n \n \n \n tb.rulenode.sas-key\n \n \n \n {{ \'tb.rulenode.sas-key-required\' | translate }}\n \n \n \n \n \n \n \n \n \n \n \n \n \n tb.rulenode.private-key-password\n \n \n \n \n
\n
\n
\n
\n
\n',styles:[":host .tb-mqtt-credentials-panel-group{margin:0 6px}\n"]}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class lr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.ackValues=["all","-1","0","1"],this.ToByteStandartCharsetTypesValues=Wt,this.ToByteStandartCharsetTypeTranslationMap=Zt}configForm(){return this.kafkaConfigForm}onConfigurationSet(e){this.kafkaConfigForm=this.fb.group({topicPattern:[e?e.topicPattern:null,[_.required]],keyPattern:[e?e.keyPattern:null],bootstrapServers:[e?e.bootstrapServers:null,[_.required]],retries:[e?e.retries:null,[_.min(0)]],batchSize:[e?e.batchSize:null,[_.min(0)]],linger:[e?e.linger:null,[_.min(0)]],bufferMemory:[e?e.bufferMemory:null,[_.min(0)]],acks:[e?e.acks:null,[_.required]],keySerializer:[e?e.keySerializer:null,[_.required]],valueSerializer:[e?e.valueSerializer:null,[_.required]],otherProperties:[e?e.otherProperties:null,[]],addMetadataKeyValuesAsKafkaHeaders:[!!e&&e.addMetadataKeyValuesAsKafkaHeaders,[]],kafkaHeadersCharset:[e?e.kafkaHeadersCharset:null,[]]})}validatorTriggers(){return["addMetadataKeyValuesAsKafkaHeaders"]}updateValidators(e){this.kafkaConfigForm.get("addMetadataKeyValuesAsKafkaHeaders").value?this.kafkaConfigForm.get("kafkaHeadersCharset").setValidators([_.required]):this.kafkaConfigForm.get("kafkaHeadersCharset").setValidators([]),this.kafkaConfigForm.get("kafkaHeadersCharset").updateValueAndValidity({emitEvent:e})}}e("KafkaConfigComponent",lr),lr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:lr,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),lr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:lr,selector:"tb-external-node-kafka-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.topic-pattern\n \n \n {{ \'tb.rulenode.topic-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.key-pattern\n \n tb.rulenode.general-pattern-hint\n \n
tb.rulenode.key-pattern-hint
\n \n tb.rulenode.bootstrap-servers\n \n \n {{ \'tb.rulenode.bootstrap-servers-required\' | translate }}\n \n \n \n tb.rulenode.retries\n \n \n {{ \'tb.rulenode.min-retries-message\' | translate }}\n \n \n \n tb.rulenode.batch-size-bytes\n \n \n {{ \'tb.rulenode.min-batch-size-bytes-message\' | translate }}\n \n \n \n tb.rulenode.linger-ms\n \n \n {{ \'tb.rulenode.min-linger-ms-message\' | translate }}\n \n \n \n tb.rulenode.buffer-memory-bytes\n \n \n {{ \'tb.rulenode.min-buffer-memory-bytes-message\' | translate }}\n \n \n \n tb.rulenode.acks\n \n \n {{ ackValue }}\n \n \n \n \n tb.rulenode.key-serializer\n \n \n {{ \'tb.rulenode.key-serializer-required\' | translate }}\n \n \n \n tb.rulenode.value-serializer\n \n \n {{ \'tb.rulenode.value-serializer-required\' | translate }}\n \n \n \n \n \n \n {{ \'tb.rulenode.add-metadata-key-values-as-kafka-headers\' | translate }}\n \n
tb.rulenode.add-metadata-key-values-as-kafka-headers-hint
\n \n tb.rulenode.charset-encoding\n \n \n {{ ToByteStandartCharsetTypeTranslationMap.get(charset) | translate }}\n \n \n \n
\n',dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:J.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Fn,selector:"tb-kv-map-config-old",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:lr,decorators:[{type:n,args:[{selector:"tb-external-node-kafka-config",template:'
\n \n tb.rulenode.topic-pattern\n \n \n {{ \'tb.rulenode.topic-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.key-pattern\n \n tb.rulenode.general-pattern-hint\n \n
tb.rulenode.key-pattern-hint
\n \n tb.rulenode.bootstrap-servers\n \n \n {{ \'tb.rulenode.bootstrap-servers-required\' | translate }}\n \n \n \n tb.rulenode.retries\n \n \n {{ \'tb.rulenode.min-retries-message\' | translate }}\n \n \n \n tb.rulenode.batch-size-bytes\n \n \n {{ \'tb.rulenode.min-batch-size-bytes-message\' | translate }}\n \n \n \n tb.rulenode.linger-ms\n \n \n {{ \'tb.rulenode.min-linger-ms-message\' | translate }}\n \n \n \n tb.rulenode.buffer-memory-bytes\n \n \n {{ \'tb.rulenode.min-buffer-memory-bytes-message\' | translate }}\n \n \n \n tb.rulenode.acks\n \n \n {{ ackValue }}\n \n \n \n \n tb.rulenode.key-serializer\n \n \n {{ \'tb.rulenode.key-serializer-required\' | translate }}\n \n \n \n tb.rulenode.value-serializer\n \n \n {{ \'tb.rulenode.value-serializer-required\' | translate }}\n \n \n \n \n \n \n {{ \'tb.rulenode.add-metadata-key-values-as-kafka-headers\' | translate }}\n \n
tb.rulenode.add-metadata-key-values-as-kafka-headers-hint
\n \n tb.rulenode.charset-encoding\n \n \n {{ ToByteStandartCharsetTypeTranslationMap.get(charset) | translate }}\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class sr extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.mqttConfigForm}onConfigurationSet(e){this.mqttConfigForm=this.fb.group({topicPattern:[e?e.topicPattern:null,[_.required]],host:[e?e.host:null,[_.required]],port:[e?e.port:null,[_.required,_.min(1),_.max(65535)]],connectTimeoutSec:[e?e.connectTimeoutSec:null,[_.required,_.min(1),_.max(200)]],clientId:[e?e.clientId:null,[]],appendClientIdSuffix:[{value:!!e&&e.appendClientIdSuffix,disabled:!(e&&ue(e.clientId))},[]],cleanSession:[!!e&&e.cleanSession,[]],retainedMessage:[!!e&&e.retainedMessage,[]],ssl:[!!e&&e.ssl,[]],credentials:[e?e.credentials:null,[]]})}updateValidators(e){ue(this.mqttConfigForm.get("clientId").value)?this.mqttConfigForm.get("appendClientIdSuffix").enable({emitEvent:!1}):this.mqttConfigForm.get("appendClientIdSuffix").disable({emitEvent:!1}),this.mqttConfigForm.get("appendClientIdSuffix").updateValueAndValidity({emitEvent:e})}validatorTriggers(){return["clientId"]}}e("MqttConfigComponent",sr),sr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:sr,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),sr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:sr,selector:"tb-external-node-mqtt-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.topic-pattern\n \n \n {{ \'tb.rulenode.topic-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n
\n \n tb.rulenode.host\n \n \n {{ \'tb.rulenode.host-required\' | translate }}\n \n \n \n tb.rulenode.port\n \n \n {{ \'tb.rulenode.port-required\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n \n tb.rulenode.connect-timeout\n \n \n {{ \'tb.rulenode.connect-timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.connect-timeout-range\' | translate }}\n \n \n {{ \'tb.rulenode.connect-timeout-range\' | translate }}\n \n \n
\n \n tb.rulenode.client-id\n \n {{\'tb.rulenode.client-id-hint\' | translate}}\n \n \n {{ \'tb.rulenode.append-client-id-suffix\' | translate }}\n \n
{{ "tb.rulenode.client-id-suffix-hint" | translate }}
\n \n {{ \'tb.rulenode.clean-session\' | translate }}\n \n \n {{ "tb.rulenode.retained-message" | translate }}\n \n \n {{ \'tb.rulenode.enable-ssl\' | translate }}\n \n \n
\n',styles:[":host .tb-mqtt-credentials-panel-group{margin:0 6px}\n"],dependencies:[{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:J.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Vn,selector:"tb-credentials-config",inputs:["required","disableCertPemCredentials","passwordFieldRequired"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:sr,decorators:[{type:n,args:[{selector:"tb-external-node-mqtt-config",template:'
\n \n tb.rulenode.topic-pattern\n \n \n {{ \'tb.rulenode.topic-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n
\n \n tb.rulenode.host\n \n \n {{ \'tb.rulenode.host-required\' | translate }}\n \n \n \n tb.rulenode.port\n \n \n {{ \'tb.rulenode.port-required\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n \n tb.rulenode.connect-timeout\n \n \n {{ \'tb.rulenode.connect-timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.connect-timeout-range\' | translate }}\n \n \n {{ \'tb.rulenode.connect-timeout-range\' | translate }}\n \n \n
\n \n tb.rulenode.client-id\n \n {{\'tb.rulenode.client-id-hint\' | translate}}\n \n \n {{ \'tb.rulenode.append-client-id-suffix\' | translate }}\n \n
{{ "tb.rulenode.client-id-suffix-hint" | translate }}
\n \n {{ \'tb.rulenode.clean-session\' | translate }}\n \n \n {{ "tb.rulenode.retained-message" | translate }}\n \n \n {{ \'tb.rulenode.enable-ssl\' | translate }}\n \n \n
\n',styles:[":host .tb-mqtt-credentials-panel-group{margin:0 6px}\n"]}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class mr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.notificationType=V,this.entityType=k}configForm(){return this.notificationConfigForm}onConfigurationSet(e){this.notificationConfigForm=this.fb.group({templateId:[e?e.templateId:null,[_.required]],targets:[e?e.targets:[],[_.required]]})}}e("NotificationConfigComponent",mr),mr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:mr,deps:[{token:R.Store},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),mr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:mr,selector:"tb-external-node-notification-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n
\n',dependencies:[{kind:"component",type:rt.EntityListComponent,selector:"tb-entity-list",inputs:["entityType","subType","labelText","placeholderText","requiredText","required","disabled","subscriptSizing","hint"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:ot.TemplateAutocompleteComponent,selector:"tb-template-autocomplete",inputs:["required","allowCreate","allowEdit","disabled","notificationTypes"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:mr,decorators:[{type:n,args:[{selector:"tb-external-node-notification-config",template:'
\n \n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder}]}});class pr extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.pubSubConfigForm}onConfigurationSet(e){this.pubSubConfigForm=this.fb.group({projectId:[e?e.projectId:null,[_.required]],topicName:[e?e.topicName:null,[_.required]],serviceAccountKey:[e?e.serviceAccountKey:null,[_.required]],serviceAccountKeyFileName:[e?e.serviceAccountKeyFileName:null,[_.required]],messageAttributes:[e?e.messageAttributes:null,[]]})}}e("PubSubConfigComponent",pr),pr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:pr,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),pr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:pr,selector:"tb-external-node-pub-sub-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.gcp-project-id\n \n \n {{ \'tb.rulenode.gcp-project-id-required\' | translate }}\n \n \n \n tb.rulenode.pubsub-topic-name\n \n \n {{ \'tb.rulenode.pubsub-topic-name-required\' | translate }}\n \n \n \n \n \n
\n \n \n
\n',dependencies:[{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:Ze.FileInputComponent,selector:"tb-file-input",inputs:["label","hint","accept","noFileText","inputId","allowedExtensions","dropLabel","contentConvertFunction","required","requiredAsError","disabled","existingFileName","readAsBinary","workFromFileObj","multipleFile"],outputs:["fileNameChanged"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Fn,selector:"tb-kv-map-config-old",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:Ce.SafePipe,name:"safe"},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:pr,decorators:[{type:n,args:[{selector:"tb-external-node-pub-sub-config",template:'
\n \n tb.rulenode.gcp-project-id\n \n \n {{ \'tb.rulenode.gcp-project-id-required\' | translate }}\n \n \n \n tb.rulenode.pubsub-topic-name\n \n \n {{ \'tb.rulenode.pubsub-topic-name-required\' | translate }}\n \n \n \n \n \n
\n \n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class ur extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.messageProperties=[null,"BASIC","TEXT_PLAIN","MINIMAL_BASIC","MINIMAL_PERSISTENT_BASIC","PERSISTENT_BASIC","PERSISTENT_TEXT_PLAIN"]}configForm(){return this.rabbitMqConfigForm}onConfigurationSet(e){this.rabbitMqConfigForm=this.fb.group({exchangeNamePattern:[e?e.exchangeNamePattern:null,[]],routingKeyPattern:[e?e.routingKeyPattern:null,[]],messageProperties:[e?e.messageProperties:null,[]],host:[e?e.host:null,[_.required]],port:[e?e.port:null,[_.required,_.min(1),_.max(65535)]],virtualHost:[e?e.virtualHost:null,[]],username:[e?e.username:null,[]],password:[e?e.password:null,[]],automaticRecoveryEnabled:[!!e&&e.automaticRecoveryEnabled,[]],connectionTimeout:[e?e.connectionTimeout:null,[_.min(0)]],handshakeTimeout:[e?e.handshakeTimeout:null,[_.min(0)]],clientProperties:[e?e.clientProperties:null,[]]})}}e("RabbitMqConfigComponent",ur),ur.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ur,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),ur.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:ur,selector:"tb-external-node-rabbit-mq-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.exchange-name-pattern\n \n \n \n tb.rulenode.routing-key-pattern\n \n \n \n tb.rulenode.message-properties\n \n \n {{ property }}\n \n \n \n
\n \n tb.rulenode.host\n \n \n {{ \'tb.rulenode.host-required\' | translate }}\n \n \n \n tb.rulenode.port\n \n \n {{ \'tb.rulenode.port-required\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n
\n \n tb.rulenode.virtual-host\n \n \n \n tb.rulenode.username\n \n \n \n tb.rulenode.password\n \n \n \n \n {{ \'tb.rulenode.automatic-recovery\' | translate }}\n \n \n tb.rulenode.connection-timeout-ms\n \n \n {{ \'tb.rulenode.min-connection-timeout-ms-message\' | translate }}\n \n \n \n tb.rulenode.handshake-timeout-ms\n \n \n {{ \'tb.rulenode.min-handshake-timeout-ms-message\' | translate }}\n \n \n \n \n \n
\n',dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:J.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:W.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Xe.TogglePasswordComponent,selector:"tb-toggle-password"},{kind:"component",type:Fn,selector:"tb-kv-map-config-old",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ur,decorators:[{type:n,args:[{selector:"tb-external-node-rabbit-mq-config",template:'
\n \n tb.rulenode.exchange-name-pattern\n \n \n \n tb.rulenode.routing-key-pattern\n \n \n \n tb.rulenode.message-properties\n \n \n {{ property }}\n \n \n \n
\n \n tb.rulenode.host\n \n \n {{ \'tb.rulenode.host-required\' | translate }}\n \n \n \n tb.rulenode.port\n \n \n {{ \'tb.rulenode.port-required\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n
\n \n tb.rulenode.virtual-host\n \n \n \n tb.rulenode.username\n \n \n \n tb.rulenode.password\n \n \n \n \n {{ \'tb.rulenode.automatic-recovery\' | translate }}\n \n \n tb.rulenode.connection-timeout-ms\n \n \n {{ \'tb.rulenode.min-connection-timeout-ms-message\' | translate }}\n \n \n \n tb.rulenode.handshake-timeout-ms\n \n \n {{ \'tb.rulenode.min-handshake-timeout-ms-message\' | translate }}\n \n \n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class dr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.proxySchemes=["http","https"],this.httpRequestTypes=Object.keys(Yt)}configForm(){return this.restApiCallConfigForm}onConfigurationSet(e){this.restApiCallConfigForm=this.fb.group({restEndpointUrlPattern:[e?e.restEndpointUrlPattern:null,[_.required]],requestMethod:[e?e.requestMethod:null,[_.required]],useSimpleClientHttpFactory:[!!e&&e.useSimpleClientHttpFactory,[]],parseToPlainText:[!!e&&e.parseToPlainText,[]],ignoreRequestBody:[!!e&&e.ignoreRequestBody,[]],enableProxy:[!!e&&e.enableProxy,[]],useSystemProxyProperties:[!!e&&e.enableProxy,[]],proxyScheme:[e?e.proxyHost:null,[]],proxyHost:[e?e.proxyHost:null,[]],proxyPort:[e?e.proxyPort:null,[]],proxyUser:[e?e.proxyUser:null,[]],proxyPassword:[e?e.proxyPassword:null,[]],readTimeoutMs:[e?e.readTimeoutMs:null,[]],maxParallelRequestsCount:[e?e.maxParallelRequestsCount:null,[_.min(0)]],headers:[e?e.headers:null,[]],useRedisQueueForMsgPersistence:[!!e&&e.useRedisQueueForMsgPersistence,[]],trimQueue:[!!e&&e.trimQueue,[]],maxQueueSize:[e?e.maxQueueSize:null,[]],credentials:[e?e.credentials:null,[]]})}validatorTriggers(){return["useSimpleClientHttpFactory","useRedisQueueForMsgPersistence","enableProxy","useSystemProxyProperties"]}updateValidators(e){const t=this.restApiCallConfigForm.get("useSimpleClientHttpFactory").value,n=this.restApiCallConfigForm.get("useRedisQueueForMsgPersistence").value,r=this.restApiCallConfigForm.get("enableProxy").value,o=this.restApiCallConfigForm.get("useSystemProxyProperties").value;r&&!o?(this.restApiCallConfigForm.get("proxyHost").setValidators(r?[_.required]:[]),this.restApiCallConfigForm.get("proxyPort").setValidators(r?[_.required,_.min(1),_.max(65535)]:[])):(this.restApiCallConfigForm.get("proxyHost").setValidators([]),this.restApiCallConfigForm.get("proxyPort").setValidators([]),t?this.restApiCallConfigForm.get("readTimeoutMs").setValidators([]):this.restApiCallConfigForm.get("readTimeoutMs").setValidators([_.min(0)])),n?this.restApiCallConfigForm.get("maxQueueSize").setValidators([_.min(0)]):this.restApiCallConfigForm.get("maxQueueSize").setValidators([]),this.restApiCallConfigForm.get("readTimeoutMs").updateValueAndValidity({emitEvent:e}),this.restApiCallConfigForm.get("maxQueueSize").updateValueAndValidity({emitEvent:e}),this.restApiCallConfigForm.get("proxyHost").updateValueAndValidity({emitEvent:e}),this.restApiCallConfigForm.get("proxyPort").updateValueAndValidity({emitEvent:e}),this.restApiCallConfigForm.get("credentials").updateValueAndValidity({emitEvent:e})}}e("RestApiCallConfigComponent",dr),dr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:dr,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),dr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:dr,selector:"tb-external-node-rest-api-call-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.endpoint-url-pattern\n \n \n {{ \'tb.rulenode.endpoint-url-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.request-method\n \n \n {{ requestType }}\n \n \n \n \n {{ \'tb.rulenode.enable-proxy\' | translate }}\n \n \n {{ \'tb.rulenode.use-simple-client-http-factory\' | translate }}\n \n \n {{ \'tb.rulenode.parse-to-plain-text\' | translate }}\n \n
tb.rulenode.parse-to-plain-text-hint
\n \n {{ \'tb.rulenode.ignore-request-body\' | translate }}\n \n
\n \n {{ \'tb.rulenode.use-system-proxy-properties\' | translate }}\n \n
\n
\n \n tb.rulenode.proxy-scheme\n \n \n {{ proxyScheme }}\n \n \n \n \n tb.rulenode.proxy-host\n \n \n {{ \'tb.rulenode.proxy-host-required\' | translate }}\n \n \n \n tb.rulenode.proxy-port\n \n \n {{ \'tb.rulenode.proxy-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.proxy-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.proxy-user\n \n \n \n tb.rulenode.proxy-password\n \n \n
\n
\n \n tb.rulenode.read-timeout\n \n tb.rulenode.read-timeout-hint\n \n \n tb.rulenode.max-parallel-requests-count\n \n tb.rulenode.max-parallel-requests-count-hint\n \n \n
\n \n \n \n {{ \'tb.rulenode.use-redis-queue\' | translate }}\n \n
\n \n {{ \'tb.rulenode.trim-redis-queue\' | translate }}\n \n \n tb.rulenode.redis-queue-max-size\n \n \n
\n \n
\n',dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:J.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Vn,selector:"tb-credentials-config",inputs:["required","disableCertPemCredentials","passwordFieldRequired"]},{kind:"component",type:Fn,selector:"tb-kv-map-config-old",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:Ce.SafePipe,name:"safe"},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:dr,decorators:[{type:n,args:[{selector:"tb-external-node-rest-api-call-config",template:'
\n \n tb.rulenode.endpoint-url-pattern\n \n \n {{ \'tb.rulenode.endpoint-url-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.request-method\n \n \n {{ requestType }}\n \n \n \n \n {{ \'tb.rulenode.enable-proxy\' | translate }}\n \n \n {{ \'tb.rulenode.use-simple-client-http-factory\' | translate }}\n \n \n {{ \'tb.rulenode.parse-to-plain-text\' | translate }}\n \n
tb.rulenode.parse-to-plain-text-hint
\n \n {{ \'tb.rulenode.ignore-request-body\' | translate }}\n \n
\n \n {{ \'tb.rulenode.use-system-proxy-properties\' | translate }}\n \n
\n
\n \n tb.rulenode.proxy-scheme\n \n \n {{ proxyScheme }}\n \n \n \n \n tb.rulenode.proxy-host\n \n \n {{ \'tb.rulenode.proxy-host-required\' | translate }}\n \n \n \n tb.rulenode.proxy-port\n \n \n {{ \'tb.rulenode.proxy-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.proxy-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.proxy-user\n \n \n \n tb.rulenode.proxy-password\n \n \n
\n
\n \n tb.rulenode.read-timeout\n \n tb.rulenode.read-timeout-hint\n \n \n tb.rulenode.max-parallel-requests-count\n \n tb.rulenode.max-parallel-requests-count-hint\n \n \n
\n \n \n \n {{ \'tb.rulenode.use-redis-queue\' | translate }}\n \n
\n \n {{ \'tb.rulenode.trim-redis-queue\' | translate }}\n \n \n tb.rulenode.redis-queue-max-size\n \n \n
\n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class cr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.smtpProtocols=["smtp","smtps"],this.tlsVersions=["TLSv1","TLSv1.1","TLSv1.2","TLSv1.3"]}configForm(){return this.sendEmailConfigForm}onConfigurationSet(e){this.sendEmailConfigForm=this.fb.group({useSystemSmtpSettings:[!!e&&e.useSystemSmtpSettings,[]],smtpProtocol:[e?e.smtpProtocol:null,[]],smtpHost:[e?e.smtpHost:null,[]],smtpPort:[e?e.smtpPort:null,[]],timeout:[e?e.timeout:null,[]],enableTls:[!!e&&e.enableTls,[]],tlsVersion:[e?e.tlsVersion:null,[]],enableProxy:[!!e&&e.enableProxy,[]],proxyHost:[e?e.proxyHost:null,[]],proxyPort:[e?e.proxyPort:null,[]],proxyUser:[e?e.proxyUser:null,[]],proxyPassword:[e?e.proxyPassword:null,[]],username:[e?e.username:null,[]],password:[e?e.password:null,[]]})}validatorTriggers(){return["useSystemSmtpSettings","enableProxy"]}updateValidators(e){const t=this.sendEmailConfigForm.get("useSystemSmtpSettings").value,n=this.sendEmailConfigForm.get("enableProxy").value;t?(this.sendEmailConfigForm.get("smtpProtocol").setValidators([]),this.sendEmailConfigForm.get("smtpHost").setValidators([]),this.sendEmailConfigForm.get("smtpPort").setValidators([]),this.sendEmailConfigForm.get("timeout").setValidators([]),this.sendEmailConfigForm.get("proxyHost").setValidators([]),this.sendEmailConfigForm.get("proxyPort").setValidators([])):(this.sendEmailConfigForm.get("smtpProtocol").setValidators([_.required]),this.sendEmailConfigForm.get("smtpHost").setValidators([_.required]),this.sendEmailConfigForm.get("smtpPort").setValidators([_.required,_.min(1),_.max(65535)]),this.sendEmailConfigForm.get("timeout").setValidators([_.required,_.min(0)]),this.sendEmailConfigForm.get("proxyHost").setValidators(n?[_.required]:[]),this.sendEmailConfigForm.get("proxyPort").setValidators(n?[_.required,_.min(1),_.max(65535)]:[])),this.sendEmailConfigForm.get("smtpProtocol").updateValueAndValidity({emitEvent:e}),this.sendEmailConfigForm.get("smtpHost").updateValueAndValidity({emitEvent:e}),this.sendEmailConfigForm.get("smtpPort").updateValueAndValidity({emitEvent:e}),this.sendEmailConfigForm.get("timeout").updateValueAndValidity({emitEvent:e}),this.sendEmailConfigForm.get("proxyHost").updateValueAndValidity({emitEvent:e}),this.sendEmailConfigForm.get("proxyPort").updateValueAndValidity({emitEvent:e})}}e("SendEmailConfigComponent",cr),cr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:cr,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),cr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:cr,selector:"tb-external-node-send-email-config",usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.use-system-smtp-settings\' | translate }}\n \n
\n \n tb.rulenode.smtp-protocol\n \n \n {{ smtpProtocol.toUpperCase() }}\n \n \n \n
\n \n tb.rulenode.smtp-host\n \n \n {{ \'tb.rulenode.smtp-host-required\' | translate }}\n \n \n \n tb.rulenode.smtp-port\n \n \n {{ \'tb.rulenode.smtp-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.smtp-port-range\' | translate }}\n \n \n {{ \'tb.rulenode.smtp-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.timeout-msec\n \n \n {{ \'tb.rulenode.timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-timeout-msec-message\' | translate }}\n \n \n \n {{ \'tb.rulenode.enable-tls\' | translate }}\n \n \n tb.rulenode.tls-version\n \n \n {{ tlsVersion }}\n \n \n \n \n {{ \'tb.rulenode.enable-proxy\' | translate }}\n \n
\n
\n \n tb.rulenode.proxy-host\n \n \n {{ \'tb.rulenode.proxy-host-required\' | translate }}\n \n \n \n tb.rulenode.proxy-port\n \n \n {{ \'tb.rulenode.proxy-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.proxy-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.proxy-user\n \n \n \n tb.rulenode.proxy-password\n \n \n
\n \n tb.rulenode.username\n \n \n \n tb.rulenode.password\n \n \n \n
\n
\n',dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:at.TbCheckboxComponent,selector:"tb-checkbox",inputs:["disabled","trueValue","falseValue"],outputs:["valueChange"]},{kind:"component",type:J.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:W.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Xe.TogglePasswordComponent,selector:"tb-toggle-password"},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:cr,decorators:[{type:n,args:[{selector:"tb-external-node-send-email-config",template:'
\n \n {{ \'tb.rulenode.use-system-smtp-settings\' | translate }}\n \n
\n \n tb.rulenode.smtp-protocol\n \n \n {{ smtpProtocol.toUpperCase() }}\n \n \n \n
\n \n tb.rulenode.smtp-host\n \n \n {{ \'tb.rulenode.smtp-host-required\' | translate }}\n \n \n \n tb.rulenode.smtp-port\n \n \n {{ \'tb.rulenode.smtp-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.smtp-port-range\' | translate }}\n \n \n {{ \'tb.rulenode.smtp-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.timeout-msec\n \n \n {{ \'tb.rulenode.timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-timeout-msec-message\' | translate }}\n \n \n \n {{ \'tb.rulenode.enable-tls\' | translate }}\n \n \n tb.rulenode.tls-version\n \n \n {{ tlsVersion }}\n \n \n \n \n {{ \'tb.rulenode.enable-proxy\' | translate }}\n \n
\n
\n \n tb.rulenode.proxy-host\n \n \n {{ \'tb.rulenode.proxy-host-required\' | translate }}\n \n \n \n tb.rulenode.proxy-port\n \n \n {{ \'tb.rulenode.proxy-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.proxy-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.proxy-user\n \n \n \n tb.rulenode.proxy-password\n \n \n
\n \n tb.rulenode.username\n \n \n \n tb.rulenode.password\n \n \n \n
\n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class fr extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.sendSmsConfigForm}onConfigurationSet(e){this.sendSmsConfigForm=this.fb.group({numbersToTemplate:[e?e.numbersToTemplate:null,[_.required]],smsMessageTemplate:[e?e.smsMessageTemplate:null,[_.required]],useSystemSmsSettings:[!!e&&e.useSystemSmsSettings,[]],smsProviderConfiguration:[e?e.smsProviderConfiguration:null,[]]})}validatorTriggers(){return["useSystemSmsSettings"]}updateValidators(e){this.sendSmsConfigForm.get("useSystemSmsSettings").value?this.sendSmsConfigForm.get("smsProviderConfiguration").setValidators([]):this.sendSmsConfigForm.get("smsProviderConfiguration").setValidators([_.required]),this.sendSmsConfigForm.get("smsProviderConfiguration").updateValueAndValidity({emitEvent:e})}}e("SendSmsConfigComponent",fr),fr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:fr,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),fr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:fr,selector:"tb-external-node-send-sms-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.numbers-to-template\n \n \n {{ \'tb.rulenode.numbers-to-template-required\' | translate }}\n \n \n \n \n tb.rulenode.sms-message-template\n \n \n {{ \'tb.rulenode.sms-message-template-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n {{ \'tb.rulenode.use-system-sms-settings\' | translate }}\n \n \n \n
\n',dependencies:[{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:J.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:it.SmsProviderConfigurationComponent,selector:"tb-sms-provider-configuration",inputs:["required","disabled"]},{kind:"pipe",type:Ce.SafePipe,name:"safe"},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:fr,decorators:[{type:n,args:[{selector:"tb-external-node-send-sms-config",template:'
\n \n tb.rulenode.numbers-to-template\n \n \n {{ \'tb.rulenode.numbers-to-template-required\' | translate }}\n \n \n \n \n tb.rulenode.sms-message-template\n \n \n {{ \'tb.rulenode.sms-message-template-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n {{ \'tb.rulenode.use-system-sms-settings\' | translate }}\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class gr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.slackChanelTypes=Object.keys(w),this.slackChanelTypesTranslateMap=P}configForm(){return this.slackConfigForm}onConfigurationSet(e){this.slackConfigForm=this.fb.group({botToken:[e?e.botToken:null],useSystemSettings:[!!e&&e.useSystemSettings],messageTemplate:[e?e.messageTemplate:null,[_.required]],conversationType:[e?e.conversationType:null,[_.required]],conversation:[e?e.conversation:null,[_.required]]})}validatorTriggers(){return["useSystemSettings"]}updateValidators(e){this.slackConfigForm.get("useSystemSettings").value?this.slackConfigForm.get("botToken").clearValidators():this.slackConfigForm.get("botToken").setValidators([_.required]),this.slackConfigForm.get("botToken").updateValueAndValidity({emitEvent:e})}}e("SlackConfigComponent",gr),gr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:gr,deps:[{token:R.Store},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),gr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:gr,selector:"tb-external-node-slack-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.message-template\n \n \n {{ \'tb.rulenode.message-template-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n {{ \'tb.rulenode.use-system-slack-settings\' | translate }}\n \n \n tb.rulenode.slack-api-token\n \n \n {{ \'tb.rulenode.slack-api-token-required\' | translate }}\n \n \n \n \n \n {{ slackChanelTypesTranslateMap.get(slackChanelType) | translate }}\n \n \n \n \n
\n',styles:[":host .tb-title{display:block;padding-bottom:6px}:host ::ng-deep .mat-mdc-radio-group{display:flex;flex-direction:row;margin-bottom:22px;gap:12px}:host ::ng-deep .mat-mdc-radio-group .mat-mdc-radio-button{flex:1 1 100%;padding:4px;border:1px solid rgba(0,0,0,.12);border-radius:6px}@media screen and (max-width: 599px){:host ::ng-deep .mat-mdc-radio-group{flex-direction:column}}\n"],dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:J.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:lt.MatRadioGroup,selector:"mat-radio-group",exportAs:["matRadioGroup"]},{kind:"component",type:lt.MatRadioButton,selector:"mat-radio-button",inputs:["disableRipple","tabIndex"],exportAs:["matRadioButton"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:st.SlackConversationAutocompleteComponent,selector:"tb-slack-conversation-autocomplete",inputs:["labelText","requiredText","required","disabled","slackChanelType","token"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:gr,decorators:[{type:n,args:[{selector:"tb-external-node-slack-config",template:'
\n \n tb.rulenode.message-template\n \n \n {{ \'tb.rulenode.message-template-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n {{ \'tb.rulenode.use-system-slack-settings\' | translate }}\n \n \n tb.rulenode.slack-api-token\n \n \n {{ \'tb.rulenode.slack-api-token-required\' | translate }}\n \n \n \n \n \n {{ slackChanelTypesTranslateMap.get(slackChanelType) | translate }}\n \n \n \n \n
\n',styles:[":host .tb-title{display:block;padding-bottom:6px}:host ::ng-deep .mat-mdc-radio-group{display:flex;flex-direction:row;margin-bottom:22px;gap:12px}:host ::ng-deep .mat-mdc-radio-group .mat-mdc-radio-button{flex:1 1 100%;padding:4px;border:1px solid rgba(0,0,0,.12);border-radius:6px}@media screen and (max-width: 599px){:host ::ng-deep .mat-mdc-radio-group{flex-direction:column}}\n"]}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder}]}});class yr extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.snsConfigForm}onConfigurationSet(e){this.snsConfigForm=this.fb.group({topicArnPattern:[e?e.topicArnPattern:null,[_.required]],accessKeyId:[e?e.accessKeyId:null,[_.required]],secretAccessKey:[e?e.secretAccessKey:null,[_.required]],region:[e?e.region:null,[_.required]]})}}e("SnsConfigComponent",yr),yr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:yr,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),yr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:yr,selector:"tb-external-node-sns-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.topic-arn-pattern\n \n \n {{ \'tb.rulenode.topic-arn-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.aws-access-key-id\n \n \n {{ \'tb.rulenode.aws-access-key-id-required\' | translate }}\n \n \n \n tb.rulenode.aws-secret-access-key\n \n \n {{ \'tb.rulenode.aws-secret-access-key-required\' | translate }}\n \n \n \n tb.rulenode.aws-region\n \n \n {{ \'tb.rulenode.aws-region-required\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:yr,decorators:[{type:n,args:[{selector:"tb-external-node-sns-config",template:'
\n \n tb.rulenode.topic-arn-pattern\n \n \n {{ \'tb.rulenode.topic-arn-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.aws-access-key-id\n \n \n {{ \'tb.rulenode.aws-access-key-id-required\' | translate }}\n \n \n \n tb.rulenode.aws-secret-access-key\n \n \n {{ \'tb.rulenode.aws-secret-access-key-required\' | translate }}\n \n \n \n tb.rulenode.aws-region\n \n \n {{ \'tb.rulenode.aws-region-required\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class xr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.sqsQueueType=Ut,this.sqsQueueTypes=Object.keys(Ut),this.sqsQueueTypeTranslationsMap=Ht}configForm(){return this.sqsConfigForm}onConfigurationSet(e){this.sqsConfigForm=this.fb.group({queueType:[e?e.queueType:null,[_.required]],queueUrlPattern:[e?e.queueUrlPattern:null,[_.required]],delaySeconds:[e?e.delaySeconds:null,[_.min(0),_.max(900)]],messageAttributes:[e?e.messageAttributes:null,[]],accessKeyId:[e?e.accessKeyId:null,[_.required]],secretAccessKey:[e?e.secretAccessKey:null,[_.required]],region:[e?e.region:null,[_.required]]})}}e("SqsConfigComponent",xr),xr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:xr,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),xr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:xr,selector:"tb-external-node-sqs-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.queue-type\n \n \n {{ sqsQueueTypeTranslationsMap.get(type) | translate }}\n \n \n \n \n tb.rulenode.queue-url-pattern\n \n \n {{ \'tb.rulenode.queue-url-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.delay-seconds\n \n \n {{ \'tb.rulenode.min-delay-seconds-message\' | translate }}\n \n \n {{ \'tb.rulenode.max-delay-seconds-message\' | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.aws-access-key-id\n \n \n {{ \'tb.rulenode.aws-access-key-id-required\' | translate }}\n \n \n \n tb.rulenode.aws-secret-access-key\n \n \n {{ \'tb.rulenode.aws-secret-access-key-required\' | translate }}\n \n \n \n tb.rulenode.aws-region\n \n \n {{ \'tb.rulenode.aws-region-required\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Fn,selector:"tb-kv-map-config-old",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:Ce.SafePipe,name:"safe"},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:xr,decorators:[{type:n,args:[{selector:"tb-external-node-sqs-config",template:'
\n \n tb.rulenode.queue-type\n \n \n {{ sqsQueueTypeTranslationsMap.get(type) | translate }}\n \n \n \n \n tb.rulenode.queue-url-pattern\n \n \n {{ \'tb.rulenode.queue-url-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.delay-seconds\n \n \n {{ \'tb.rulenode.min-delay-seconds-message\' | translate }}\n \n \n {{ \'tb.rulenode.max-delay-seconds-message\' | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.aws-access-key-id\n \n \n {{ \'tb.rulenode.aws-access-key-id-required\' | translate }}\n \n \n \n tb.rulenode.aws-secret-access-key\n \n \n {{ \'tb.rulenode.aws-secret-access-key-required\' | translate }}\n \n \n \n tb.rulenode.aws-region\n \n \n {{ \'tb.rulenode.aws-region-required\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class br{}e("RulenodeCoreConfigExternalModule",br),br.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:br,deps:[],target:t.ɵɵFactoryTarget.NgModule}),br.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.10",ngImport:t,type:br,declarations:[yr,xr,pr,lr,sr,mr,ur,dr,cr,ir,fr,gr],imports:[Q,E,_e,$n],exports:[yr,xr,pr,lr,sr,mr,ur,dr,cr,ir,fr,gr]}),br.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:br,imports:[Q,E,_e,$n]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:br,decorators:[{type:c,args:[{declarations:[yr,xr,pr,lr,sr,mr,ur,dr,cr,ir,fr,gr],imports:[Q,E,_e,$n],exports:[yr,xr,pr,lr,sr,mr,ur,dr,cr,ir,fr,gr]}]}]});class hr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.searchText=""}configForm(){return this.alarmStatusConfigForm}prepareInputConfig(e){return{alarmStatusList:se(e?.alarmStatusList)?e.alarmStatusList:null}}onConfigurationSet(e){this.alarmStatusConfigForm=this.fb.group({alarmStatusList:[e.alarmStatusList,[_.required]]})}}e("CheckAlarmStatusComponent",hr),hr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:hr,deps:[{token:R.Store},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),hr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:hr,selector:"tb-filter-node-check-alarm-status-config",usesInheritance:!0,ngImport:t,template:'
\n
\n
tb.rulenode.alarm-status
\n
\n tb.rulenode.alarm-required\n
\n
\n \n
\n\n\n\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:jn,selector:"tb-alarm-status-select"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:hr,decorators:[{type:n,args:[{selector:"tb-filter-node-check-alarm-status-config",template:'
\n
\n
tb.rulenode.alarm-status
\n
\n tb.rulenode.alarm-required\n
\n
\n \n
\n\n\n\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder}]}});class vr extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.checkMessageConfigForm}prepareInputConfig(e){return{messageNames:se(e?.messageNames)?e.messageNames:[],metadataNames:se(e?.metadataNames)?e.metadataNames:[],checkAllKeys:!!se(e?.checkAllKeys)&&e.checkAllKeys}}prepareOutputConfig(e){return{messageNames:se(e?.messageNames)?e.messageNames:[],metadataNames:se(e?.metadataNames)?e.metadataNames:[],checkAllKeys:e.checkAllKeys}}atLeastOne(e,t=null){return n=>{t||(t=Object.keys(n.controls));return n?.controls&&t.some((t=>!e(n.controls[t])))?null:{atLeastOne:!0}}}onConfigurationSet(e){this.checkMessageConfigForm=this.fb.group({messageNames:[e.messageNames,[]],metadataNames:[e.metadataNames,[]],checkAllKeys:[e.checkAllKeys,[]]},{validators:this.atLeastOne(_.required,["messageNames","metadataNames"])})}get touchedValidationControl(){return["messageNames","metadataNames"].some((e=>this.checkMessageConfigForm.get(e).touched))}}e("CheckMessageConfigComponent",vr),vr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:vr,deps:[{token:R.Store},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),vr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:vr,selector:"tb-filter-node-check-message-config",usesInheritance:!0,ngImport:t,template:'
\n
\n
tb.rulenode.fields-to-check
\n
\n tb.rulenode.at-least-one-field-required\n
\n
\n \n help\n \n \n help\n \n
\n \n {{ \'tb.rulenode.check-all-keys\' | translate }}\n \n
\n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"component",type:et.StringItemsListComponent,selector:"tb-string-items-list",inputs:["required","disabled","label","placeholder","hint","requiredText","floatLabel","appearance","editable","subscriptSizing","predefinedValues"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:W.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:ne.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:re.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:vr,decorators:[{type:n,args:[{selector:"tb-filter-node-check-message-config",template:'
\n
\n
tb.rulenode.fields-to-check
\n
\n tb.rulenode.at-least-one-field-required\n
\n
\n \n help\n \n \n help\n \n
\n \n {{ \'tb.rulenode.check-all-keys\' | translate }}\n \n
\n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder}]}});class Cr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.entitySearchDirection=Object.values(C),this.entitySearchDirectionTranslationsMap=F}configForm(){return this.checkRelationConfigForm}prepareInputConfig(e){return{checkForSingleEntity:!!se(e?.checkForSingleEntity)&&e.checkForSingleEntity,direction:se(e?.direction)?e.direction:null,entityType:se(e?.entityType)?e.entityType:null,entityId:se(e?.entityId)?e.entityId:null,relationType:se(e?.relationType)?e.relationType:null}}onConfigurationSet(e){this.checkRelationConfigForm=this.fb.group({checkForSingleEntity:[e.checkForSingleEntity,[]],direction:[e.direction,[]],entityType:[e.entityType,e&&e.checkForSingleEntity?[_.required]:[]],entityId:[e.entityId,e&&e.checkForSingleEntity?[_.required]:[]],relationType:[e.relationType,[_.required]]})}validatorTriggers(){return["checkForSingleEntity"]}updateValidators(e){const t=this.checkRelationConfigForm.get("checkForSingleEntity").value;this.checkRelationConfigForm.get("entityType").setValidators(t?[_.required]:[]),this.checkRelationConfigForm.get("entityType").updateValueAndValidity({emitEvent:e}),this.checkRelationConfigForm.get("entityId").setValidators(t?[_.required]:[]),this.checkRelationConfigForm.get("entityId").updateValueAndValidity({emitEvent:e})}}e("CheckRelationConfigComponent",Cr),Cr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Cr,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Cr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Cr,selector:"tb-filter-node-check-relation-config",usesInheritance:!0,ngImport:t,template:'
\n
tb.rulenode.relation-search-parameters
\n
\n \n {{ \'relation.direction\' | translate }}\n \n \n {{ entitySearchDirectionTranslationsMap.get(direction) | translate }} tb.rulenode.relations-query-config-direction-suffix\n \n \n \n \n \n
\n \n {{ \'tb.rulenode.check-relation-to-specific-entity\' | translate }}\n \n
\n
\n \n \n \n \n
\n
\n
\n',styles:[":host .slide-toggle{margin-bottom:18px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:mt.EntityAutocompleteComponent,selector:"tb-entity-autocomplete",inputs:["entityType","entitySubtype","excludeEntityIds","labelText","requiredText","useFullEntityId","appearance","required","disabled"],outputs:["entityChanged"]},{kind:"component",type:Fe.EntityTypeSelectComponent,selector:"tb-entity-type-select",inputs:["allowedEntityTypes","useAliasEntityTypes","filterAllowedEntityTypes","showLabel","required","disabled"]},{kind:"component",type:Je.RelationTypeAutocompleteComponent,selector:"tb-relation-type-autocomplete",inputs:["showLabel","additionalClasses","appearance","required","disabled","subscriptSizing"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:ne.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:re.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Cr,decorators:[{type:n,args:[{selector:"tb-filter-node-check-relation-config",template:'
\n
tb.rulenode.relation-search-parameters
\n
\n \n {{ \'relation.direction\' | translate }}\n \n \n {{ entitySearchDirectionTranslationsMap.get(direction) | translate }} tb.rulenode.relations-query-config-direction-suffix\n \n \n \n \n \n
\n \n {{ \'tb.rulenode.check-relation-to-specific-entity\' | translate }}\n \n
\n
\n \n \n \n \n
\n
\n
\n',styles:[":host .slide-toggle{margin-bottom:18px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class Fr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.perimeterType=St,this.perimeterTypes=Object.values(St),this.perimeterTypeTranslationMap=qt,this.rangeUnits=Object.values(Et),this.rangeUnitTranslationMap=Gt,this.defaultPaddingEnable=!0}configForm(){return this.geoFilterConfigForm}prepareInputConfig(e){return{latitudeKeyName:se(e?.latitudeKeyName)?e.latitudeKeyName:null,longitudeKeyName:se(e?.longitudeKeyName)?e.longitudeKeyName:null,perimeterType:se(e?.perimeterType)?e.perimeterType:null,fetchPerimeterInfoFromMessageMetadata:!!se(e?.fetchPerimeterInfoFromMessageMetadata)&&e.fetchPerimeterInfoFromMessageMetadata,perimeterKeyName:se(e?.perimeterKeyName)?e.perimeterKeyName:null,centerLatitude:se(e?.centerLatitude)?e.centerLatitude:null,centerLongitude:se(e?.centerLongitude)?e.centerLongitude:null,range:se(e?.range)?e.range:null,rangeUnit:se(e?.rangeUnit)?e.rangeUnit:null,polygonsDefinition:se(e?.polygonsDefinition)?e.polygonsDefinition:null}}onConfigurationSet(e){this.geoFilterConfigForm=this.fb.group({latitudeKeyName:[e.latitudeKeyName,[_.required]],longitudeKeyName:[e.longitudeKeyName,[_.required]],perimeterType:[e.perimeterType,[_.required]],fetchPerimeterInfoFromMessageMetadata:[e.fetchPerimeterInfoFromMessageMetadata,[]],perimeterKeyName:[e.perimeterKeyName,[]],centerLatitude:[e.centerLatitude,[]],centerLongitude:[e.centerLongitude,[]],range:[e.range,[]],rangeUnit:[e.rangeUnit,[]],polygonsDefinition:[e.polygonsDefinition,[]]})}validatorTriggers(){return["fetchPerimeterInfoFromMessageMetadata","perimeterType"]}updateValidators(e){const t=this.geoFilterConfigForm.get("fetchPerimeterInfoFromMessageMetadata").value,n=this.geoFilterConfigForm.get("perimeterType").value;t?this.geoFilterConfigForm.get("perimeterKeyName").setValidators([_.required]):this.geoFilterConfigForm.get("perimeterKeyName").setValidators([]),t||n!==St.CIRCLE?(this.geoFilterConfigForm.get("centerLatitude").setValidators([]),this.geoFilterConfigForm.get("centerLongitude").setValidators([]),this.geoFilterConfigForm.get("range").setValidators([]),this.geoFilterConfigForm.get("rangeUnit").setValidators([]),this.defaultPaddingEnable=!0):(this.geoFilterConfigForm.get("centerLatitude").setValidators([_.required,_.min(-90),_.max(90)]),this.geoFilterConfigForm.get("centerLongitude").setValidators([_.required,_.min(-180),_.max(180)]),this.geoFilterConfigForm.get("range").setValidators([_.required,_.min(0)]),this.geoFilterConfigForm.get("rangeUnit").setValidators([_.required]),this.defaultPaddingEnable=!1),t||n!==St.POLYGON?this.geoFilterConfigForm.get("polygonsDefinition").setValidators([]):this.geoFilterConfigForm.get("polygonsDefinition").setValidators([_.required]),this.geoFilterConfigForm.get("perimeterKeyName").updateValueAndValidity({emitEvent:e}),this.geoFilterConfigForm.get("centerLatitude").updateValueAndValidity({emitEvent:e}),this.geoFilterConfigForm.get("centerLongitude").updateValueAndValidity({emitEvent:e}),this.geoFilterConfigForm.get("range").updateValueAndValidity({emitEvent:e}),this.geoFilterConfigForm.get("rangeUnit").updateValueAndValidity({emitEvent:e}),this.geoFilterConfigForm.get("polygonsDefinition").updateValueAndValidity({emitEvent:e})}}e("GpsGeoFilterConfigComponent",Fr),Fr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Fr,deps:[{token:R.Store},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Fr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Fr,selector:"tb-filter-node-gps-geofencing-config",usesInheritance:!0,ngImport:t,template:'
\n
\n
tb.rulenode.coordinate-field-names
\n
\n
\n \n {{ \'tb.rulenode.latitude-field-name\' | translate }}\n \n \n {{ \'tb.rulenode.latitude-field-name-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.longitude-field-name\' | translate }}\n \n \n {{ \'tb.rulenode.longitude-field-name-required\' | translate }}\n \n \n
\n
tb.rulenode.coordinate-field-hint
\n
\n
\n
\n
tb.rulenode.geofence-configuration
\n
\n \n {{ \'tb.rulenode.perimeter-type\' | translate }}\n \n \n {{ perimeterTypeTranslationMap.get(type) | translate }}\n \n \n \n
\n \n {{ \'tb.rulenode.fetch-perimeter-info-from-metadata\' | translate }}\n \n
\n \n {{ \'tb.rulenode.perimeter-key-name\' | translate }}\n \n \n {{ \'tb.rulenode.perimeter-key-name-required\' | translate }}\n \n {{ \'tb.rulenode.perimeter-key-name-hint\' | translate }}\n \n
\n
\n \n {{ \'tb.rulenode.circle-center-latitude\' | translate }}\n \n \n {{ \'tb.rulenode.circle-center-latitude-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.circle-center-longitude\' | translate }}\n \n \n {{ \'tb.rulenode.circle-center-longitude-required\' | translate }}\n \n \n
\n
\n \n {{ \'tb.rulenode.range\' | translate }}\n \n \n {{ \'tb.rulenode.range-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.range-units\' | translate }}\n \n \n {{ rangeUnitTranslationMap.get(type) | translate }}\n \n \n \n {{ \'tb.rulenode.range-units-required\' | translate }}\n \n \n
\n
\n \n {{ \'tb.rulenode.polygon-definition\' | translate }}\n \n {{ \'tb.rulenode.polygon-definition-hint\' | translate }}\n \n {{ \'tb.rulenode.polygon-definition-required\' | translate }}\n \n \n
\n
\n
\n',styles:[":host .slide-toggle{margin-bottom:18px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:ne.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:Z.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:O.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:re.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Fr,decorators:[{type:n,args:[{selector:"tb-filter-node-gps-geofencing-config",template:'
\n
\n
tb.rulenode.coordinate-field-names
\n
\n
\n \n {{ \'tb.rulenode.latitude-field-name\' | translate }}\n \n \n {{ \'tb.rulenode.latitude-field-name-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.longitude-field-name\' | translate }}\n \n \n {{ \'tb.rulenode.longitude-field-name-required\' | translate }}\n \n \n
\n
tb.rulenode.coordinate-field-hint
\n
\n
\n
\n
tb.rulenode.geofence-configuration
\n
\n \n {{ \'tb.rulenode.perimeter-type\' | translate }}\n \n \n {{ perimeterTypeTranslationMap.get(type) | translate }}\n \n \n \n
\n \n {{ \'tb.rulenode.fetch-perimeter-info-from-metadata\' | translate }}\n \n
\n \n {{ \'tb.rulenode.perimeter-key-name\' | translate }}\n \n \n {{ \'tb.rulenode.perimeter-key-name-required\' | translate }}\n \n {{ \'tb.rulenode.perimeter-key-name-hint\' | translate }}\n \n
\n
\n \n {{ \'tb.rulenode.circle-center-latitude\' | translate }}\n \n \n {{ \'tb.rulenode.circle-center-latitude-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.circle-center-longitude\' | translate }}\n \n \n {{ \'tb.rulenode.circle-center-longitude-required\' | translate }}\n \n \n
\n
\n \n {{ \'tb.rulenode.range\' | translate }}\n \n \n {{ \'tb.rulenode.range-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.range-units\' | translate }}\n \n \n {{ rangeUnitTranslationMap.get(type) | translate }}\n \n \n \n {{ \'tb.rulenode.range-units-required\' | translate }}\n \n \n
\n
\n \n {{ \'tb.rulenode.polygon-definition\' | translate }}\n \n {{ \'tb.rulenode.polygon-definition-hint\' | translate }}\n \n {{ \'tb.rulenode.polygon-definition-required\' | translate }}\n \n \n
\n
\n
\n',styles:[":host .slide-toggle{margin-bottom:18px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder}]}});class kr extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.messageTypeConfigForm}prepareInputConfig(e){return{messageTypes:se(e?.messageTypes)?e.messageTypes:null}}onConfigurationSet(e){this.messageTypeConfigForm=this.fb.group({messageTypes:[e.messageTypes,[_.required]]})}}e("MessageTypeConfigComponent",kr),kr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:kr,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),kr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:kr,selector:"tb-filter-node-message-type-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n
\n',dependencies:[{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:Dn,selector:"tb-message-types-config",inputs:["required","label","placeholder","disabled"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:kr,decorators:[{type:n,args:[{selector:"tb-filter-node-message-type-config",template:'
\n \n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class Lr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.allowedEntityTypes=[k.DEVICE,k.ASSET,k.ENTITY_VIEW,k.TENANT,k.CUSTOMER,k.USER,k.DASHBOARD,k.RULE_CHAIN,k.RULE_NODE]}configForm(){return this.originatorTypeConfigForm}prepareInputConfig(e){return{originatorTypes:se(e?.originatorTypes)?e.originatorTypes:null}}onConfigurationSet(e){this.originatorTypeConfigForm=this.fb.group({originatorTypes:[e.originatorTypes,[_.required]]})}}e("OriginatorTypeConfigComponent",Lr),Lr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Lr,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Lr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Lr,selector:"tb-filter-node-originator-type-config",usesInheritance:!0,ngImport:t,template:'
\n \n help\n \n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"component",type:pt.EntityTypeListComponent,selector:"tb-entity-type-list",inputs:["required","additionalClasses","appearance","label","floatLabel","disabled","subscriptSizing","allowedEntityTypes","emptyInputPlaceholder","filledInputPlaceholder","ignoreAuthorityFilter"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:W.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:Z.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Lr,decorators:[{type:n,args:[{selector:"tb-filter-node-originator-type-config",template:'
\n \n help\n \n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class Tr extends f{constructor(e,t,n,o){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=n,this.translate=o,this.tbelEnabled=ae(this.store).tbelEnabled,this.scriptLanguage=b,this.changeScript=new r,this.hasScript=!0,this.testScriptLabel="tb.rulenode.test-filter-function"}configForm(){return this.scriptConfigForm}onConfigurationSet(e){this.scriptConfigForm=this.fb.group({scriptLang:[e.scriptLang,[_.required]],jsScript:[e.jsScript,[]],tbelScript:[e.tbelScript,[]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.scriptConfigForm.get("scriptLang").value;t!==b.TBEL||this.tbelEnabled||(t=b.JS,this.scriptConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.scriptConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.scriptConfigForm.get("jsScript").setValidators(t===b.JS?[_.required]:[]),this.scriptConfigForm.get("jsScript").updateValueAndValidity({emitEvent:e}),this.scriptConfigForm.get("tbelScript").setValidators(t===b.TBEL?[_.required]:[]),this.scriptConfigForm.get("tbelScript").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=b.JS)),{scriptLang:se(e?.scriptLang)?e.scriptLang:b.JS,jsScript:se(e?.jsScript)?e.jsScript:null,tbelScript:se(e?.tbelScript)?e.tbelScript:null}}testScript(e){const t=this.scriptConfigForm.get("scriptLang").value,n=t===b.JS?"jsScript":"tbelScript",r=t===b.JS?"rulenode/filter_node_script_fn":"rulenode/tbel/filter_node_script_fn",o=this.scriptConfigForm.get(n).value;this.nodeScriptTestService.testNodeScript(o,"filter",this.translate.instant("tb.rulenode.filter"),"Filter",["msg","metadata","msgType"],this.ruleNodeId,r,t,e).subscribe((e=>{e&&(this.scriptConfigForm.get(n).setValue(e),this.changeScript.emit())}))}onValidate(){this.scriptConfigForm.get("scriptLang").value===b.JS&&this.jsFuncComponent.validateOnSubmit()}}e("ScriptConfigComponent",Tr),Tr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Tr,deps:[{token:R.Store},{token:O.UntypedFormBuilder},{token:ie.NodeScriptTestService},{token:X.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Tr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Tr,selector:"tb-filter-node-script-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n \n \n \n
\n',dependencies:[{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:de.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:ce.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ce.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:ye.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Tr,decorators:[{type:n,args:[{selector:"tb-filter-node-script-config",template:'
\n \n \n \n \n \n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder},{type:ie.NodeScriptTestService},{type:X.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}});class Ir extends f{constructor(e,t,n,o){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=n,this.translate=o,this.tbelEnabled=ae(this.store).tbelEnabled,this.scriptLanguage=b,this.changeScript=new r,this.hasScript=!0,this.testScriptLabel="tb.rulenode.test-switch-function"}configForm(){return this.switchConfigForm}onConfigurationSet(e){this.switchConfigForm=this.fb.group({scriptLang:[e.scriptLang,[_.required]],jsScript:[e.jsScript,[]],tbelScript:[e.tbelScript,[]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.switchConfigForm.get("scriptLang").value;t!==b.TBEL||this.tbelEnabled||(t=b.JS,this.switchConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.switchConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.switchConfigForm.get("jsScript").setValidators(t===b.JS?[_.required]:[]),this.switchConfigForm.get("jsScript").updateValueAndValidity({emitEvent:e}),this.switchConfigForm.get("tbelScript").setValidators(t===b.TBEL?[_.required]:[]),this.switchConfigForm.get("tbelScript").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=b.JS)),{scriptLang:se(e?.scriptLang)?e.scriptLang:b.JS,jsScript:se(e?.jsScript)?e.jsScript:null,tbelScript:se(e?.tbelScript)?e.tbelScript:null}}testScript(e){const t=this.switchConfigForm.get("scriptLang").value,n=t===b.JS?"jsScript":"tbelScript",r=t===b.JS?"rulenode/switch_node_script_fn":"rulenode/tbel/switch_node_script_fn",o=this.switchConfigForm.get(n).value;this.nodeScriptTestService.testNodeScript(o,"switch",this.translate.instant("tb.rulenode.switch"),"Switch",["msg","metadata","msgType"],this.ruleNodeId,r,t,e).subscribe((e=>{e&&(this.switchConfigForm.get(n).setValue(e),this.changeScript.emit())}))}onValidate(){this.switchConfigForm.get("scriptLang").value===b.JS&&this.jsFuncComponent.validateOnSubmit()}}e("SwitchConfigComponent",Ir),Ir.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Ir,deps:[{token:R.Store},{token:O.UntypedFormBuilder},{token:ie.NodeScriptTestService},{token:X.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Ir.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Ir,selector:"tb-filter-node-switch-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n \n \n \n
\n',dependencies:[{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:de.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:ce.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ce.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:ye.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Ir,decorators:[{type:n,args:[{selector:"tb-filter-node-switch-config",template:'
\n \n \n \n \n \n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder},{type:ie.NodeScriptTestService},{type:X.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}});class Nr{}e("RuleNodeCoreConfigFilterModule",Nr),Nr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Nr,deps:[],target:t.ɵɵFactoryTarget.NgModule}),Nr.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.10",ngImport:t,type:Nr,declarations:[vr,Cr,Fr,kr,Lr,Tr,Ir,hr],imports:[Q,E,$n],exports:[vr,Cr,Fr,kr,Lr,Tr,Ir,hr]}),Nr.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Nr,imports:[Q,E,$n]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Nr,decorators:[{type:c,args:[{declarations:[vr,Cr,Fr,kr,Lr,Tr,Ir,hr],imports:[Q,E,$n],exports:[vr,Cr,Fr,kr,Lr,Tr,Ir,hr]}]}]});class Sr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.originatorSource=kt,this.originatorSources=Object.keys(kt),this.originatorSourceTranslationMap=Lt,this.originatorSourceDescTranslationMap=Tt,this.allowedEntityTypes=[k.DEVICE,k.ASSET,k.ENTITY_VIEW,k.USER,k.EDGE]}configForm(){return this.changeOriginatorConfigForm}onConfigurationSet(e){this.changeOriginatorConfigForm=this.fb.group({originatorSource:[e?e.originatorSource:null,[_.required]],entityType:[e?e.entityType:null,[]],entityNamePattern:[e?e.entityNamePattern:null,[]],relationsQuery:[e?e.relationsQuery:null,[]]})}validatorTriggers(){return["originatorSource"]}updateValidators(e){const t=this.changeOriginatorConfigForm.get("originatorSource").value;t===kt.RELATED?this.changeOriginatorConfigForm.get("relationsQuery").setValidators([_.required]):this.changeOriginatorConfigForm.get("relationsQuery").setValidators([]),t===kt.ENTITY?(this.changeOriginatorConfigForm.get("entityType").setValidators([_.required]),this.changeOriginatorConfigForm.get("entityNamePattern").setValidators([_.required,_.pattern(/.*\S.*/)])):(this.changeOriginatorConfigForm.get("entityType").patchValue(null,{emitEvent:e}),this.changeOriginatorConfigForm.get("entityNamePattern").patchValue(null,{emitEvent:e}),this.changeOriginatorConfigForm.get("entityType").setValidators([]),this.changeOriginatorConfigForm.get("entityNamePattern").setValidators([])),this.changeOriginatorConfigForm.get("relationsQuery").updateValueAndValidity({emitEvent:e}),this.changeOriginatorConfigForm.get("entityType").updateValueAndValidity({emitEvent:e}),this.changeOriginatorConfigForm.get("entityNamePattern").updateValueAndValidity({emitEvent:e})}}e("ChangeOriginatorConfigComponent",Sr),Sr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Sr,deps:[{token:R.Store},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Sr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Sr,selector:"tb-transformation-node-change-originator-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.new-originator\n \n \n \n {{ originatorSourceTranslationMap.get(changeOriginatorConfigForm.get(\'originatorSource\').value) | translate }}\n \n \n \n \n {{ originatorSourceTranslationMap.get(source) | translate }}\n \n
\n \n {{ originatorSourceDescTranslationMap.get(source) | translate }}\n \n
\n
\n
\n
\n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n \n
\n
\n \n \n
\n',dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Fe.EntityTypeSelectComponent,selector:"tb-entity-type-select",inputs:["allowedEntityTypes","useAliasEntityTypes","filterAllowedEntityTypes","showLabel","required","disabled"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"directive",type:ee.MatSelectTrigger,selector:"mat-select-trigger"},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:qe.MatListItemTitle,selector:"[matListItemTitle]"},{kind:"directive",type:qe.MatListItemMeta,selector:"[matListItemMeta]"},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Gn,selector:"tb-relations-query-config",inputs:["disabled","required"]},{kind:"component",type:An,selector:"tb-example-hint",inputs:["hintText","popupHelpLink","textAlign"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Sr,decorators:[{type:n,args:[{selector:"tb-transformation-node-change-originator-config",template:'
\n \n tb.rulenode.new-originator\n \n \n \n {{ originatorSourceTranslationMap.get(changeOriginatorConfigForm.get(\'originatorSource\').value) | translate }}\n \n \n \n \n {{ originatorSourceTranslationMap.get(source) | translate }}\n \n
\n \n {{ originatorSourceDescTranslationMap.get(source) | translate }}\n \n
\n
\n
\n
\n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n \n
\n
\n \n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder}]}});class qr extends f{constructor(e,t,n,o){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=n,this.translate=o,this.tbelEnabled=ae(this.store).tbelEnabled,this.scriptLanguage=b,this.changeScript=new r,this.hasScript=!0,this.testScriptLabel="tb.rulenode.test-transformer-function"}configForm(){return this.scriptConfigForm}onConfigurationSet(e){this.scriptConfigForm=this.fb.group({scriptLang:[e?e.scriptLang:b.JS,[_.required]],jsScript:[e?e.jsScript:null,[_.required]],tbelScript:[e?e.tbelScript:null,[]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.scriptConfigForm.get("scriptLang").value;t!==b.TBEL||this.tbelEnabled||(t=b.JS,this.scriptConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.scriptConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.scriptConfigForm.get("jsScript").setValidators(t===b.JS?[_.required]:[]),this.scriptConfigForm.get("jsScript").updateValueAndValidity({emitEvent:e}),this.scriptConfigForm.get("tbelScript").setValidators(t===b.TBEL?[_.required]:[]),this.scriptConfigForm.get("tbelScript").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=b.JS)),e}testScript(e){const t=this.scriptConfigForm.get("scriptLang").value,n=t===b.JS?"jsScript":"tbelScript",r=t===b.JS?"rulenode/transformation_node_script_fn":"rulenode/tbel/transformation_node_script_fn",o=this.scriptConfigForm.get(n).value;this.nodeScriptTestService.testNodeScript(o,"update",this.translate.instant("tb.rulenode.transformer"),"Transform",["msg","metadata","msgType"],this.ruleNodeId,r,t,e).subscribe((e=>{e&&(this.scriptConfigForm.get(n).setValue(e),this.changeScript.emit())}))}onValidate(){this.scriptConfigForm.get("scriptLang").value===b.JS&&this.jsFuncComponent.validateOnSubmit()}}e("TransformScriptConfigComponent",qr),qr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:qr,deps:[{token:R.Store},{token:O.FormBuilder},{token:ie.NodeScriptTestService},{token:X.TranslateService}],target:t.ɵɵFactoryTarget.Component}),qr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:qr,selector:"tb-transformation-node-script-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n \n \n
\n \n
\n
\n',dependencies:[{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:de.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:ce.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ce.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:ye.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:qr,decorators:[{type:n,args:[{selector:"tb-transformation-node-script-config",template:'
\n \n \n \n \n \n \n \n
\n \n
\n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder},{type:ie.NodeScriptTestService},{type:X.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}}); -/** - * @license - * Copyright Google LLC All Rights Reserved. - * - * Use of this source code is governed by an MIT-style license that can be - * found in the LICENSE file at https://angular.io/license - */ -const Ar=ut({passive:!0});class Mr{constructor(e,t){this._platform=e,this._ngZone=t,this._monitoredElements=new Map}monitor(e){if(!this._platform.isBrowser)return He;const t=Te(e),n=this._monitoredElements.get(t);if(n)return n.subject;const r=new Ke,o="cdk-text-field-autofilled",a=e=>{"cdk-text-field-autofill-start"!==e.animationName||t.classList.contains(o)?"cdk-text-field-autofill-end"===e.animationName&&t.classList.contains(o)&&(t.classList.remove(o),this._ngZone.run((()=>r.next({target:e.target,isAutofilled:!1})))):(t.classList.add(o),this._ngZone.run((()=>r.next({target:e.target,isAutofilled:!0}))))};return this._ngZone.runOutsideAngular((()=>{t.addEventListener("animationstart",a,Ar),t.classList.add("cdk-text-field-autofill-monitored")})),this._monitoredElements.set(t,{subject:r,unlisten:()=>{t.removeEventListener("animationstart",a,Ar)}}),r}stopMonitoring(e){const t=Te(e),n=this._monitoredElements.get(t);n&&(n.unlisten(),n.subject.complete(),t.classList.remove("cdk-text-field-autofill-monitored"),t.classList.remove("cdk-text-field-autofilled"),this._monitoredElements.delete(t))}ngOnDestroy(){this._monitoredElements.forEach(((e,t)=>this.stopMonitoring(t)))}}Mr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.0-rc.0",ngImport:t,type:Mr,deps:[{token:dt.Platform},{token:t.NgZone}],target:t.ɵɵFactoryTarget.Injectable}),Mr.ɵprov=t.ɵɵngDeclareInjectable({minVersion:"12.0.0",version:"15.2.0-rc.0",ngImport:t,type:Mr,providedIn:"root"}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.0-rc.0",ngImport:t,type:Mr,decorators:[{type:s,args:[{providedIn:"root"}]}],ctorParameters:function(){return[{type:dt.Platform},{type:t.NgZone}]}});class Er{constructor(e,t){this._elementRef=e,this._autofillMonitor=t,this.cdkAutofill=new r}ngOnInit(){this._autofillMonitor.monitor(this._elementRef).subscribe((e=>this.cdkAutofill.emit(e)))}ngOnDestroy(){this._autofillMonitor.stopMonitoring(this._elementRef)}}Er.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.0-rc.0",ngImport:t,type:Er,deps:[{token:t.ElementRef},{token:Mr}],target:t.ɵɵFactoryTarget.Directive}),Er.ɵdir=t.ɵɵngDeclareDirective({minVersion:"14.0.0",version:"15.2.0-rc.0",type:Er,selector:"[cdkAutofill]",outputs:{cdkAutofill:"cdkAutofill"},ngImport:t}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.0-rc.0",ngImport:t,type:Er,decorators:[{type:u,args:[{selector:"[cdkAutofill]"}]}],ctorParameters:function(){return[{type:t.ElementRef},{type:Mr}]},propDecorators:{cdkAutofill:[{type:d}]}}); -/** - * @license - * Copyright Google LLC All Rights Reserved. - * - * Use of this source code is governed by an MIT-style license that can be - * found in the LICENSE file at https://angular.io/license - */ -class Gr{get minRows(){return this._minRows}set minRows(e){this._minRows=Ie(e),this._setMinHeight()}get maxRows(){return this._maxRows}set maxRows(e){this._maxRows=Ie(e),this._setMaxHeight()}get enabled(){return this._enabled}set enabled(e){e=Le(e),this._enabled!==e&&((this._enabled=e)?this.resizeToFitContent(!0):this.reset())}get placeholder(){return this._textareaElement.placeholder}set placeholder(e){this._cachedPlaceholderHeight=void 0,e?this._textareaElement.setAttribute("placeholder",e):this._textareaElement.removeAttribute("placeholder"),this._cacheTextareaPlaceholderHeight()}constructor(e,t,n,r){this._elementRef=e,this._platform=t,this._ngZone=n,this._destroyed=new Ke,this._enabled=!0,this._previousMinRows=-1,this._isViewInited=!1,this._handleFocusEvent=e=>{this._hasFocus="focus"===e.type},this._document=r,this._textareaElement=this._elementRef.nativeElement}_setMinHeight(){const e=this.minRows&&this._cachedLineHeight?this.minRows*this._cachedLineHeight+"px":null;e&&(this._textareaElement.style.minHeight=e)}_setMaxHeight(){const e=this.maxRows&&this._cachedLineHeight?this.maxRows*this._cachedLineHeight+"px":null;e&&(this._textareaElement.style.maxHeight=e)}ngAfterViewInit(){this._platform.isBrowser&&(this._initialHeight=this._textareaElement.style.height,this.resizeToFitContent(),this._ngZone.runOutsideAngular((()=>{const e=this._getWindow();je(e,"resize").pipe(Pe(16),we(this._destroyed)).subscribe((()=>this.resizeToFitContent(!0))),this._textareaElement.addEventListener("focus",this._handleFocusEvent),this._textareaElement.addEventListener("blur",this._handleFocusEvent)})),this._isViewInited=!0,this.resizeToFitContent(!0))}ngOnDestroy(){this._textareaElement.removeEventListener("focus",this._handleFocusEvent),this._textareaElement.removeEventListener("blur",this._handleFocusEvent),this._destroyed.next(),this._destroyed.complete()}_cacheTextareaLineHeight(){if(this._cachedLineHeight)return;let e=this._textareaElement.cloneNode(!1);e.rows=1,e.style.position="absolute",e.style.visibility="hidden",e.style.border="none",e.style.padding="0",e.style.height="",e.style.minHeight="",e.style.maxHeight="",e.style.overflow="hidden",this._textareaElement.parentNode.appendChild(e),this._cachedLineHeight=e.clientHeight,e.remove(),this._setMinHeight(),this._setMaxHeight()}_measureScrollHeight(){const e=this._textareaElement,t=e.style.marginBottom||"",n=this._platform.FIREFOX,r=n&&this._hasFocus,o=n?"cdk-textarea-autosize-measuring-firefox":"cdk-textarea-autosize-measuring";r&&(e.style.marginBottom=`${e.clientHeight}px`),e.classList.add(o);const a=e.scrollHeight-4;return e.classList.remove(o),r&&(e.style.marginBottom=t),a}_cacheTextareaPlaceholderHeight(){if(!this._isViewInited||null!=this._cachedPlaceholderHeight)return;if(!this.placeholder)return void(this._cachedPlaceholderHeight=0);const e=this._textareaElement.value;this._textareaElement.value=this._textareaElement.placeholder,this._cachedPlaceholderHeight=this._measureScrollHeight(),this._textareaElement.value=e}ngDoCheck(){this._platform.isBrowser&&this.resizeToFitContent()}resizeToFitContent(e=!1){if(!this._enabled)return;if(this._cacheTextareaLineHeight(),this._cacheTextareaPlaceholderHeight(),!this._cachedLineHeight)return;const t=this._elementRef.nativeElement,n=t.value;if(!e&&this._minRows===this._previousMinRows&&n===this._previousValue)return;const r=this._measureScrollHeight(),o=Math.max(r,this._cachedPlaceholderHeight||0);t.style.height=`${o}px`,this._ngZone.runOutsideAngular((()=>{"undefined"!=typeof requestAnimationFrame?requestAnimationFrame((()=>this._scrollToCaretPosition(t))):setTimeout((()=>this._scrollToCaretPosition(t)))})),this._previousValue=n,this._previousMinRows=this._minRows}reset(){void 0!==this._initialHeight&&(this._textareaElement.style.height=this._initialHeight)}_noopInputHandler(){}_getDocument(){return this._document||document}_getWindow(){return this._getDocument().defaultView||window}_scrollToCaretPosition(e){const{selectionStart:t,selectionEnd:n}=e;!this._destroyed.isStopped&&this._hasFocus&&e.setSelectionRange(t,n)}}Gr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.0-rc.0",ngImport:t,type:Gr,deps:[{token:t.ElementRef},{token:dt.Platform},{token:t.NgZone},{token:$,optional:!0}],target:t.ɵɵFactoryTarget.Directive}),Gr.ɵdir=t.ɵɵngDeclareDirective({minVersion:"14.0.0",version:"15.2.0-rc.0",type:Gr,selector:"textarea[cdkTextareaAutosize]",inputs:{minRows:["cdkAutosizeMinRows","minRows"],maxRows:["cdkAutosizeMaxRows","maxRows"],enabled:["cdkTextareaAutosize","enabled"],placeholder:"placeholder"},host:{attributes:{rows:"1"},listeners:{input:"_noopInputHandler()"},classAttribute:"cdk-textarea-autosize"},exportAs:["cdkTextareaAutosize"],ngImport:t}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.0-rc.0",ngImport:t,type:Gr,decorators:[{type:u,args:[{selector:"textarea[cdkTextareaAutosize]",exportAs:"cdkTextareaAutosize",host:{class:"cdk-textarea-autosize",rows:"1","(input)":"_noopInputHandler()"}}]}],ctorParameters:function(){return[{type:t.ElementRef},{type:dt.Platform},{type:t.NgZone},{type:void 0,decorators:[{type:p},{type:m,args:[$]}]}]},propDecorators:{minRows:[{type:i,args:["cdkAutosizeMinRows"]}],maxRows:[{type:i,args:["cdkAutosizeMaxRows"]}],enabled:[{type:i,args:["cdkTextareaAutosize"]}],placeholder:[{type:i}]}}); -/** - * @license - * Copyright Google LLC All Rights Reserved. - * - * Use of this source code is governed by an MIT-style license that can be - * found in the LICENSE file at https://angular.io/license - */ -class Dr{}Dr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.0-rc.0",ngImport:t,type:Dr,deps:[],target:t.ɵɵFactoryTarget.NgModule}),Dr.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.0-rc.0",ngImport:t,type:Dr,declarations:[Er,Gr],exports:[Er,Gr]}),Dr.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.0-rc.0",ngImport:t,type:Dr}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.0-rc.0",ngImport:t,type:Dr,decorators:[{type:c,args:[{declarations:[Er,Gr],exports:[Er,Gr]}]}]});class Vr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.mailBodyTypes=[{name:"tb.mail-body-type.plain-text",description:"tb.mail-body-type.plain-text-description",value:"false"},{name:"tb.mail-body-type.html",description:"tb.mail-body-type.html-text-description",value:"true"},{name:"tb.mail-body-type.use-body-type-template",description:"tb.mail-body-type.dynamic-text-description",value:"dynamic"}]}configForm(){return this.toEmailConfigForm}onConfigurationSet(e){this.toEmailConfigForm=this.fb.group({fromTemplate:[e?e.fromTemplate:null,[_.required]],toTemplate:[e?e.toTemplate:null,[_.required]],ccTemplate:[e?e.ccTemplate:null,[]],bccTemplate:[e?e.bccTemplate:null,[]],subjectTemplate:[e?e.subjectTemplate:null,[_.required]],mailBodyType:[e?e.mailBodyType:null],isHtmlTemplate:[e?e.isHtmlTemplate:null,[_.required]],bodyTemplate:[e?e.bodyTemplate:null,[_.required]]})}prepareInputConfig(e){return{fromTemplate:se(e?.fromTemplate)?e.fromTemplate:null,toTemplate:se(e?.toTemplate)?e.toTemplate:null,ccTemplate:se(e?.ccTemplate)?e.ccTemplate:null,bccTemplate:se(e?.bccTemplate)?e.bccTemplate:null,subjectTemplate:se(e?.subjectTemplate)?e.subjectTemplate:null,mailBodyType:se(e?.mailBodyType)?e.mailBodyType:null,isHtmlTemplate:se(e?.isHtmlTemplate)?e.isHtmlTemplate:null,bodyTemplate:se(e?.bodyTemplate)?e.bodyTemplate:null}}updateValidators(e){"dynamic"===this.toEmailConfigForm.get("mailBodyType").value?this.toEmailConfigForm.get("isHtmlTemplate").enable({emitEvent:!1}):this.toEmailConfigForm.get("isHtmlTemplate").disable({emitEvent:!1}),this.toEmailConfigForm.get("isHtmlTemplate").updateValueAndValidity({emitEvent:e})}validatorTriggers(){return["mailBodyType"]}getBodyTypeName(){return this.mailBodyTypes.find((e=>e.value===this.toEmailConfigForm.get("mailBodyType").value)).name}}e("ToEmailConfigComponent",Vr),Vr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Vr,deps:[{token:R.Store},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Vr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Vr,selector:"tb-transformation-node-to-email-config",usesInheritance:!0,ngImport:t,template:'
\n
\n
tb.rulenode.email-sender
\n
\n \n tb.rulenode.from-template\n \n \n {{ \'tb.rulenode.email-from-template-hint\' | translate }}\n \n \n
\n
\n
\n
\n \n {{ \'tb.rulenode.from-template-required\' | translate }}\n \n
\n
\n
\n
\n
\n
tb.rulenode.recipients
\n \n \n
\n
\n \n tb.rulenode.to-template\n \n \n {{ \'tb.rulenode.to-template-required\' | translate }}\n \n \n \n tb.rulenode.cc-template\n \n \n \n tb.rulenode.bcc-template\n \n \n
\n
\n
\n
tb.rulenode.message-subject-and-content
\n \n \n
\n \n tb.rulenode.subject-template\n \n \n {{ \'tb.rulenode.subject-template-required\' | translate }}\n \n \n \n tb.rulenode.mail-body-type\n \n \n \n {{ getBodyTypeName() | translate }}\n \n \n \n \n {{ type.name | translate }}\n \n
\n \n {{ type.description | translate }}\n \n
\n
\n
\n \n tb.rulenode.body-type-template\n \n tb.mail-body-type.after-template-evaluation-hint\n \n \n tb.rulenode.body-template\n \n \n {{ \'tb.rulenode.body-template-required\' | translate }}\n \n \n
\n
\n
\n',styles:[":host .input-bottom-double-hint{display:inline-flex}:host .input-bottom-double-hint .see-example{flex-shrink:0;padding-right:16px}:host textarea.tb-enable-vertical-resize{resize:vertical}\n"],dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:$e.HelpPopupComponent,selector:"[tb-help-popup], [tb-help-popup-content]",inputs:["tb-help-popup","tb-help-popup-content","trigger-text","trigger-style","tb-help-popup-placement","tb-help-popup-style","hintMode"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Gr,selector:"textarea[cdkTextareaAutosize]",inputs:["cdkAutosizeMinRows","cdkAutosizeMaxRows","cdkTextareaAutosize","placeholder"],exportAs:["cdkTextareaAutosize"]},{kind:"component",type:ee.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"directive",type:ee.MatSelectTrigger,selector:"mat-select-trigger"},{kind:"component",type:te.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:qe.MatListItemTitle,selector:"[matListItemTitle]"},{kind:"directive",type:qe.MatListItemMeta,selector:"[matListItemMeta]"},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:An,selector:"tb-example-hint",inputs:["hintText","popupHelpLink","textAlign"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Vr,decorators:[{type:n,args:[{selector:"tb-transformation-node-to-email-config",template:'
\n
\n
tb.rulenode.email-sender
\n
\n \n tb.rulenode.from-template\n \n \n {{ \'tb.rulenode.email-from-template-hint\' | translate }}\n \n \n
\n
\n
\n
\n \n {{ \'tb.rulenode.from-template-required\' | translate }}\n \n
\n
\n
\n
\n
\n
tb.rulenode.recipients
\n \n \n
\n
\n \n tb.rulenode.to-template\n \n \n {{ \'tb.rulenode.to-template-required\' | translate }}\n \n \n \n tb.rulenode.cc-template\n \n \n \n tb.rulenode.bcc-template\n \n \n
\n
\n
\n
tb.rulenode.message-subject-and-content
\n \n \n
\n \n tb.rulenode.subject-template\n \n \n {{ \'tb.rulenode.subject-template-required\' | translate }}\n \n \n \n tb.rulenode.mail-body-type\n \n \n \n {{ getBodyTypeName() | translate }}\n \n \n \n \n {{ type.name | translate }}\n \n
\n \n {{ type.description | translate }}\n \n
\n
\n
\n \n tb.rulenode.body-type-template\n \n tb.mail-body-type.after-template-evaluation-hint\n \n \n tb.rulenode.body-template\n \n \n {{ \'tb.rulenode.body-template-required\' | translate }}\n \n \n
\n
\n
\n',styles:[":host .input-bottom-double-hint{display:inline-flex}:host .input-bottom-double-hint .see-example{flex-shrink:0;padding-right:16px}:host textarea.tb-enable-vertical-resize{resize:vertical}\n"]}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder}]}});class wr extends f{constructor(e,t,n){super(e),this.store=e,this.fb=t,this.translate=n,this.copyFrom=[],this.translation=on;for(const e of this.translation.keys())this.copyFrom.push({value:e,name:this.translate.instant(this.translation.get(e))})}onConfigurationSet(e){this.copyKeysConfigForm=this.fb.group({copyFrom:[e.copyFrom,[_.required]],keys:[e?e.keys:null,[_.required]]})}configForm(){return this.copyKeysConfigForm}prepareInputConfig(e){let t;return t=se(e?.fromMetadata)?e.copyFrom?rn.METADATA:rn.DATA:se(e?.copyFrom)?e.copyFrom:rn.DATA,{keys:se(e?.keys)?e.keys:null,copyFrom:t}}}e("CopyKeysConfigComponent",wr),wr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:wr,deps:[{token:R.Store},{token:O.FormBuilder},{token:X.TranslateService}],target:t.ɵɵFactoryTarget.Component}),wr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:wr,selector:"tb-transformation-node-copy-keys-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n help\n \n \n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"component",type:et.StringItemsListComponent,selector:"tb-string-items-list",inputs:["required","disabled","label","placeholder","hint","requiredText","floatLabel","appearance","editable","subscriptSizing","predefinedValues"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:W.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:Kn,selector:"tb-msg-metadata-chip",inputs:["labelText","translation"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:wr,decorators:[{type:n,args:[{selector:"tb-transformation-node-copy-keys-config",template:'
\n \n \n \n \n help\n \n \n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder},{type:X.TranslateService}]}});class Pr extends f{constructor(e,t,n){super(e),this.store=e,this.fb=t,this.translate=n,this.renameIn=[],this.translation=ln;for(const e of this.translation.keys())this.renameIn.push({value:e,name:this.translate.instant(this.translation.get(e))})}configForm(){return this.renameKeysConfigForm}onConfigurationSet(e){this.renameKeysConfigForm=this.fb.group({renameIn:[e?e.renameIn:null,[_.required]],renameKeysMapping:[e?e.renameKeysMapping:null,[_.required]]})}prepareInputConfig(e){let t;return t=se(e?.fromMetadata)?e.fromMetadata?rn.METADATA:rn.DATA:se(e?.renameIn)?e?.renameIn:rn.DATA,{renameKeysMapping:se(e?.renameKeysMapping)?e.renameKeysMapping:null,renameIn:t}}}e("RenameKeysConfigComponent",Pr),Pr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Pr,deps:[{token:R.Store},{token:O.FormBuilder},{token:X.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Pr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Pr,selector:"tb-transformation-node-rename-keys-config",usesInheritance:!0,ngImport:t,template:'
\n
tb.rulenode.rename-keys-in
\n
\n
\n \n \n {{ data.name }}\n \n \n
\n
\n \n \n
\n',styles:[":host .fetch-to-data-toggle{max-width:420px;width:100%}:host .fx-centered{display:flex;width:100%;justify-content:space-around}\n"],dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"directive",type:tt.ToggleOption,selector:"tb-toggle-option",inputs:["value"]},{kind:"component",type:nt.ToggleSelectComponent,selector:"tb-toggle-select",inputs:["disabled","selectMediaBreakpoint","appearance","disablePagination"]},{kind:"component",type:Mn,selector:"tb-kv-map-config",inputs:["disabled","uniqueKeyValuePairValidator","labelText","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","popupHelpLink","required"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Pr,decorators:[{type:n,args:[{selector:"tb-transformation-node-rename-keys-config",template:'
\n
tb.rulenode.rename-keys-in
\n
\n
\n \n \n {{ data.name }}\n \n \n
\n
\n \n \n
\n',styles:[":host .fetch-to-data-toggle{max-width:420px;width:100%}:host .fx-centered{display:flex;width:100%;justify-content:space-around}\n"]}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder},{type:X.TranslateService}]}});class Rr extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.jsonPathConfigForm}onConfigurationSet(e){this.jsonPathConfigForm=this.fb.group({jsonPath:[e?e.jsonPath:null,[_.required]]})}}e("NodeJsonPathConfigComponent",Rr),Rr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Rr,deps:[{token:R.Store},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Rr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Rr,selector:"tb-transformation-node-json-path-config",usesInheritance:!0,ngImport:t,template:"
\n \n {{ 'tb.rulenode.json-path-expression' | translate }}\n \n {{ 'tb.rulenode.json-path-expression-hint' | translate }}\n {{ 'tb.rulenode.json-path-expression-required' | translate }}\n \n
\n",dependencies:[{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Rr,decorators:[{type:n,args:[{selector:"tb-transformation-node-json-path-config",template:"
\n \n {{ 'tb.rulenode.json-path-expression' | translate }}\n \n {{ 'tb.rulenode.json-path-expression-hint' | translate }}\n {{ 'tb.rulenode.json-path-expression-required' | translate }}\n \n
\n"}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder}]}});class Or extends f{constructor(e,t,n){super(e),this.store=e,this.fb=t,this.translate=n,this.deleteFrom=[],this.translation=an;for(const e of this.translation.keys())this.deleteFrom.push({value:e,name:this.translate.instant(this.translation.get(e))})}onConfigurationSet(e){this.deleteKeysConfigForm=this.fb.group({deleteFrom:[e.deleteFrom,[_.required]],keys:[e?e.keys:null,[_.required]]})}prepareInputConfig(e){let t;return t=se(e?.fromMetadata)?e.fromMetadata?rn.METADATA:rn.DATA:se(e?.deleteFrom)?e?.deleteFrom:rn.DATA,{keys:se(e?.keys)?e.keys:null,deleteFrom:t}}configForm(){return this.deleteKeysConfigForm}}e("DeleteKeysConfigComponent",Or),Or.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Or,deps:[{token:R.Store},{token:O.FormBuilder},{token:X.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Or.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Or,selector:"tb-transformation-node-delete-keys-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n help\n \n \n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"component",type:et.StringItemsListComponent,selector:"tb-string-items-list",inputs:["required","disabled","label","placeholder","hint","requiredText","floatLabel","appearance","editable","subscriptSizing","predefinedValues"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:W.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:Kn,selector:"tb-msg-metadata-chip",inputs:["labelText","translation"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Or,decorators:[{type:n,args:[{selector:"tb-transformation-node-delete-keys-config",template:'
\n \n \n \n \n help\n \n \n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder},{type:X.TranslateService}]}});class _r extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.serviceType=x.TB_RULE_ENGINE,this.deduplicationStrategie=wt,this.deduplicationStrategies=Object.keys(this.deduplicationStrategie),this.deduplicationStrategiesTranslations=Pt}configForm(){return this.deduplicationConfigForm}onConfigurationSet(e){this.deduplicationConfigForm=this.fb.group({interval:[se(e?.interval)?e.interval:null,[_.required,_.min(1)]],strategy:[se(e?.strategy)?e.strategy:null,[_.required]],outMsgType:[se(e?.outMsgType)?e.outMsgType:null,[_.required]],queueName:[se(e?.queueName)?e.queueName:null,[_.required]],maxPendingMsgs:[se(e?.maxPendingMsgs)?e.maxPendingMsgs:null,[_.required,_.min(1),_.max(1e3)]],maxRetries:[se(e?.maxRetries)?e.maxRetries:null,[_.required,_.min(0),_.max(100)]]})}prepareInputConfig(e){return e||(e={}),e.outMsgType||(e.outMsgType="POST_TELEMETRY_REQUEST"),super.prepareInputConfig(e)}updateValidators(e){this.deduplicationConfigForm.get("strategy").value===this.deduplicationStrategie.ALL?(this.deduplicationConfigForm.get("queueName").enable({emitEvent:!1}),this.deduplicationConfigForm.get("outMsgType").enable({emitEvent:!1})):(this.deduplicationConfigForm.get("outMsgType").disable({emitEvent:!1}),this.deduplicationConfigForm.get("queueName").disable({emitEvent:!1})),this.deduplicationConfigForm.get("outMsgType").updateValueAndValidity({emitEvent:e}),this.deduplicationConfigForm.get("queueName").updateValueAndValidity({emitEvent:e})}validatorTriggers(){return["strategy"]}}e("DeduplicationConfigComponent",_r),_r.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:_r,deps:[{token:R.Store},{token:O.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),_r.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:_r,selector:"tb-action-node-msg-deduplication-config",usesInheritance:!0,ngImport:t,template:'
\n \n {{\'tb.rulenode.interval\' | translate}}\n \n \n {{\'tb.rulenode.interval-required\' | translate}}\n \n \n {{\'tb.rulenode.interval-min-error\' | translate}}\n \n help\n \n
\n
\n
tb.rulenode.strategy
\n \n \n {{ deduplicationStrategiesTranslations.get(strategy) | translate }}\n \n \n \n \n \n \n \n \n
\n \n \n \n \n
\n
\n
\n \n \n tb.rulenode.advanced-settings\n \n
\n \n {{\'tb.rulenode.max-pending-msgs\' | translate}}\n \n \n {{\'tb.rulenode.max-pending-msgs-required\' | translate}}\n \n \n {{\'tb.rulenode.max-pending-msgs-max-error\' | translate}}\n \n \n {{\'tb.rulenode.max-pending-msgs-min-error\' | translate}}\n \n help\n \n \n {{\'tb.rulenode.max-retries\' | translate}}\n \n \n {{\'tb.rulenode.max-retries-required\' | translate}}\n \n \n {{\'tb.rulenode.max-retries-max-error\' | translate}}\n \n \n {{\'tb.rulenode.max-retries-min-error\' | translate}}\n \n help\n \n
\n
\n
\n
\n
\n',dependencies:[{kind:"directive",type:j.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:j.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:oe.QueueAutocompleteComponent,selector:"tb-queue-autocomplete",inputs:["labelText","requiredText","autocompleteHint","subscriptSizing","required","queueType","disabled"]},{kind:"component",type:fe.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:Y.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:W.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:W.MatLabel,selector:"mat-label"},{kind:"directive",type:W.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:W.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"directive",type:ge.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:We.MatExpansionPanel,selector:"mat-expansion-panel",inputs:["disabled","expanded","hideToggle","togglePosition"],outputs:["opened","closed","expandedChange","afterExpand","afterCollapse"],exportAs:["matExpansionPanel"]},{kind:"component",type:We.MatExpansionPanelHeader,selector:"mat-expansion-panel-header",inputs:["tabIndex","expandedHeight","collapsedHeight"]},{kind:"directive",type:We.MatExpansionPanelTitle,selector:"mat-panel-title"},{kind:"directive",type:O.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:O.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:X.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"directive",type:tt.ToggleOption,selector:"tb-toggle-option",inputs:["value"]},{kind:"component",type:nt.ToggleSelectComponent,selector:"tb-toggle-select",inputs:["disabled","selectMediaBreakpoint","appearance","disablePagination"]},{kind:"component",type:Bn,selector:"tb-output-message-type-autocomplete",inputs:["subscriptSizing","disabled","required"]},{kind:"component",type:An,selector:"tb-example-hint",inputs:["hintText","popupHelpLink","textAlign"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:_r,decorators:[{type:n,args:[{selector:"tb-action-node-msg-deduplication-config",template:'
\n \n {{\'tb.rulenode.interval\' | translate}}\n \n \n {{\'tb.rulenode.interval-required\' | translate}}\n \n \n {{\'tb.rulenode.interval-min-error\' | translate}}\n \n help\n \n
\n
\n
tb.rulenode.strategy
\n \n \n {{ deduplicationStrategiesTranslations.get(strategy) | translate }}\n \n \n \n \n \n \n \n \n
\n \n \n \n \n
\n
\n
\n \n \n tb.rulenode.advanced-settings\n \n
\n \n {{\'tb.rulenode.max-pending-msgs\' | translate}}\n \n \n {{\'tb.rulenode.max-pending-msgs-required\' | translate}}\n \n \n {{\'tb.rulenode.max-pending-msgs-max-error\' | translate}}\n \n \n {{\'tb.rulenode.max-pending-msgs-min-error\' | translate}}\n \n help\n \n \n {{\'tb.rulenode.max-retries\' | translate}}\n \n \n {{\'tb.rulenode.max-retries-required\' | translate}}\n \n \n {{\'tb.rulenode.max-retries-max-error\' | translate}}\n \n \n {{\'tb.rulenode.max-retries-min-error\' | translate}}\n \n help\n \n
\n
\n
\n
\n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.FormBuilder}]}});class Br{}e("RulenodeCoreConfigTransformModule",Br),Br.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Br,deps:[],target:t.ɵɵFactoryTarget.NgModule}),Br.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.10",ngImport:t,type:Br,declarations:[Sr,qr,Vr,wr,Pr,Rr,Or,_r],imports:[Q,E,$n],exports:[Sr,qr,Vr,wr,Pr,Rr,Or,_r]}),Br.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Br,imports:[Q,E,$n]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Br,decorators:[{type:c,args:[{declarations:[Sr,qr,Vr,wr,Pr,Rr,Or,_r],imports:[Q,E,$n],exports:[Sr,qr,Vr,wr,Pr,Rr,Or,_r]}]}]});class Kr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.entityType=k}configForm(){return this.ruleChainInputConfigForm}onConfigurationSet(e){this.ruleChainInputConfigForm=this.fb.group({ruleChainId:[e?e.ruleChainId:null,[_.required]]})}}e("RuleChainInputComponent",Kr),Kr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Kr,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Kr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Kr,selector:"tb-flow-node-rule-chain-input-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n
\n',dependencies:[{kind:"component",type:mt.EntityAutocompleteComponent,selector:"tb-entity-autocomplete",inputs:["entityType","entitySubtype","excludeEntityIds","labelText","requiredText","useFullEntityId","appearance","required","disabled"],outputs:["entityChanged"]},{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:O.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:O.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Kr,decorators:[{type:n,args:[{selector:"tb-flow-node-rule-chain-input-config",template:'
\n \n \n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class zr extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.ruleChainOutputConfigForm}onConfigurationSet(e){this.ruleChainOutputConfigForm=this.fb.group({})}}e("RuleChainOutputComponent",zr),zr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:zr,deps:[{token:R.Store},{token:O.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),zr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:zr,selector:"tb-flow-node-rule-chain-output-config",usesInheritance:!0,ngImport:t,template:'
\n
\n
\n',dependencies:[{kind:"directive",type:Z.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:O.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:O.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"pipe",type:X.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:zr,decorators:[{type:n,args:[{selector:"tb-flow-node-rule-chain-output-config",template:'
\n
\n
\n'}]}],ctorParameters:function(){return[{type:R.Store},{type:O.UntypedFormBuilder}]}});class Ur{}e("RuleNodeCoreConfigFlowModule",Ur),Ur.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Ur,deps:[],target:t.ɵɵFactoryTarget.NgModule}),Ur.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.10",ngImport:t,type:Ur,declarations:[Kr,zr],imports:[Q,E,$n],exports:[Kr,zr]}),Ur.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Ur,imports:[Q,E,$n]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Ur,decorators:[{type:c,args:[{declarations:[Kr,zr],imports:[Q,E,$n],exports:[Kr,zr]}]}]});class Hr{constructor(e){!function(e){e.setTranslation("en_US",{tb:{rulenode:{id:"Id","additional-info":"Additional Info","advanced-settings":"Advanced settings","create-entity-if-not-exists":"Create new entity if not exists","create-entity-if-not-exists-hint":"Create a new entity set above if it does not exist.","entity-name-pattern":"Name pattern","entity-name-pattern-required":"Name pattern is required","entity-name-pattern-hint":"Name pattern field support templatization. Use $[messageKey] to extract value from the message and ${metadataKey} to extract value from the metadata.","copy-message-type":"Copy message type","entity-type-pattern":"Type pattern","entity-type-pattern-required":"Type pattern is required","message-type-value":"Message type value","message-type-value-required":"Message type value is required","message-type-value-max-length":"Message type value should be less than 256","output-message-type":"Output message type","entity-cache-expiration":"Entities cache expiration time (sec)","entity-cache-expiration-hint":"Specifies maximum time interval allowed to store found entity records. 0 value means that records will never expire.","entity-cache-expiration-required":"Entities cache expiration time is required.","entity-cache-expiration-range":"Entities cache expiration time should be greater than or equal to 0.","customer-name-pattern":"Customer name pattern","customer-name-pattern-required":"Customer name pattern is required","create-customer-if-not-exists":"Create new customer if not exists","customer-cache-expiration":"Customers cache expiration time (sec)","customer-cache-expiration-hint":"Specifies maximum time interval allowed to store found customer records. 0 value means that records will never expire.","customer-cache-expiration-required":"Customers cache expiration time is required.","customer-cache-expiration-range":"Customers cache expiration time should be greater than or equal to 0.","interval-start":"Interval start","interval-end":"Interval end","time-unit":"Time unit","fetch-mode":"Fetch mode","order-by-timestamp":"Order by timestamp",limit:"Limit","limit-hint":"Min limit value is 2, max - 1000. If you want to fetch a single entry, select fetch mode 'First' or 'Last'.","limit-required":"Limit is required.","limit-range":"Limit should be in a range from 2 to 1000.","time-unit-milliseconds":"Milliseconds","time-unit-seconds":"Seconds","time-unit-minutes":"Minutes","time-unit-hours":"Hours","time-unit-days":"Days","time-value-range":"Allowing range from 1 to 2147483647.","start-interval-value-required":"Interval start is required.","end-interval-value-required":"Interval end is required.",filter:"Filter",switch:"Switch","math-templatization-tooltip":"This field support templatization. Use $[messageKey] to extract value from the message and ${metadataKey} to extract value from the metadata.","add-message-type":"Add message type","select-message-types-required":"At least one message type should be selected.","select-message-types":"Select message types","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","attributes-keys":"Attributes keys","attributes-keys-required":"Attributes keys are required","notify-device":"Force notification to the device","send-attributes-updated-notification":"Send attributes updated notification","send-attributes-updated-notification-hint":"Send notification about updated attributes as a separate message to the rule engine queue.","send-attributes-deleted-notification":"Send attributes deleted notification","send-attributes-deleted-notification-hint":"Send notification about deleted attributes as a separate message to the rule engine queue.","update-attributes-only-on-value-change":"Save attributes only if the value changes","update-attributes-only-on-value-change-hint":"Updates the attributes on every incoming message disregarding if their value has changed. Increases API usage and reduces performance.","update-attributes-only-on-value-change-hint-enabled":"Updates the attributes only if their value has changed. If the value is not changed, no update to the attribute timestamp nor attribute change notification will be sent.","fetch-credentials-to-metadata":"Fetch credentials to metadata","notify-device-on-update-hint":"If enabled, force notification to the device about shared attributes update. If disabled, the notification behavior is controlled by the 'notifyDevice' parameter from the incoming message metadata. To turn off the notification, the message metadata must contain the 'notifyDevice' parameter set to 'false'. Any other case will trigger the notification to the device.","notify-device-on-delete-hint":"If enabled, force notification to the device about shared attributes removal. If disabled, the notification behavior is controlled by the 'notifyDevice' parameter from the incoming message metadata. To turn on the notification, the message metadata must contain the 'notifyDevice' parameter set to 'true'. In any other case, the notification will not be triggered to the device.","latest-timeseries":"Latest time-series data keys","timeseries-keys":"Timeseries keys","timeseries-keys-required":"At least one timeseries key should be selected.","add-timeseries-key":"Add timeseries key","add-message-field":"Add message field","relation-search-parameters":"Relation search parameters","add-metadata-field":"Add metadata field","data-keys":"Message field names","copy-from":"Copy from","data-to-metadata":"Data to metadata","metadata-to-data":"Metadata to data","use-regular-expression-hint":"Use regular expression to copy keys by pattern.\n\nTips & tricks:\nPress 'Enter' to complete field name input.\nPress 'Backspace' to delete field name. Multiple field names supported.",interval:"Interval","interval-required":"Interval is required","interval-hint":"Deduplication interval in seconds.","interval-min-error":"Min allowed value is 1","max-pending-msgs":"Max pending messages","max-pending-msgs-hint":"Maximum number of messages that are stored in memory for each unique deduplication id.","max-pending-msgs-required":"Max pending messages is required","max-pending-msgs-max-error":"Max allowed value is 1000","max-pending-msgs-min-error":"Min allowed value is 1","max-retries":"Max retries","max-retries-required":"Max retries is required","max-retries-hint":"Maximum number of retries to push the deduplicated messages into the queue. 10 seconds delay is used between retries","max-retries-max-error":"Max allowed value is 100","max-retries-min-error":"Min allowed value is 0",strategy:"Strategy","strategy-required":"Strategy is required","strategy-all-hint":"Return all messages that arrived during deduplication period as a single JSON array message. Where each element represents object with msg and metadata inner properties.","strategy-first-hint":"Return first message that arrived during deduplication period.","strategy-last-hint":"Return last message that arrived during deduplication period.",first:"First",last:"Last",all:"All","output-msg-type-hint":"The message type of the deduplication result.","queue-name-hint":"The queue name where the deduplication result will be published.",keys:"Keys","keys-required":"Keys are required","rename-keys-in":"Rename keys in",data:"Data",message:"Message",metadata:"Metadata","current-key-name":"Current key name","key-name-required":"Key name is required","new-key-name":"New key name","new-key-name-required":"New key name is required","metadata-keys":"Metadata field names","json-path-expression":"JSON path expression","json-path-expression-required":"JSON path expression is required","json-path-expression-hint":"JSONPath specifies a path to an element or a set of elements in a JSON structure. '$' represents the root object or array.","relations-query":"Relations query","device-relations-query":"Device relations query","max-relation-level":"Max relation level","max-relation-level-error":"Value should be greater than 0 or unspecified.","relation-type":"Relation type","relation-type-pattern":"Relation type pattern","relation-type-pattern-required":"Relation type pattern is required","relation-types-list":"Relation types to propagate","relation-types-list-hint":"If Propagate relation types are not selected, alarms will be propagated without filtering by relation type.","unlimited-level":"Unlimited level","latest-telemetry":"Latest telemetry","add-telemetry-key":"Add telemetry key","delete-from":"Delete from","use-regular-expression-delete-hint":"Use regular expression to delete keys by pattern.\n\nTips & tricks:\nPress 'Enter' to complete field name input.\nPress 'Backspace' to delete field name.\nMultiple field names supported.","fetch-into":"Fetch into","attr-mapping":"Attributes mapping:","source-attribute":"Source attribute key","source-attribute-required":"Source attribute key is required.","source-telemetry":"Source telemetry key","source-telemetry-required":"Source telemetry key is required.","target-key":"Target key","target-key-required":"Target key is required.","attr-mapping-required":"At least one mapping entry should be specified.","fields-mapping":"Fields mapping","relations-query-config-direction-suffix":"originator","profile-name":"Profile name","fetch-circle-parameter-info-from-metadata-hint":'Metadata field \'{{perimeterKeyName}}\' should be defined in next format: {"latitude":48.196, "longitude":24.6532, "radius":100.0, "radiusUnit":"METER"}',"fetch-poligon-parameter-info-from-metadata-hint":"Metadata field '{{perimeterKeyName}}' should be defined in next format: [[48.19736,24.65235],[48.19800,24.65060],...,[48.19849,24.65420]]","short-templatization-tooltip":"Use $[messageKey] to extract value from the message and ${metadataKey} to extract value from the metadata.","fields-mapping-required":"At least one field mapping should be specified.","at-least-one-field-required":"At least one input field must have a value(s) provided.","originator-fields-sv-map-hint":"Target key fields support templatization. Use $[messageKey] to extract value from the message and ${metadataKey} to extract value from the metadata.","sv-map-hint":"Only target key fields support templatization. Use $[messageKey] to extract value from the message and ${metadataKey} to extract value from the metadata.","source-field":"Source field","source-field-required":"Source field is required.","originator-source":"Originator source","new-originator":"New originator","originator-customer":"Customer","originator-tenant":"Tenant","originator-related":"Related entity","originator-alarm-originator":"Alarm Originator","originator-entity":"Entity by name pattern","clone-message":"Clone message",transform:"Transform","default-ttl":"Default TTL in seconds","default-ttl-required":"Default TTL is required.","min-default-ttl-message":"Only 0 minimum TTL is allowed.","message-count":"Message count (0 - unlimited)","message-count-required":"Message count is required.","min-message-count-message":"Only 0 minimum message count is allowed.","period-seconds":"Period in seconds","period-seconds-required":"Period is required.","use-metadata-period-in-seconds-patterns":"Use period in seconds pattern","use-metadata-period-in-seconds-patterns-hint":"If selected, rule node use period in seconds interval pattern from message metadata or data assuming that intervals are in the seconds.","period-in-seconds-pattern":"Period in seconds pattern","period-in-seconds-pattern-required":"Period in seconds pattern is required","min-period-seconds-message":"Only 1 second minimum period is allowed.",originator:"Originator","message-body":"Message body","message-metadata":"Message metadata",generate:"Generate","test-generator-function":"Test generator function",generator:"Generator","test-filter-function":"Test filter function","test-switch-function":"Test switch function","test-transformer-function":"Test transformer function",transformer:"Transformer","alarm-create-condition":"Alarm create condition","test-condition-function":"Test condition function","alarm-clear-condition":"Alarm clear condition","alarm-details-builder":"Alarm details builder","test-details-function":"Test details function","alarm-type":"Alarm type","select-entity-types":"Select entity types","alarm-type-required":"Alarm type is required.","alarm-severity":"Alarm severity","alarm-severity-required":"Alarm severity is required","alarm-severity-pattern":"Alarm severity pattern","alarm-status-filter":"Alarm status filter","alarm-status-list-empty":"Alarm status list is empty","no-alarm-status-matching":"No alarm status matching were found.",propagate:"Propagate alarm to related entities","propagate-to-owner":"Propagate alarm to entity owner (Customer or Tenant)","propagate-to-tenant":"Propagate alarm to Tenant",condition:"Condition",details:"Details","to-string":"To string","test-to-string-function":"Test to string function","from-template":"From","from-template-required":"From is required","message-to-metadata":"Message to metadata","metadata-to-message":"Metadata to message","from-message":"From message","from-metadata":"From metadata","to-template":"To","to-template-required":"To Template is required","mail-address-list-template-hint":'Comma separated address list, use ${metadataKey} for value from metadata, $[messageKey] for value from message body',"cc-template":"Cc","bcc-template":"Bcc","subject-template":"Subject","subject-template-required":"Subject Template is required","body-template":"Body","body-template-required":"Body Template is required","dynamic-mail-body-type":"Dynamic mail body type","mail-body-type":"Mail body type","body-type-template":"Body type template","request-id-metadata-attribute":"Request Id Metadata attribute name","timeout-sec":"Timeout in seconds","timeout-required":"Timeout is required","min-timeout-message":"Only 0 minimum timeout value is allowed.","endpoint-url-pattern":"Endpoint URL pattern","endpoint-url-pattern-required":"Endpoint URL pattern is required","request-method":"Request method","use-simple-client-http-factory":"Use simple client HTTP factory","ignore-request-body":"Without request body","parse-to-plain-text":"Parse to plain text","parse-to-plain-text-hint":'If selected, request body message payload will be transformed from JSON string to plain text, e.g. msg = "Hello,\\t\\"world\\"" will be parsed to Hello, "world"',"read-timeout":"Read timeout in millis","read-timeout-hint":"The value of 0 means an infinite timeout","max-parallel-requests-count":"Max number of parallel requests","max-parallel-requests-count-hint":"The value of 0 specifies no limit in parallel processing",headers:"Headers","headers-hint":'Use ${metadataKey} for value from metadata, $[messageKey] for value from message body in header/value fields',header:"Header","header-required":"Header is required",value:"Value","value-required":"Value is required","topic-pattern":"Topic pattern","key-pattern":"Key pattern","key-pattern-hint":"Optional. If a valid partition number is specified, it will be used when sending the record. If no partition is specified, the key will be used instead. If neither is specified, a partition will be assigned in a round-robin fashion.","topic-pattern-required":"Topic pattern is required",topic:"Topic","topic-required":"Topic is required","bootstrap-servers":"Bootstrap servers","bootstrap-servers-required":"Bootstrap servers value is required","other-properties":"Other properties",key:"Key","key-required":"Key is required",retries:"Automatically retry times if fails","min-retries-message":"Only 0 minimum retries is allowed.","batch-size-bytes":"Produces batch size in bytes","min-batch-size-bytes-message":"Only 0 minimum batch size is allowed.","linger-ms":"Time to buffer locally (ms)","min-linger-ms-message":"Only 0 ms minimum value is allowed.","buffer-memory-bytes":"Client buffer max size in bytes","min-buffer-memory-message":"Only 0 minimum buffer size is allowed.",acks:"Number of acknowledgments","key-serializer":"Key serializer","key-serializer-required":"Key serializer is required","value-serializer":"Value serializer","value-serializer-required":"Value serializer is required","topic-arn-pattern":"Topic ARN pattern","topic-arn-pattern-required":"Topic ARN pattern is required","aws-access-key-id":"AWS Access Key ID","aws-access-key-id-required":"AWS Access Key ID is required","aws-secret-access-key":"AWS Secret Access Key","aws-secret-access-key-required":"AWS Secret Access Key is required","aws-region":"AWS Region","aws-region-required":"AWS Region is required","exchange-name-pattern":"Exchange name pattern","routing-key-pattern":"Routing key pattern","message-properties":"Message properties",host:"Host","host-required":"Host is required",port:"Port","port-required":"Port is required","port-range":"Port should be in a range from 1 to 65535.","virtual-host":"Virtual host",username:"Username",password:"Password","automatic-recovery":"Automatic recovery","connection-timeout-ms":"Connection timeout (ms)","min-connection-timeout-ms-message":"Only 0 ms minimum value is allowed.","handshake-timeout-ms":"Handshake timeout (ms)","min-handshake-timeout-ms-message":"Only 0 ms minimum value is allowed.","client-properties":"Client properties","queue-url-pattern":"Queue URL pattern","queue-url-pattern-required":"Queue URL pattern is required","delay-seconds":"Delay (seconds)","min-delay-seconds-message":"Only 0 seconds minimum value is allowed.","max-delay-seconds-message":"Only 900 seconds maximum value is allowed.",name:"Name","name-required":"Name is required","queue-type":"Queue type","sqs-queue-standard":"Standard","sqs-queue-fifo":"FIFO","gcp-project-id":"GCP project ID","gcp-project-id-required":"GCP project ID is required","gcp-service-account-key":"GCP service account key file","gcp-service-account-key-required":"GCP service account key file is required","pubsub-topic-name":"Topic name","pubsub-topic-name-required":"Topic name is required","message-attributes":"Message attributes","message-attributes-hint":'Use ${metadataKey} for value from metadata, $[messageKey] for value from message body in name/value fields',"connect-timeout":"Connection timeout (sec)","connect-timeout-required":"Connection timeout is required.","connect-timeout-range":"Connection timeout should be in a range from 1 to 200.","client-id":"Client ID","client-id-hint":'Optional. Leave empty for auto-generated Client ID. Be careful when specifying the Client ID. Majority of the MQTT brokers will not allow multiple connections with the same Client ID. To connect to such brokers, your mqtt Client ID must be unique. When platform is running in a micro-services mode, the copy of rule node is launched in each micro-service. This will automatically lead to multiple mqtt clients with the same ID and may cause failures of the rule node. To avoid such failures enable "Add Service ID as suffix to Client ID" option below.',"append-client-id-suffix":"Add Service ID as suffix to Client ID","client-id-suffix-hint":'Optional. Applied when "Client ID" specified explicitly. If selected then Service ID will be added to Client ID as a suffix. Helps to avoid failures when platform is running in a micro-services mode.',"device-id":"Device ID","device-id-required":"Device ID is required.","clean-session":"Clean session","enable-ssl":"Enable SSL",credentials:"Credentials","credentials-type":"Credentials type","credentials-type-required":"Credentials type is required.","credentials-anonymous":"Anonymous","credentials-basic":"Basic","credentials-pem":"PEM","credentials-pem-hint":"At least Server CA certificate file or a pair of Client certificate and Client private key files are required","credentials-sas":"Shared Access Signature","sas-key":"SAS Key","sas-key-required":"SAS Key is required.",hostname:"Hostname","hostname-required":"Hostname is required.","azure-ca-cert":"CA certificate file","username-required":"Username is required.","password-required":"Password is required.","ca-cert":"Server CA certificate file","private-key":"Client private key file",cert:"Client certificate file","no-file":"No file selected.","drop-file":"Drop a file or click to select a file to upload.","private-key-password":"Private key password","use-system-smtp-settings":"Use system SMTP settings","use-metadata-dynamic-interval":"Use dynamic interval","metadata-dynamic-interval-hint":"Interval start and end input fields support templatization. Note that the substituted template value should be set in milliseconds. Use $[messageKey] to extract value from the message and ${metadataKey} to extract value from the metadata.","use-metadata-interval-patterns-hint":"If selected, rule node use start and end interval patterns from message metadata or data assuming that intervals are in the milliseconds.","use-message-alarm-data":"Use message alarm data","overwrite-alarm-details":"Overwrite alarm details","use-alarm-severity-pattern":"Use alarm severity pattern","check-all-keys":"Check that all specified fields are present","check-all-keys-hint":"If selected, checks that all specified keys are present in the message data and metadata.","check-relation-to-specific-entity":"Check relation to specific entity","check-relation-to-specific-entity-tooltip":"If enabled, checks the presence of relation with a specific entity otherwise, checks the presence of relation with any entity. In both cases, relation lookup is based on configured direction and type.","check-relation-hint":"Checks existence of relation to specific entity or to any entity based on direction and relation type.","delete-relation-to-specific-entity":"Delete relation to specific entity","delete-relation-hint":"Deletes relation from the originator of the incoming message to the specified entity or list of entities based on direction and type.","remove-current-relations":"Remove current relations","remove-current-relations-hint":"Removes current relations from the originator of the incoming message based on direction and type.","change-originator-to-related-entity":"Change originator to related entity","change-originator-to-related-entity-hint":"Used to process submitted message as a message from another entity.","start-interval":"Interval start","end-interval":"Interval end","start-interval-required":"Interval start is required.","end-interval-required":"Interval end is required.","smtp-protocol":"Protocol","smtp-host":"SMTP host","smtp-host-required":"SMTP host is required.","smtp-port":"SMTP port","smtp-port-required":"You must supply a smtp port.","smtp-port-range":"SMTP port should be in a range from 1 to 65535.","timeout-msec":"Timeout ms","min-timeout-msec-message":"Only 0 ms minimum value is allowed.","enter-username":"Enter username","enter-password":"Enter password","enable-tls":"Enable TLS","tls-version":"TLS version","enable-proxy":"Enable proxy","use-system-proxy-properties":"Use system proxy properties","proxy-host":"Proxy host","proxy-host-required":"Proxy host is required.","proxy-port":"Proxy port","proxy-port-required":"Proxy port is required.","proxy-port-range":"Proxy port should be in a range from 1 to 65535.","proxy-user":"Proxy user","proxy-password":"Proxy password","proxy-scheme":"Proxy scheme","numbers-to-template":"Phone Numbers To Template","numbers-to-template-required":"Phone Numbers To Template is required","numbers-to-template-hint":'Comma separated Phone Numbers, use ${metadataKey} for value from metadata, $[messageKey] for value from message body',"sms-message-template":"SMS message Template","sms-message-template-required":"SMS message Template is required","use-system-sms-settings":"Use system SMS provider settings","min-period-0-seconds-message":"Only 0 second minimum period is allowed.","max-pending-messages":"Maximum pending messages","max-pending-messages-required":"Maximum pending messages is required.","max-pending-messages-range":"Maximum pending messages should be in a range from 1 to 100000.","originator-types-filter":"Originator types filter","interval-seconds":"Interval in seconds","interval-seconds-required":"Interval is required.","min-interval-seconds-message":"Only 1 second minimum interval is allowed.","output-timeseries-key-prefix":"Output timeseries key prefix","output-timeseries-key-prefix-required":"Output timeseries key prefix required.","separator-hint":'Press "Enter" to complete field input.',"select-details":"Select details","entity-details-id":"Id","entity-details-title":"Title","entity-details-country":"Country","entity-details-state":"State","entity-details-city":"City","entity-details-zip":"Zip","entity-details-address":"Address","entity-details-address2":"Address2","entity-details-additional_info":"Additional Info","entity-details-phone":"Phone","entity-details-email":"Email","email-sender":"Email sender","fields-to-check":"Fields to check","add-detail":"Add detail","check-all-keys-tooltip":"If enabled, checks the presence of all fields listed in the message and metadata field names within the incoming message and its metadata.","fields-to-check-hint":'Press "Enter" to complete field name input. Multiple field names supported.',"entity-details-list-empty":"At least one detail should be selected.","alarm-status":"Alarm status","alarm-required":"At least one alarm status should be selected.","no-entity-details-matching":"No entity details matching were found.","custom-table-name":"Custom table name","custom-table-name-required":"Table Name is required","custom-table-hint":"Enter the table name without prefix 'cs_tb_'.","message-field":"Message field","message-field-required":"Message field is required.","table-col":"Table column","table-col-required":"Table column is required.","latitude-field-name":"Latitude field name","longitude-field-name":"Longitude field name","latitude-field-name-required":"Latitude field name is required.","longitude-field-name-required":"Longitude field name is required.","fetch-perimeter-info-from-metadata":"Fetch perimeter information from metadata","fetch-perimeter-info-from-metadata-tooltip":"If perimeter type is set to 'Polygon' the value of metadata field '{{perimeterKeyName}}' will be set as perimeter definition without additional parsing of the value. Otherwise, if perimeter type is set to 'Circle' the value of '{{perimeterKeyName}}' metadata field will be parsed to extract 'latitude', 'longitude', 'radius', 'radiusUnit' fields that uses for circle perimeter definition.","perimeter-key-name":"Perimeter key name","perimeter-key-name-hint":"Metadata field name that includes perimeter information.","perimeter-key-name-required":"Perimeter key name is required.","perimeter-circle":"Circle","perimeter-polygon":"Polygon","perimeter-type":"Perimeter type","circle-center-latitude":"Center latitude","circle-center-latitude-required":"Center latitude is required.","circle-center-longitude":"Center longitude","circle-center-longitude-required":"Center longitude is required.","range-unit-meter":"Meter","range-unit-kilometer":"Kilometer","range-unit-foot":"Foot","range-unit-mile":"Mile","range-unit-nautical-mile":"Nautical mile","range-units":"Range units","range-units-required":"Range units is required.",range:"Range","range-required":"Range is required.","polygon-definition":"Polygon definition","polygon-definition-required":"Polygon definition is required.","polygon-definition-hint":"Use the following format for manual definition of polygon: [[lat1,lon1],[lat2,lon2], ... ,[latN,lonN]].","min-inside-duration":"Minimal inside duration","min-inside-duration-value-required":"Minimal inside duration is required","min-inside-duration-time-unit":"Minimal inside duration time unit","min-outside-duration":"Minimal outside duration","min-outside-duration-value-required":"Minimal outside duration is required","min-outside-duration-time-unit":"Minimal outside duration time unit","tell-failure-if-absent":"Tell Failure","tell-failure-if-absent-hint":'If at least one selected key doesn\'t exist the outbound message will report "Failure".',"get-latest-value-with-ts":"Fetch timestamp for the latest telemetry values","get-latest-value-with-ts-hint":'If selected, the latest telemetry values will also include timestamp, e.g: "temp": "{"ts":1574329385897, "value":42}"',"use-redis-queue":"Use redis queue for message persistence","ignore-null-strings":"Ignore null strings","ignore-null-strings-hint":"If selected rule node will ignore entity fields with empty value.","trim-redis-queue":"Trim redis queue","redis-queue-max-size":"Redis queue max size","add-metadata-key-values-as-kafka-headers":"Add Message metadata key-value pairs to Kafka record headers","add-metadata-key-values-as-kafka-headers-hint":"If selected, key-value pairs from message metadata will be added to the outgoing records headers as byte arrays with predefined charset encoding.","charset-encoding":"Charset encoding","charset-encoding-required":"Charset encoding is required.","charset-us-ascii":"US-ASCII","charset-iso-8859-1":"ISO-8859-1","charset-utf-8":"UTF-8","charset-utf-16be":"UTF-16BE","charset-utf-16le":"UTF-16LE","charset-utf-16":"UTF-16","select-queue-hint":"The queue name can be selected from a drop-down list or add a custom name.","persist-alarm-rules":"Persist state of alarm rules","fetch-alarm-rules":"Fetch state of alarm rules","input-value-key":"Input value key","input-value-key-required":"Input value key is required.","output-value-key":"Output value key","output-value-key-required":"Output value key is required.","number-of-digits-after-floating-point":"Number of digits after floating point","number-of-digits-after-floating-point-range":"Number of digits after floating point should be in a range from 0 to 15.","failure-if-delta-negative":"Tell Failure if delta is negative","failure-if-delta-negative-tooltip":"Rule node forces failure of message processing if delta value is negative.","use-caching":"Use caching","use-caching-tooltip":'Rule node will cache the value of "{{inputValueKey}}" that arrives from the incoming message to improve performance. Note that the cache will not be updated if you modify the "{{inputValueKey}}" value elsewhere.',"add-time-difference-between-readings":'Add the time difference between "{{inputValueKey}}" readings',"add-time-difference-between-readings-tooltip":'If enabled, the rule node will add the "{{periodValueKey}}" to the outbound message.',"period-value-key":"Period value key","period-value-key-required":"Period value key is required.","general-pattern-hint":"Use ${metadataKey} for value from metadata, $[messageKey] for value from message body.","alarm-severity-pattern-hint":'Use ${metadataKey} for value from metadata, $[messageKey] for value from message body. Alarm severity should be system (CRITICAL, MAJOR etc.)',"output-node-name-hint":"The rule node name corresponds to the relation type of the output message, and it is used to forward messages to other rule nodes in the caller rule chain.","skip-latest-persistence":"Skip latest persistence","use-server-ts":"Use server ts","use-server-ts-hint":"Enable this setting to use the timestamp of the message processing instead of the timestamp from the message. Useful for all sorts of sequential processing if you merge messages from multiple sources (devices, assets, etc).","kv-map-pattern-hint":"All input fields support templatization. Use $[messageKey] to extract value from the message and ${metadataKey} to extract value from the metadata.","shared-scope":"Shared scope","server-scope":"Server scope","client-scope":"Client scope","attribute-type":"Attribute","constant-type":"Constant","time-series-type":"Time-series","message-body-type":"Message","message-metadata-type":"Metadata","argument-tile":"Arguments","no-arguments-prompt":"No arguments configured","result-title":"Result","functions-field-input":"Functions","no-option-found":"No option found","argument-source-field-input":"Source","argument-source-field-input-required":"Argument source is required.","argument-key-field-input":"Key","argument-key-field-input-required":"Argument key is required.","constant-value-field-input":"Constant value","constant-value-field-input-required":"Constant value is required.","attribute-scope-field-input":"Attribute scope","attribute-scope-field-input-required":"Attribute scope os required.","default-value-field-input":"Default value","type-field-input":"Type","type-field-input-required":"Type is required.","key-field-input":"Key","add-entity-type":"Add entity type","add-device-profile":"Add device profile","key-field-input-required":"Key is required.","number-floating-point-field-input":"Number of digits after floating point","number-floating-point-field-input-hint":"Use 0 to convert result to integer","add-to-message-field-input":"Add to message","add-to-metadata-field-input":"Add to metadata","custom-expression-field-input":"Mathematical Expression","custom-expression-field-input-required":"Mathematical expression is required","custom-expression-field-input-hint":"Specify a mathematical expression to evaluate. Default expression demonstrates how to transform Fahrenheit to Celsius","retained-message":"Retained","attributes-mapping":"Attributes mapping","latest-telemetry-mapping":"Latest telemetry mapping","add-mapped-attribute-to":"Add mapped attributes to","add-mapped-latest-telemetry-to":"Add mapped latest telemetry to","add-mapped-fields-to":"Add mapped fields to","add-selected-details-to":"Add selected details to","clear-selected-types":"Clear selected types","clear-selected-details":"Clear selected details","clear-selected-fields":"Clear selected fields","clear-selected-keys":"Clear selected keys","geofence-configuration":"Geofence configuration","coordinate-field-names":"Coordinate field names","coordinate-field-hint":"Rule node tries to retrieve the specified fields from the message. If they are not present, it will look them up in the metadata.","fetch-credentials-to":"Fetch credentials to","add-originator-attributes-to":"Add originator attributes to","originator-attributes":"Originator attributes","fetch-latest-telemetry-with-timestamp":"Fetch latest telemetry with timestamp","fetch-latest-telemetry-with-timestamp-tooltip":'If selected, latest telemetry values will be added to the outbound metadata with timestamp, e.g: "{{latestTsKeyName}}": "{"ts":1574329385897, "value":42}"',"tell-failure":"Tell failure if any of the attributes are missing","tell-failure-tooltip":'If at least one selected key doesn\'t exist the outbound message will report "Failure".',"created-time":"Created time","chip-help":"Press 'Enter' to complete {{inputName}} input. \nPress 'Backspace' to delete {{inputName}}. \nMultiple values supported.",detail:"detail","field-name":"field name","device-profile":"device profile","entity-type":"entity type","message-type":"message type","timeseries-key":"timeseries key",type:"Type","first-name":"First name","last-name":"Last name",label:"Label","originator-fields-mapping":"Originator fields mapping","add-mapped-originator-fields-to":"Add mapped originator fields to",fields:"Fields","skip-empty-fields":"Skip empty fields","skip-empty-fields-tooltip":"Fields with empty values will not be added to the output message/output metadata.","fetch-interval":"Fetch interval","fetch-strategy":"Fetch strategy","fetch-timeseries-from-to":"Fetch timeseries from {{startInterval}} {{startIntervalTimeUnit}} ago to {{endInterval}} {{endIntervalTimeUnit}} ago.","fetch-timeseries-from-to-invalid":'Fetch timeseries invalid ("Interval start" should be less than "Interval end").',"use-metadata-dynamic-interval-tooltip":"If selected, the rule node will use dynamic interval start and end based on the message and metadata patterns.","all-mode-hint":'If selected fetch mode "All" rule node will retrieve telemetry from the fetch interval with configurable query parameters.',"first-mode-hint":'If selected fetch mode "First" rule node will retrieve the closest telemetry to the fetch interval\'s start.',"last-mode-hint":'If selected fetch mode "Last" rule node will retrieve the closest telemetry to the fetch interval\'s end.',ascending:"Ascending",descending:"Descending",min:"Min",max:"Max",average:"Average",sum:"Sum",count:"Count",none:"None","last-level-relation-tooltip":"If selected, the rule node will search related entities only on the level set in the max relation level.","last-level-device-relation-tooltip":"If selected, the rule node will search related devices only on the level set in the max relation level.","data-to-fetch":"Data to fetch","mapping-of-customers":"Mapping of customer's","map-fields-required":"All mapping fields are required.",attributes:"Attributes","related-device-attributes":"Related device attributes","add-selected-attributes-to":"Add selected attributes to","device-profiles":"Device profiles","mapping-of-tenant":"Mapping of tenant's","add-attribute-key":"Add attribute key","message-template":"Message template","message-template-required":"Message template is required","use-system-slack-settings":"Use system slack settings","slack-api-token":"Slack API token","slack-api-token-required":"Slack API token is required","keys-mapping":"keys mapping","add-key":"Add key",recipients:"Recipients","message-subject-and-content":"Message subject and content","template-rules-hint":"Both input fields support templatization. Use $[messageKey] to extract value from the message and ${metadataKey} to extract value from the metadata.","originator-customer-desc":"Use customer of incoming message originator as new originator.","originator-tenant-desc":"Use current tenant as new originator.","originator-related-entity-desc":"Use related entity as new originator. Lookup based on configured relation type and direction.","originator-alarm-originator-desc":"Use alarm originator as new originator. Only if incoming message originator is alarm entity.","originator-entity-by-name-pattern-desc":"Use entity fetched from DB as new originator. Lookup based on entity type and specified name pattern.","email-from-template-hint":"Use $[messageKey] to extract value from the message and ${metadataKey} to extract value from the metadata.","recipients-block-main-hint":"Comma-separated address list. All input fields support templatization. Use $[messageKey] to extract value from the message and ${metadataKey} to extract value from the metadata."},"key-val":{key:"Key",value:"Value","see-examples":"See examples.","remove-entry":"Remove entry","remove-mapping-entry":"Remove mapping entry","add-mapping-entry":"Add mapping","add-entry":"Add entry","copy-key-values-from":"Copy key-values from","delete-key-values":"Delete key-values","delete-key-values-from":"Delete key-values from","at-least-one-key-error":"At least one key should be selected.","unique-key-value-pair-error":"'{{keyText}}' must be different from the '{{valText}}'!"},"mail-body-type":{"plain-text":"Plain text",html:"HTML",dynamic:"Dynamic","use-body-type-template":"Use body type template","plain-text-description":"Simple, unformatted text with no special styling or formating.","html-text-description":"Allows you to use HTML tags for formatting, links and images in your mai body.","dynamic-text-description":"Allows to use Plain Text or HTML body type dynamically based on templatization feature.","after-template-evaluation-hint":"After template evaluation value should be true for HTML, and false for Plain text."}}},!0)}(e)}}e("RuleNodeCoreConfigModule",Hr),Hr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Hr,deps:[{token:X.TranslateService}],target:t.ɵɵFactoryTarget.NgModule}),Hr.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.10",ngImport:t,type:Hr,declarations:[ct],imports:[Q,E],exports:[Qn,Nr,ar,br,Br,Ur,ct]}),Hr.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Hr,imports:[Q,E,Qn,Nr,ar,br,Br,Ur]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Hr,decorators:[{type:c,args:[{declarations:[ct],imports:[Q,E],exports:[Qn,Nr,ar,br,Br,Ur,ct]}]}],ctorParameters:function(){return[{type:X.TranslateService}]}})}}}));//# sourceMappingURL=rulenode-core-config.js.map +System.register(["@angular/core","@shared/public-api","@ngrx/store","@angular/forms","@angular/common","@angular/material/checkbox","@angular/material/input","@angular/material/form-field","@angular/flex-layout/flex","@ngx-translate/core","@angular/material/select","@angular/material/core","@angular/material/slide-toggle","@shared/components/hint-tooltip-icon.component","@core/public-api","@shared/components/js-func.component","@angular/material/button","@angular/material/icon","@angular/material/tooltip","@shared/components/script-lang.component","@angular/cdk/keycodes","@angular/material/chips","@shared/pipe/safe.pipe","@shared/components/entity/entity-type-select.component","@shared/components/entity/entity-select.component","@angular/cdk/coercion","@shared/components/tb-error.component","@angular/flex-layout/extended","@angular/material/list","@angular/cdk/drag-drop","rxjs/operators","@angular/material/autocomplete","@shared/pipe/highlight.pipe","@home/components/public-api","tslib","rxjs","@shared/components/help-popup.component","@shared/components/entity/entity-subtype-list.component","@shared/components/relation/relation-type-autocomplete.component","@home/components/relation/relation-filters.component","@angular/material/expansion","@shared/components/file-input.component","@shared/components/button/toggle-password.component","@shared/components/string-items-list.component","@shared/components/toggle-header.component","@shared/components/toggle-select.component","@shared/components/entity/entity-list.component","@shared/components/notification/template-autocomplete.component","@shared/components/tb-checkbox.component","@home/components/sms/sms-provider-configuration.component","@angular/material/radio","@shared/components/slack-conversation-autocomplete.component","@shared/components/entity/entity-autocomplete.component","@shared/components/entity/entity-type-list.component","@angular/cdk/platform"],(function(e){"use strict";var t,n,r,o,a,i,l,s,m,p,d,u,c,f,g,y,x,b,h,v,C,F,k,L,T,I,N,S,q,A,M,E,G,D,w,V,P,R,O,_,B,K,z,U,H,j,$,Q,J,Y,W,Z,X,ee,te,ne,re,oe,ae,ie,le,se,me,pe,de,ue,ce,fe,ge,ye,xe,be,he,ve,Ce,Fe,ke,Le,Te,Ie,Ne,Se,qe,Ae,Me,Ee,Ge,De,we,Ve,Pe,Re,Oe,_e,Be,Ke,ze,Ue,He,je,$e,Qe,Je,Ye,We,Ze,Xe,et,tt,nt,rt,ot,at,it,lt,st,mt,pt;return{setters:[function(e){t=e,n=e.Component,r=e.EventEmitter,o=e.ViewChild,a=e.forwardRef,i=e.Input,l=e.InjectionToken,s=e.Injectable,m=e.Inject,p=e.Optional,d=e.Directive,u=e.Output,c=e.NgModule},function(e){f=e.RuleNodeConfigurationComponent,g=e.AttributeScope,y=e.telemetryTypeTranslations,x=e.ScriptLanguage,b=e.AlarmSeverity,h=e.alarmSeverityTranslations,v=e.EntitySearchDirection,C=e.entitySearchDirectionTranslations,F=e.EntityType,k=e.entityFields,L=e.PageComponent,T=e.coerceBoolean,I=e.MessageType,N=e.messageTypeNames,S=e,q=e.AlarmStatus,A=e.alarmStatusTranslations,M=e.SharedModule,E=e.AggregationType,G=e.aggregationTranslations,D=e.NotificationType,w=e.SlackChanelType,V=e.SlackChanelTypesTranslateMap},function(e){P=e},function(e){R=e,O=e.Validators,_=e.NgControl,B=e.NG_VALUE_ACCESSOR,K=e.NG_VALIDATORS,z=e.FormArray,U=e.FormGroup},function(e){H=e,j=e.DOCUMENT,$=e.CommonModule},function(e){Q=e},function(e){J=e},function(e){Y=e},function(e){W=e},function(e){Z=e},function(e){X=e},function(e){ee=e},function(e){te=e},function(e){ne=e},function(e){re=e.getCurrentAuthState,oe=e,ae=e.isEqual,ie=e.isDefinedAndNotNull,le=e.deepTrim,se=e.isObject,me=e.isNotEmptyStr},function(e){pe=e},function(e){de=e},function(e){ue=e},function(e){ce=e},function(e){fe=e},function(e){ge=e.ENTER,ye=e.COMMA,xe=e.SEMICOLON},function(e){be=e},function(e){he=e},function(e){ve=e},function(e){Ce=e},function(e){Fe=e.coerceBooleanProperty,ke=e.coerceElement,Le=e.coerceNumberProperty},function(e){Te=e},function(e){Ie=e},function(e){Ne=e},function(e){Se=e},function(e){qe=e.tap,Ae=e.map,Me=e.startWith,Ee=e.mergeMap,Ge=e.share,De=e.takeUntil,we=e.auditTime},function(e){Ve=e},function(e){Pe=e},function(e){Re=e.HomeComponentsModule},function(e){Oe=e.__decorate},function(e){_e=e.Subject,Be=e.takeUntil,Ke=e.of,ze=e.EMPTY,Ue=e.fromEvent},function(e){He=e},function(e){je=e},function(e){$e=e},function(e){Qe=e},function(e){Je=e},function(e){Ye=e},function(e){We=e},function(e){Ze=e},function(e){Xe=e},function(e){et=e},function(e){tt=e},function(e){nt=e},function(e){rt=e},function(e){ot=e},function(e){at=e},function(e){it=e},function(e){lt=e},function(e){st=e},function(e){mt=e.normalizePassiveListenerOptions,pt=e}],execute:function(){class dt extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.emptyConfigForm}onConfigurationSet(e){this.emptyConfigForm=this.fb.group({})}}e("EmptyConfigComponent",dt),dt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:dt,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),dt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:dt,selector:"tb-node-empty-config",usesInheritance:!0,ngImport:t,template:"
",isInline:!0}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:dt,decorators:[{type:n,args:[{selector:"tb-node-empty-config",template:"
"}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class ut extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.assignCustomerConfigForm}onConfigurationSet(e){this.assignCustomerConfigForm=this.fb.group({customerNamePattern:[e?e.customerNamePattern:null,[O.required,O.pattern(/.*\S.*/)]],createCustomerIfNotExists:[!!e&&e.createCustomerIfNotExists,[]],customerCacheExpiration:[e?e.customerCacheExpiration:null,[O.required,O.min(0)]]})}prepareOutputConfig(e){return e.customerNamePattern=e.customerNamePattern.trim(),e}}e("AssignCustomerConfigComponent",ut),ut.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ut,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),ut.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:ut,selector:"tb-action-node-assign-to-customer-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.customer-name-pattern\n \n \n {{ \'tb.rulenode.customer-name-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n {{ \'tb.rulenode.create-customer-if-not-exists\' | translate }}\n \n \n tb.rulenode.customer-cache-expiration\n \n \n {{ \'tb.rulenode.customer-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.customer-cache-expiration-range\' | translate }}\n \n tb.rulenode.customer-cache-expiration-hint\n \n
\n',dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Q.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ut,decorators:[{type:n,args:[{selector:"tb-action-node-assign-to-customer-config",template:'
\n \n tb.rulenode.customer-name-pattern\n \n \n {{ \'tb.rulenode.customer-name-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n {{ \'tb.rulenode.create-customer-if-not-exists\' | translate }}\n \n \n tb.rulenode.customer-cache-expiration\n \n \n {{ \'tb.rulenode.customer-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.customer-cache-expiration-range\' | translate }}\n \n tb.rulenode.customer-cache-expiration-hint\n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class ct extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.attributeScopeMap=g,this.attributeScopes=Object.keys(g),this.telemetryTypeTranslationsMap=y}configForm(){return this.attributesConfigForm}onConfigurationSet(e){this.attributesConfigForm=this.fb.group({scope:[e?e.scope:null,[O.required]],notifyDevice:[!e||e.notifyDevice,[]],sendAttributesUpdatedNotification:[!!e&&e.sendAttributesUpdatedNotification,[]],updateAttributesOnlyOnValueChange:[!!e&&e.updateAttributesOnlyOnValueChange,[]]}),this.attributesConfigForm.get("scope").valueChanges.subscribe((e=>{e!==g.SHARED_SCOPE&&this.attributesConfigForm.get("notifyDevice").patchValue(!1,{emitEvent:!1}),e===g.CLIENT_SCOPE&&this.attributesConfigForm.get("sendAttributesUpdatedNotification").patchValue(!1,{emitEvent:!1}),this.attributesConfigForm.get("updateAttributesOnlyOnValueChange").patchValue(!1,{emitEvent:!1})}))}}e("AttributesConfigComponent",ct),ct.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ct,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),ct.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:ct,selector:"tb-action-node-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n
\n \n {{ \'tb.rulenode.update-attributes-only-on-value-change\' | translate }}\n \n
\n
\n \n {{ \'tb.rulenode.send-attributes-updated-notification\' | translate }}\n \n
\n
\n \n {{ \'tb.rulenode.notify-device\' | translate }}\n \n
\n
\n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:te.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:ne.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ct,decorators:[{type:n,args:[{selector:"tb-action-node-attributes-config",template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n
\n \n {{ \'tb.rulenode.update-attributes-only-on-value-change\' | translate }}\n \n
\n
\n \n {{ \'tb.rulenode.send-attributes-updated-notification\' | translate }}\n \n
\n
\n \n {{ \'tb.rulenode.notify-device\' | translate }}\n \n
\n
\n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class ft extends f{constructor(e,t,n,o){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=n,this.translate=o,this.tbelEnabled=re(this.store).tbelEnabled,this.scriptLanguage=x,this.changeScript=new r,this.hasScript=!0,this.testScriptLabel="tb.rulenode.test-details-function"}configForm(){return this.clearAlarmConfigForm}onConfigurationSet(e){this.clearAlarmConfigForm=this.fb.group({scriptLang:[e?e.scriptLang:x.JS,[O.required]],alarmDetailsBuildJs:[e?e.alarmDetailsBuildJs:null,[]],alarmDetailsBuildTbel:[e?e.alarmDetailsBuildTbel:null,[]],alarmType:[e?e.alarmType:null,[O.required]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.clearAlarmConfigForm.get("scriptLang").value;t!==x.TBEL||this.tbelEnabled||(t=x.JS,this.clearAlarmConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.clearAlarmConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.clearAlarmConfigForm.get("alarmDetailsBuildJs").setValidators(t===x.JS?[O.required]:[]),this.clearAlarmConfigForm.get("alarmDetailsBuildJs").updateValueAndValidity({emitEvent:e}),this.clearAlarmConfigForm.get("alarmDetailsBuildTbel").setValidators(t===x.TBEL?[O.required]:[]),this.clearAlarmConfigForm.get("alarmDetailsBuildTbel").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=x.JS)),e}testScript(e){const t=this.clearAlarmConfigForm.get("scriptLang").value,n=t===x.JS?"alarmDetailsBuildJs":"alarmDetailsBuildTbel",r=t===x.JS?"rulenode/clear_alarm_node_script_fn":"rulenode/tbel/clear_alarm_node_script_fn",o=this.clearAlarmConfigForm.get(n).value;this.nodeScriptTestService.testNodeScript(o,"json",this.translate.instant("tb.rulenode.details"),"Details",["msg","metadata","msgType"],this.ruleNodeId,r,t,e).subscribe((e=>{e&&(this.clearAlarmConfigForm.get(n).setValue(e),this.changeScript.emit())}))}onValidate(){this.clearAlarmConfigForm.get("scriptLang").value===x.JS&&this.jsFuncComponent.validateOnSubmit()}}e("ClearAlarmConfigComponent",ft),ft.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ft,deps:[{token:P.Store},{token:R.UntypedFormBuilder},{token:oe.NodeScriptTestService},{token:Z.TranslateService}],target:t.ɵɵFactoryTarget.Component}),ft.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:ft,selector:"tb-action-node-clear-alarm-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n \n \n
\n \n
\n \n tb.rulenode.alarm-type\n \n \n {{ \'tb.rulenode.alarm-type-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n
\n',dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:pe.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:de.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:de.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:fe.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ft,decorators:[{type:n,args:[{selector:"tb-action-node-clear-alarm-config",template:'
\n \n \n \n \n \n \n \n
\n \n
\n \n tb.rulenode.alarm-type\n \n \n {{ \'tb.rulenode.alarm-type-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder},{type:oe.NodeScriptTestService},{type:Z.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}});class gt extends f{constructor(e,t,n,o){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=n,this.translate=o,this.alarmSeverities=Object.keys(b),this.alarmSeverityTranslationMap=h,this.separatorKeysCodes=[ge,ye,xe],this.tbelEnabled=re(this.store).tbelEnabled,this.scriptLanguage=x,this.changeScript=new r,this.hasScript=!0,this.testScriptLabel="tb.rulenode.test-details-function"}configForm(){return this.createAlarmConfigForm}onConfigurationSet(e){this.createAlarmConfigForm=this.fb.group({scriptLang:[e?e.scriptLang:x.JS,[O.required]],alarmDetailsBuildJs:[e?e.alarmDetailsBuildJs:null,[]],alarmDetailsBuildTbel:[e?e.alarmDetailsBuildTbel:null,[]],useMessageAlarmData:[!!e&&e.useMessageAlarmData,[]],overwriteAlarmDetails:[!!e&&e.overwriteAlarmDetails,[]],alarmType:[e?e.alarmType:null,[]],severity:[e?e.severity:null,[]],propagate:[!!e&&e.propagate,[]],relationTypes:[e?e.relationTypes:null,[]],propagateToOwner:[!!e&&e.propagateToOwner,[]],propagateToTenant:[!!e&&e.propagateToTenant,[]],dynamicSeverity:!1}),this.createAlarmConfigForm.get("dynamicSeverity").valueChanges.subscribe((e=>{e?this.createAlarmConfigForm.get("severity").patchValue("",{emitEvent:!1}):this.createAlarmConfigForm.get("severity").patchValue(this.alarmSeverities[0],{emitEvent:!1})}))}validatorTriggers(){return["useMessageAlarmData","overwriteAlarmDetails","scriptLang"]}updateValidators(e){const t=this.createAlarmConfigForm.get("useMessageAlarmData").value,n=this.createAlarmConfigForm.get("overwriteAlarmDetails").value;t?(this.createAlarmConfigForm.get("alarmType").setValidators([]),this.createAlarmConfigForm.get("severity").setValidators([])):(this.createAlarmConfigForm.get("alarmType").setValidators([O.required]),this.createAlarmConfigForm.get("severity").setValidators([O.required])),this.createAlarmConfigForm.get("alarmType").updateValueAndValidity({emitEvent:e}),this.createAlarmConfigForm.get("severity").updateValueAndValidity({emitEvent:e});let r=this.createAlarmConfigForm.get("scriptLang").value;r!==x.TBEL||this.tbelEnabled||(r=x.JS,this.createAlarmConfigForm.get("scriptLang").patchValue(r,{emitEvent:!1}),setTimeout((()=>{this.createAlarmConfigForm.updateValueAndValidity({emitEvent:!0})})));const o=!1===t||!0===n;this.createAlarmConfigForm.get("alarmDetailsBuildJs").setValidators(o&&r===x.JS?[O.required]:[]),this.createAlarmConfigForm.get("alarmDetailsBuildTbel").setValidators(o&&r===x.TBEL?[O.required]:[]),this.createAlarmConfigForm.get("alarmDetailsBuildJs").updateValueAndValidity({emitEvent:e}),this.createAlarmConfigForm.get("alarmDetailsBuildTbel").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=x.JS)),e}testScript(e){const t=this.createAlarmConfigForm.get("scriptLang").value,n=t===x.JS?"alarmDetailsBuildJs":"alarmDetailsBuildTbel",r=t===x.JS?"rulenode/create_alarm_node_script_fn":"rulenode/tbel/create_alarm_node_script_fn",o=this.createAlarmConfigForm.get(n).value;this.nodeScriptTestService.testNodeScript(o,"json",this.translate.instant("tb.rulenode.details"),"Details",["msg","metadata","msgType"],this.ruleNodeId,r,t,e).subscribe((e=>{e&&(this.createAlarmConfigForm.get(n).setValue(e),this.changeScript.emit())}))}removeKey(e,t){const n=this.createAlarmConfigForm.get(t).value,r=n.indexOf(e);r>=0&&(n.splice(r,1),this.createAlarmConfigForm.get(t).setValue(n,{emitEvent:!0}))}addKey(e,t){const n=e.input;let r=e.value;if((r||"").trim()){r=r.trim();let e=this.createAlarmConfigForm.get(t).value;e&&-1!==e.indexOf(r)||(e||(e=[]),e.push(r),this.createAlarmConfigForm.get(t).setValue(e,{emitEvent:!0}))}n&&(n.value="")}onValidate(){const e=this.createAlarmConfigForm.get("useMessageAlarmData").value,t=this.createAlarmConfigForm.get("overwriteAlarmDetails").value;if(!e||t){this.createAlarmConfigForm.get("scriptLang").value===x.JS&&this.jsFuncComponent.validateOnSubmit()}}}e("CreateAlarmConfigComponent",gt),gt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:gt,deps:[{token:P.Store},{token:R.UntypedFormBuilder},{token:oe.NodeScriptTestService},{token:Z.TranslateService}],target:t.ɵɵFactoryTarget.Component}),gt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:gt,selector:"tb-action-node-create-alarm-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.use-message-alarm-data\' | translate }}\n \n \n {{ \'tb.rulenode.overwrite-alarm-details\' | translate }}\n \n
\n \n \n \n \n \n \n \n
\n \n
\n
\n
\n \n tb.rulenode.alarm-type\n \n \n {{ \'tb.rulenode.alarm-type-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n {{ \'tb.rulenode.use-alarm-severity-pattern\' | translate }}\n \n \n tb.rulenode.alarm-severity\n \n \n {{ alarmSeverityTranslationMap.get(severity) | translate }}\n \n \n \n {{ \'tb.rulenode.alarm-severity-required\' | translate }}\n \n \n \n tb.rulenode.alarm-severity-pattern\n \n \n {{ \'tb.rulenode.alarm-severity-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.propagate\' | translate }}\n \n
\n \n tb.rulenode.relation-types-list\n \n \n {{key}}\n close\n \n \n \n tb.rulenode.relation-types-list-hint\n \n
\n \n {{ \'tb.rulenode.propagate-to-owner\' | translate }}\n \n \n {{ \'tb.rulenode.propagate-to-tenant\' | translate }}\n \n
\n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:pe.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:de.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:de.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:Q.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:be.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:be.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:be.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:be.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:fe.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:he.SafePipe,name:"safe"},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:gt,decorators:[{type:n,args:[{selector:"tb-action-node-create-alarm-config",template:'
\n \n {{ \'tb.rulenode.use-message-alarm-data\' | translate }}\n \n \n {{ \'tb.rulenode.overwrite-alarm-details\' | translate }}\n \n
\n \n \n \n \n \n \n \n
\n \n
\n
\n
\n \n tb.rulenode.alarm-type\n \n \n {{ \'tb.rulenode.alarm-type-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n {{ \'tb.rulenode.use-alarm-severity-pattern\' | translate }}\n \n \n tb.rulenode.alarm-severity\n \n \n {{ alarmSeverityTranslationMap.get(severity) | translate }}\n \n \n \n {{ \'tb.rulenode.alarm-severity-required\' | translate }}\n \n \n \n tb.rulenode.alarm-severity-pattern\n \n \n {{ \'tb.rulenode.alarm-severity-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.propagate\' | translate }}\n \n
\n \n tb.rulenode.relation-types-list\n \n \n {{key}}\n close\n \n \n \n tb.rulenode.relation-types-list-hint\n \n
\n \n {{ \'tb.rulenode.propagate-to-owner\' | translate }}\n \n \n {{ \'tb.rulenode.propagate-to-tenant\' | translate }}\n \n
\n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder},{type:oe.NodeScriptTestService},{type:Z.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}});class yt extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.directionTypes=Object.keys(v),this.directionTypeTranslations=C,this.entityType=F}configForm(){return this.createRelationConfigForm}onConfigurationSet(e){this.createRelationConfigForm=this.fb.group({direction:[e?e.direction:null,[O.required]],entityType:[e?e.entityType:null,[O.required]],entityNamePattern:[e?e.entityNamePattern:null,[]],entityTypePattern:[e?e.entityTypePattern:null,[]],relationType:[e?e.relationType:null,[O.required]],createEntityIfNotExists:[!!e&&e.createEntityIfNotExists,[]],removeCurrentRelations:[!!e&&e.removeCurrentRelations,[]],changeOriginatorToRelatedEntity:[!!e&&e.changeOriginatorToRelatedEntity,[]],entityCacheExpiration:[e?e.entityCacheExpiration:null,[O.required,O.min(0)]]})}validatorTriggers(){return["entityType"]}updateValidators(e){const t=this.createRelationConfigForm.get("entityType").value;t?this.createRelationConfigForm.get("entityNamePattern").setValidators([O.required,O.pattern(/.*\S.*/)]):this.createRelationConfigForm.get("entityNamePattern").setValidators([]),!t||t!==F.DEVICE&&t!==F.ASSET?this.createRelationConfigForm.get("entityTypePattern").setValidators([]):this.createRelationConfigForm.get("entityTypePattern").setValidators([O.required,O.pattern(/.*\S.*/)]),this.createRelationConfigForm.get("entityNamePattern").updateValueAndValidity({emitEvent:e}),this.createRelationConfigForm.get("entityTypePattern").updateValueAndValidity({emitEvent:e})}prepareOutputConfig(e){return e.entityNamePattern=e.entityNamePattern?e.entityNamePattern.trim():null,e.entityTypePattern=e.entityTypePattern?e.entityTypePattern.trim():null,e}}e("CreateRelationConfigComponent",yt),yt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:yt,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),yt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:yt,selector:"tb-action-node-create-relation-config",usesInheritance:!0,ngImport:t,template:'
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.entity-type-pattern\n \n \n {{ \'tb.rulenode.entity-type-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n
\n \n tb.rulenode.relation-type-pattern\n \n \n {{ \'tb.rulenode.relation-type-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n
\n \n {{ \'tb.rulenode.create-entity-if-not-exists\' | translate }}\n \n
tb.rulenode.create-entity-if-not-exists-hint
\n
\n \n {{ \'tb.rulenode.remove-current-relations\' | translate }}\n \n
tb.rulenode.remove-current-relations-hint
\n \n {{ \'tb.rulenode.change-originator-to-related-entity\' | translate }}\n \n
tb.rulenode.change-originator-to-related-entity-hint
\n \n tb.rulenode.entity-cache-expiration\n \n \n {{ \'tb.rulenode.entity-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.entity-cache-expiration-range\' | translate }}\n \n tb.rulenode.entity-cache-expiration-hint\n \n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ve.EntityTypeSelectComponent,selector:"tb-entity-type-select",inputs:["allowedEntityTypes","useAliasEntityTypes","filterAllowedEntityTypes","showLabel","required","disabled"]},{kind:"component",type:Q.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:yt,decorators:[{type:n,args:[{selector:"tb-action-node-create-relation-config",template:'
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.entity-type-pattern\n \n \n {{ \'tb.rulenode.entity-type-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n
\n \n tb.rulenode.relation-type-pattern\n \n \n {{ \'tb.rulenode.relation-type-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n
\n \n {{ \'tb.rulenode.create-entity-if-not-exists\' | translate }}\n \n
tb.rulenode.create-entity-if-not-exists-hint
\n
\n \n {{ \'tb.rulenode.remove-current-relations\' | translate }}\n \n
tb.rulenode.remove-current-relations-hint
\n \n {{ \'tb.rulenode.change-originator-to-related-entity\' | translate }}\n \n
tb.rulenode.change-originator-to-related-entity-hint
\n \n tb.rulenode.entity-cache-expiration\n \n \n {{ \'tb.rulenode.entity-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.entity-cache-expiration-range\' | translate }}\n \n tb.rulenode.entity-cache-expiration-hint\n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class xt extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.directionTypes=Object.keys(v),this.directionTypeTranslations=C,this.entityType=F}configForm(){return this.deleteRelationConfigForm}onConfigurationSet(e){this.deleteRelationConfigForm=this.fb.group({deleteForSingleEntity:[!!e&&e.deleteForSingleEntity,[]],direction:[e?e.direction:null,[O.required]],entityType:[e?e.entityType:null,[]],entityNamePattern:[e?e.entityNamePattern:null,[]],relationType:[e?e.relationType:null,[O.required]],entityCacheExpiration:[e?e.entityCacheExpiration:null,[O.required,O.min(0)]]})}validatorTriggers(){return["deleteForSingleEntity","entityType"]}updateValidators(e){const t=this.deleteRelationConfigForm.get("deleteForSingleEntity").value,n=this.deleteRelationConfigForm.get("entityType").value;t?this.deleteRelationConfigForm.get("entityType").setValidators([O.required]):this.deleteRelationConfigForm.get("entityType").setValidators([]),t&&n?this.deleteRelationConfigForm.get("entityNamePattern").setValidators([O.required,O.pattern(/.*\S.*/)]):this.deleteRelationConfigForm.get("entityNamePattern").setValidators([]),this.deleteRelationConfigForm.get("entityType").updateValueAndValidity({emitEvent:!1}),this.deleteRelationConfigForm.get("entityNamePattern").updateValueAndValidity({emitEvent:e})}prepareOutputConfig(e){return e.entityNamePattern=e.entityNamePattern?e.entityNamePattern.trim():null,e}}e("DeleteRelationConfigComponent",xt),xt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:xt,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),xt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:xt,selector:"tb-action-node-delete-relation-config",usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.delete-relation-to-specific-entity\' | translate }}\n \n
tb.rulenode.delete-relation-hint
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n
\n \n tb.rulenode.relation-type-pattern\n \n \n {{ \'tb.rulenode.relation-type-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.entity-cache-expiration\n \n \n {{ \'tb.rulenode.entity-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.entity-cache-expiration-range\' | translate }}\n \n tb.rulenode.entity-cache-expiration-hint\n \n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ve.EntityTypeSelectComponent,selector:"tb-entity-type-select",inputs:["allowedEntityTypes","useAliasEntityTypes","filterAllowedEntityTypes","showLabel","required","disabled"]},{kind:"component",type:Q.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:xt,decorators:[{type:n,args:[{selector:"tb-action-node-delete-relation-config",template:'
\n \n {{ \'tb.rulenode.delete-relation-to-specific-entity\' | translate }}\n \n
tb.rulenode.delete-relation-hint
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n
\n \n tb.rulenode.relation-type-pattern\n \n \n {{ \'tb.rulenode.relation-type-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.entity-cache-expiration\n \n \n {{ \'tb.rulenode.entity-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.entity-cache-expiration-range\' | translate }}\n \n tb.rulenode.entity-cache-expiration-hint\n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class bt extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.deviceProfile}onConfigurationSet(e){this.deviceProfile=this.fb.group({persistAlarmRulesState:[!!e&&e.persistAlarmRulesState,O.required],fetchAlarmRulesStateOnStart:[!!e&&e.fetchAlarmRulesStateOnStart,O.required]})}}e("DeviceProfileConfigComponent",bt),bt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:bt,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),bt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:bt,selector:"tb-device-profile-config",usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.persist-alarm-rules\' | translate }}\n \n \n {{ \'tb.rulenode.fetch-alarm-rules\' | translate }}\n \n
\n',dependencies:[{kind:"component",type:Q.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:bt,decorators:[{type:n,args:[{selector:"tb-device-profile-config",template:'
\n \n {{ \'tb.rulenode.persist-alarm-rules\' | translate }}\n \n \n {{ \'tb.rulenode.fetch-alarm-rules\' | translate }}\n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class ht extends f{constructor(e,t,n,o){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=n,this.translate=o,this.tbelEnabled=re(this.store).tbelEnabled,this.scriptLanguage=x,this.changeScript=new r,this.hasScript=!0,this.testScriptLabel="tb.rulenode.test-generator-function"}configForm(){return this.generatorConfigForm}onConfigurationSet(e){this.generatorConfigForm=this.fb.group({msgCount:[e?e.msgCount:null,[O.required,O.min(0)]],periodInSeconds:[e?e.periodInSeconds:null,[O.required,O.min(1)]],originator:[e?e.originator:null,[]],scriptLang:[e?e.scriptLang:x.JS,[O.required]],jsScript:[e?e.jsScript:null,[]],tbelScript:[e?e.tbelScript:null,[]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.generatorConfigForm.get("scriptLang").value;t!==x.TBEL||this.tbelEnabled||(t=x.JS,this.generatorConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.generatorConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.generatorConfigForm.get("jsScript").setValidators(t===x.JS?[O.required]:[]),this.generatorConfigForm.get("jsScript").updateValueAndValidity({emitEvent:e}),this.generatorConfigForm.get("tbelScript").setValidators(t===x.TBEL?[O.required]:[]),this.generatorConfigForm.get("tbelScript").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=x.JS),e.originatorId&&e.originatorType?e.originator={id:e.originatorId,entityType:e.originatorType}:e.originator=null,delete e.originatorId,delete e.originatorType),e}prepareOutputConfig(e){return e.originator?(e.originatorId=e.originator.id,e.originatorType=e.originator.entityType):(e.originatorId=null,e.originatorType=null),delete e.originator,e}testScript(e){const t=this.generatorConfigForm.get("scriptLang").value,n=t===x.JS?"jsScript":"tbelScript",r=t===x.JS?"rulenode/generator_node_script_fn":"rulenode/tbel/generator_node_script_fn",o=this.generatorConfigForm.get(n).value;this.nodeScriptTestService.testNodeScript(o,"generate",this.translate.instant("tb.rulenode.generator"),"Generate",["prevMsg","prevMetadata","prevMsgType"],this.ruleNodeId,r,t,e).subscribe((e=>{e&&(this.generatorConfigForm.get(n).setValue(e),this.changeScript.emit())}))}onValidate(){this.generatorConfigForm.get("scriptLang").value===x.JS&&this.jsFuncComponent.validateOnSubmit()}}var vt;e("GeneratorConfigComponent",ht),ht.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ht,deps:[{token:P.Store},{token:R.UntypedFormBuilder},{token:oe.NodeScriptTestService},{token:Z.TranslateService}],target:t.ɵɵFactoryTarget.Component}),ht.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:ht,selector:"tb-action-node-generator-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.message-count\n \n \n {{ \'tb.rulenode.message-count-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-message-count-message\' | translate }}\n \n \n \n tb.rulenode.period-seconds\n \n \n {{ \'tb.rulenode.period-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-period-seconds-message\' | translate }}\n \n \n
\n \n \n \n
\n\n \n \n \n \n \n \n \n
\n \n
\n
\n',dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Ce.EntitySelectComponent,selector:"tb-entity-select",inputs:["allowedEntityTypes","useAliasEntityTypes","required","disabled"]},{kind:"component",type:pe.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:de.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:de.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:fe.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ht,decorators:[{type:n,args:[{selector:"tb-action-node-generator-config",template:'
\n \n tb.rulenode.message-count\n \n \n {{ \'tb.rulenode.message-count-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-message-count-message\' | translate }}\n \n \n \n tb.rulenode.period-seconds\n \n \n {{ \'tb.rulenode.period-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-period-seconds-message\' | translate }}\n \n \n
\n \n \n \n
\n\n \n \n \n \n \n \n \n
\n \n
\n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder},{type:oe.NodeScriptTestService},{type:Z.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}}),function(e){e.CUSTOMER="CUSTOMER",e.TENANT="TENANT",e.RELATED="RELATED",e.ALARM_ORIGINATOR="ALARM_ORIGINATOR",e.ENTITY="ENTITY"}(vt||(vt={}));const Ct=new Map([[vt.CUSTOMER,"tb.rulenode.originator-customer"],[vt.TENANT,"tb.rulenode.originator-tenant"],[vt.RELATED,"tb.rulenode.originator-related"],[vt.ALARM_ORIGINATOR,"tb.rulenode.originator-alarm-originator"],[vt.ENTITY,"tb.rulenode.originator-entity"]]),Ft=new Map([[vt.CUSTOMER,"tb.rulenode.originator-customer-desc"],[vt.TENANT,"tb.rulenode.originator-tenant-desc"],[vt.RELATED,"tb.rulenode.originator-related-entity-desc"],[vt.ALARM_ORIGINATOR,"tb.rulenode.originator-alarm-originator-desc"],[vt.ENTITY,"tb.rulenode.originator-entity-by-name-pattern-desc"]]),kt=[k.createdTime,k.name,{value:"type",name:"tb.rulenode.profile-name",keyName:"originatorProfileName"},k.firstName,k.lastName,k.email,k.title,k.country,k.state,k.city,k.address,k.address2,k.zip,k.phone,k.label,{value:"id",name:"tb.rulenode.id",keyName:"id"},{value:"additionalInfo",name:"tb.rulenode.additional-info",keyName:"additionalInfo"}],Lt=new Map([["type","profileName"],["createdTime","createdTime"],["name","name"],["firstName","firstName"],["lastName","lastName"],["email","email"],["title","title"],["country","country"],["state","state"],["city","city"],["address","address"],["address2","address2"],["zip","zip"],["phone","phone"],["label","label"],["id","id"],["additionalInfo","additionalInfo"]]);var Tt;!function(e){e.CIRCLE="CIRCLE",e.POLYGON="POLYGON"}(Tt||(Tt={}));const It=new Map([[Tt.CIRCLE,"tb.rulenode.perimeter-circle"],[Tt.POLYGON,"tb.rulenode.perimeter-polygon"]]);var Nt;!function(e){e.MILLISECONDS="MILLISECONDS",e.SECONDS="SECONDS",e.MINUTES="MINUTES",e.HOURS="HOURS",e.DAYS="DAYS"}(Nt||(Nt={}));const St=new Map([[Nt.MILLISECONDS,"tb.rulenode.time-unit-milliseconds"],[Nt.SECONDS,"tb.rulenode.time-unit-seconds"],[Nt.MINUTES,"tb.rulenode.time-unit-minutes"],[Nt.HOURS,"tb.rulenode.time-unit-hours"],[Nt.DAYS,"tb.rulenode.time-unit-days"]]);var qt;!function(e){e.METER="METER",e.KILOMETER="KILOMETER",e.FOOT="FOOT",e.MILE="MILE",e.NAUTICAL_MILE="NAUTICAL_MILE"}(qt||(qt={}));const At=new Map([[qt.METER,"tb.rulenode.range-unit-meter"],[qt.KILOMETER,"tb.rulenode.range-unit-kilometer"],[qt.FOOT,"tb.rulenode.range-unit-foot"],[qt.MILE,"tb.rulenode.range-unit-mile"],[qt.NAUTICAL_MILE,"tb.rulenode.range-unit-nautical-mile"]]);var Mt;!function(e){e.ID="ID",e.TITLE="TITLE",e.COUNTRY="COUNTRY",e.STATE="STATE",e.CITY="CITY",e.ZIP="ZIP",e.ADDRESS="ADDRESS",e.ADDRESS2="ADDRESS2",e.PHONE="PHONE",e.EMAIL="EMAIL",e.ADDITIONAL_INFO="ADDITIONAL_INFO"}(Mt||(Mt={}));const Et=new Map([[Mt.ID,"tb.rulenode.entity-details-id"],[Mt.TITLE,"tb.rulenode.entity-details-title"],[Mt.COUNTRY,"tb.rulenode.entity-details-country"],[Mt.STATE,"tb.rulenode.entity-details-state"],[Mt.CITY,"tb.rulenode.entity-details-city"],[Mt.ZIP,"tb.rulenode.entity-details-zip"],[Mt.ADDRESS,"tb.rulenode.entity-details-address"],[Mt.ADDRESS2,"tb.rulenode.entity-details-address2"],[Mt.PHONE,"tb.rulenode.entity-details-phone"],[Mt.EMAIL,"tb.rulenode.entity-details-email"],[Mt.ADDITIONAL_INFO,"tb.rulenode.entity-details-additional_info"]]);var Gt;!function(e){e.FIRST="FIRST",e.LAST="LAST",e.ALL="ALL"}(Gt||(Gt={}));const Dt=new Map([[Gt.FIRST,"tb.rulenode.first"],[Gt.LAST,"tb.rulenode.last"],[Gt.ALL,"tb.rulenode.all"]]),wt=new Map([[Gt.FIRST,"tb.rulenode.first-mode-hint"],[Gt.LAST,"tb.rulenode.last-mode-hint"],[Gt.ALL,"tb.rulenode.all-mode-hint"]]);var Vt,Pt;!function(e){e.ASC="ASC",e.DESC="DESC"}(Vt||(Vt={})),function(e){e.ATTRIBUTES="ATTRIBUTES",e.LATEST_TELEMETRY="LATEST_TELEMETRY",e.FIELDS="FIELDS"}(Pt||(Pt={}));const Rt=new Map([[Pt.ATTRIBUTES,"tb.rulenode.attributes"],[Pt.LATEST_TELEMETRY,"tb.rulenode.latest-telemetry"],[Pt.FIELDS,"tb.rulenode.fields"]]),Ot=new Map([[Pt.ATTRIBUTES,"tb.rulenode.add-mapped-attribute-to"],[Pt.LATEST_TELEMETRY,"tb.rulenode.add-mapped-latest-telemetry-to"],[Pt.FIELDS,"tb.rulenode.add-mapped-fields-to"]]),_t=new Map([[Vt.ASC,"tb.rulenode.ascending"],[Vt.DESC,"tb.rulenode.descending"]]);var Bt;!function(e){e.STANDARD="STANDARD",e.FIFO="FIFO"}(Bt||(Bt={}));const Kt=new Map([[Bt.STANDARD,"tb.rulenode.sqs-queue-standard"],[Bt.FIFO,"tb.rulenode.sqs-queue-fifo"]]),zt=["anonymous","basic","cert.PEM"],Ut=new Map([["anonymous","tb.rulenode.credentials-anonymous"],["basic","tb.rulenode.credentials-basic"],["cert.PEM","tb.rulenode.credentials-pem"]]),Ht=["sas","cert.PEM"],jt=new Map([["sas","tb.rulenode.credentials-sas"],["cert.PEM","tb.rulenode.credentials-pem"]]);var $t;!function(e){e.GET="GET",e.POST="POST",e.PUT="PUT",e.DELETE="DELETE"}($t||($t={}));const Qt=["US-ASCII","ISO-8859-1","UTF-8","UTF-16BE","UTF-16LE","UTF-16"],Jt=new Map([["US-ASCII","tb.rulenode.charset-us-ascii"],["ISO-8859-1","tb.rulenode.charset-iso-8859-1"],["UTF-8","tb.rulenode.charset-utf-8"],["UTF-16BE","tb.rulenode.charset-utf-16be"],["UTF-16LE","tb.rulenode.charset-utf-16le"],["UTF-16","tb.rulenode.charset-utf-16"]]);var Yt;!function(e){e.CUSTOM="CUSTOM",e.ADD="ADD",e.SUB="SUB",e.MULT="MULT",e.DIV="DIV",e.SIN="SIN",e.SINH="SINH",e.COS="COS",e.COSH="COSH",e.TAN="TAN",e.TANH="TANH",e.ACOS="ACOS",e.ASIN="ASIN",e.ATAN="ATAN",e.ATAN2="ATAN2",e.EXP="EXP",e.EXPM1="EXPM1",e.SQRT="SQRT",e.CBRT="CBRT",e.GET_EXP="GET_EXP",e.HYPOT="HYPOT",e.LOG="LOG",e.LOG10="LOG10",e.LOG1P="LOG1P",e.CEIL="CEIL",e.FLOOR="FLOOR",e.FLOOR_DIV="FLOOR_DIV",e.FLOOR_MOD="FLOOR_MOD",e.ABS="ABS",e.MIN="MIN",e.MAX="MAX",e.POW="POW",e.SIGNUM="SIGNUM",e.RAD="RAD",e.DEG="DEG"}(Yt||(Yt={}));const Wt=new Map([[Yt.CUSTOM,{value:Yt.CUSTOM,name:"Custom Function",description:"Use this function to specify complex mathematical expression.",minArgs:1,maxArgs:16}],[Yt.ADD,{value:Yt.ADD,name:"Addition",description:"x + y",minArgs:2,maxArgs:2}],[Yt.SUB,{value:Yt.SUB,name:"Subtraction",description:"x - y",minArgs:2,maxArgs:2}],[Yt.MULT,{value:Yt.MULT,name:"Multiplication",description:"x * y",minArgs:2,maxArgs:2}],[Yt.DIV,{value:Yt.DIV,name:"Division",description:"x / y",minArgs:2,maxArgs:2}],[Yt.SIN,{value:Yt.SIN,name:"Sine",description:"Returns the trigonometric sine of an angle in radians.",minArgs:1,maxArgs:1}],[Yt.SINH,{value:Yt.SINH,name:"Hyperbolic sine",description:"Returns the hyperbolic sine of an argument.",minArgs:1,maxArgs:1}],[Yt.COS,{value:Yt.COS,name:"Cosine",description:"Returns the trigonometric cosine of an angle in radians.",minArgs:1,maxArgs:1}],[Yt.COSH,{value:Yt.COSH,name:"Hyperbolic cosine",description:"Returns the hyperbolic cosine of an argument.",minArgs:1,maxArgs:1}],[Yt.TAN,{value:Yt.TAN,name:"Tangent",description:"Returns the trigonometric tangent of an angle in radians",minArgs:1,maxArgs:1}],[Yt.TANH,{value:Yt.TANH,name:"Hyperbolic tangent",description:"Returns the hyperbolic tangent of an argument",minArgs:1,maxArgs:1}],[Yt.ACOS,{value:Yt.ACOS,name:"Arc cosine",description:"Returns the arc cosine of an argument",minArgs:1,maxArgs:1}],[Yt.ASIN,{value:Yt.ASIN,name:"Arc sine",description:"Returns the arc sine of an argument",minArgs:1,maxArgs:1}],[Yt.ATAN,{value:Yt.ATAN,name:"Arc tangent",description:"Returns the arc tangent of an argument",minArgs:1,maxArgs:1}],[Yt.ATAN2,{value:Yt.ATAN2,name:"2-argument arc tangent",description:"Returns the angle theta from the conversion of rectangular coordinates (x, y) to polar coordinates (r, theta)",minArgs:2,maxArgs:2}],[Yt.EXP,{value:Yt.EXP,name:"Exponential",description:"Returns Euler's number e raised to the power of an argument",minArgs:1,maxArgs:1}],[Yt.EXPM1,{value:Yt.EXPM1,name:"Exponential minus one",description:"Returns Euler's number e raised to the power of an argument minus one",minArgs:1,maxArgs:1}],[Yt.SQRT,{value:Yt.SQRT,name:"Square",description:"Returns the correctly rounded positive square root of an argument",minArgs:1,maxArgs:1}],[Yt.CBRT,{value:Yt.CBRT,name:"Cube root",description:"Returns the cube root of an argument",minArgs:1,maxArgs:1}],[Yt.GET_EXP,{value:Yt.GET_EXP,name:"Get exponent",description:"Returns the unbiased exponent used in the representation of an argument",minArgs:1,maxArgs:1}],[Yt.HYPOT,{value:Yt.HYPOT,name:"Square root",description:"Returns the square root of the squares of the arguments",minArgs:2,maxArgs:2}],[Yt.LOG,{value:Yt.LOG,name:"Logarithm",description:"Returns the natural logarithm of an argument",minArgs:1,maxArgs:1}],[Yt.LOG10,{value:Yt.LOG10,name:"Base 10 logarithm",description:"Returns the base 10 logarithm of an argument",minArgs:1,maxArgs:1}],[Yt.LOG1P,{value:Yt.LOG1P,name:"Logarithm of the sum",description:"Returns the natural logarithm of the sum of an argument",minArgs:1,maxArgs:1}],[Yt.CEIL,{value:Yt.CEIL,name:"Ceiling",description:"Returns the smallest (closest to negative infinity) of an argument",minArgs:1,maxArgs:1}],[Yt.FLOOR,{value:Yt.FLOOR,name:"Floor",description:"Returns the largest (closest to positive infinity) of an argument",minArgs:1,maxArgs:1}],[Yt.FLOOR_DIV,{value:Yt.FLOOR_DIV,name:"Floor division",description:"Returns the largest (closest to positive infinity) of the arguments",minArgs:2,maxArgs:2}],[Yt.FLOOR_MOD,{value:Yt.FLOOR_MOD,name:"Floor modulus",description:"Returns the floor modulus of the arguments",minArgs:2,maxArgs:2}],[Yt.ABS,{value:Yt.ABS,name:"Absolute",description:"Returns the absolute value of an argument",minArgs:1,maxArgs:1}],[Yt.MIN,{value:Yt.MIN,name:"Min",description:"Returns the smaller of the arguments",minArgs:2,maxArgs:2}],[Yt.MAX,{value:Yt.MAX,name:"Max",description:"Returns the greater of the arguments",minArgs:2,maxArgs:2}],[Yt.POW,{value:Yt.POW,name:"Raise to a power",description:"Returns the value of the first argument raised to the power of the second argument",minArgs:2,maxArgs:2}],[Yt.SIGNUM,{value:Yt.SIGNUM,name:"Sign of a real number",description:"Returns the signum function of the argument",minArgs:1,maxArgs:1}],[Yt.RAD,{value:Yt.RAD,name:"Radian",description:"Converts an angle measured in degrees to an approximately equivalent angle measured in radians",minArgs:1,maxArgs:1}],[Yt.DEG,{value:Yt.DEG,name:"Degrees",description:"Converts an angle measured in radians to an approximately equivalent angle measured in degrees.",minArgs:1,maxArgs:1}]]);var Zt,Xt,en;!function(e){e.MESSAGE_BODY="MESSAGE_BODY",e.MESSAGE_METADATA="MESSAGE_METADATA",e.ATTRIBUTE="ATTRIBUTE",e.TIME_SERIES="TIME_SERIES",e.CONSTANT="CONSTANT"}(Zt||(Zt={})),function(e){e.MESSAGE_BODY="MESSAGE_BODY",e.MESSAGE_METADATA="MESSAGE_METADATA",e.ATTRIBUTE="ATTRIBUTE",e.TIME_SERIES="TIME_SERIES"}(Xt||(Xt={})),function(e){e.DATA="DATA",e.METADATA="METADATA"}(en||(en={}));const tn=new Map([[en.DATA,"tb.rulenode.message-to-metadata"],[en.METADATA,"tb.rulenode.metadata-to-message"]]),nn=(new Map([[en.DATA,"tb.rulenode.from-message"],[en.METADATA,"tb.rulenode.from-metadata"]]),new Map([[en.DATA,"tb.rulenode.message"],[en.METADATA,"tb.rulenode.metadata"]])),rn=new Map([[en.DATA,"tb.rulenode.message"],[en.METADATA,"tb.rulenode.message-metadata"]]),on=new Map([[Zt.MESSAGE_BODY,{name:"tb.rulenode.message-body-type",description:"Fetch argument value from incoming message"}],[Zt.MESSAGE_METADATA,{name:"tb.rulenode.message-metadata-type",description:"Fetch argument value from incoming message metadata"}],[Zt.ATTRIBUTE,{name:"tb.rulenode.attribute-type",description:"Fetch attribute value from database"}],[Zt.TIME_SERIES,{name:"tb.rulenode.time-series-type",description:"Fetch latest time-series value from database"}],[Zt.CONSTANT,{name:"tb.rulenode.constant-type",description:"Define constant value"}]]),an=new Map([[Xt.MESSAGE_BODY,{name:"tb.rulenode.message-body-type",description:"Add result to the outgoing message"}],[Xt.MESSAGE_METADATA,{name:"tb.rulenode.message-metadata-type",description:"Add result to the outgoing message metadata"}],[Xt.ATTRIBUTE,{name:"tb.rulenode.attribute-type",description:"Store result as an entity attribute in the database"}],[Xt.TIME_SERIES,{name:"tb.rulenode.time-series-type",description:"Store result as an entity time-series in the database"}]]),ln=["x","y","z","a","b","c","d","k","l","m","n","o","p","r","s","t"];var sn,mn;!function(e){e.SHARED_SCOPE="SHARED_SCOPE",e.SERVER_SCOPE="SERVER_SCOPE",e.CLIENT_SCOPE="CLIENT_SCOPE"}(sn||(sn={})),function(e){e.SHARED_SCOPE="SHARED_SCOPE",e.SERVER_SCOPE="SERVER_SCOPE"}(mn||(mn={}));const pn=new Map([[sn.SHARED_SCOPE,"tb.rulenode.shared-scope"],[sn.SERVER_SCOPE,"tb.rulenode.server-scope"],[sn.CLIENT_SCOPE,"tb.rulenode.client-scope"]]);class dn extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.perimeterType=Tt,this.perimeterTypes=Object.keys(Tt),this.perimeterTypeTranslationMap=It,this.rangeUnits=Object.keys(qt),this.rangeUnitTranslationMap=At,this.timeUnits=Object.keys(Nt),this.timeUnitsTranslationMap=St}configForm(){return this.geoActionConfigForm}onConfigurationSet(e){this.geoActionConfigForm=this.fb.group({latitudeKeyName:[e?e.latitudeKeyName:null,[O.required]],longitudeKeyName:[e?e.longitudeKeyName:null,[O.required]],perimeterType:[e?e.perimeterType:null,[O.required]],fetchPerimeterInfoFromMessageMetadata:[!!e&&e.fetchPerimeterInfoFromMessageMetadata,[]],perimeterKeyName:[e?e.perimeterKeyName:null,[]],centerLatitude:[e?e.centerLatitude:null,[]],centerLongitude:[e?e.centerLatitude:null,[]],range:[e?e.range:null,[]],rangeUnit:[e?e.rangeUnit:null,[]],polygonsDefinition:[e?e.polygonsDefinition:null,[]],minInsideDuration:[e?e.minInsideDuration:null,[O.required,O.min(1),O.max(2147483647)]],minInsideDurationTimeUnit:[e?e.minInsideDurationTimeUnit:null,[O.required]],minOutsideDuration:[e?e.minOutsideDuration:null,[O.required,O.min(1),O.max(2147483647)]],minOutsideDurationTimeUnit:[e?e.minOutsideDurationTimeUnit:null,[O.required]]})}validatorTriggers(){return["fetchPerimeterInfoFromMessageMetadata","perimeterType"]}updateValidators(e){const t=this.geoActionConfigForm.get("fetchPerimeterInfoFromMessageMetadata").value,n=this.geoActionConfigForm.get("perimeterType").value;t?this.geoActionConfigForm.get("perimeterKeyName").setValidators([O.required]):this.geoActionConfigForm.get("perimeterKeyName").setValidators([]),t||n!==Tt.CIRCLE?(this.geoActionConfigForm.get("centerLatitude").setValidators([]),this.geoActionConfigForm.get("centerLongitude").setValidators([]),this.geoActionConfigForm.get("range").setValidators([]),this.geoActionConfigForm.get("rangeUnit").setValidators([])):(this.geoActionConfigForm.get("centerLatitude").setValidators([O.required,O.min(-90),O.max(90)]),this.geoActionConfigForm.get("centerLongitude").setValidators([O.required,O.min(-180),O.max(180)]),this.geoActionConfigForm.get("range").setValidators([O.required,O.min(0)]),this.geoActionConfigForm.get("rangeUnit").setValidators([O.required])),t||n!==Tt.POLYGON?this.geoActionConfigForm.get("polygonsDefinition").setValidators([]):this.geoActionConfigForm.get("polygonsDefinition").setValidators([O.required]),this.geoActionConfigForm.get("perimeterKeyName").updateValueAndValidity({emitEvent:e}),this.geoActionConfigForm.get("centerLatitude").updateValueAndValidity({emitEvent:e}),this.geoActionConfigForm.get("centerLongitude").updateValueAndValidity({emitEvent:e}),this.geoActionConfigForm.get("range").updateValueAndValidity({emitEvent:e}),this.geoActionConfigForm.get("rangeUnit").updateValueAndValidity({emitEvent:e}),this.geoActionConfigForm.get("polygonsDefinition").updateValueAndValidity({emitEvent:e})}}e("GpsGeoActionConfigComponent",dn),dn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:dn,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),dn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:dn,selector:"tb-action-node-gps-geofencing-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.latitude-key-name\n \n \n {{ \'tb.rulenode.latitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.longitude-key-name\n \n \n {{ \'tb.rulenode.longitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.perimeter-type\n \n \n {{ perimeterTypeTranslationMap.get(type) | translate }}\n \n \n \n \n {{ \'tb.rulenode.fetch-perimeter-info-from-metadata\' | translate }}\n \n \n tb.rulenode.perimeter-key-name\n \n \n {{ \'tb.rulenode.perimeter-key-name-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.circle-center-latitude\n \n \n {{ \'tb.rulenode.circle-center-latitude-required\' | translate }}\n \n \n \n tb.rulenode.circle-center-longitude\n \n \n {{ \'tb.rulenode.circle-center-longitude-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.range\n \n \n {{ \'tb.rulenode.range-required\' | translate }}\n \n \n \n tb.rulenode.range-units\n \n \n {{ rangeUnitTranslationMap.get(type) | translate }}\n \n \n \n
\n
\n
\n \n tb.rulenode.polygon-definition\n \n \n {{ \'tb.rulenode.polygon-definition-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.min-inside-duration\n \n \n {{ \'tb.rulenode.min-inside-duration-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n tb.rulenode.min-inside-duration-time-unit\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n \n tb.rulenode.min-outside-duration\n \n \n {{ \'tb.rulenode.min-outside-duration-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n tb.rulenode.min-outside-duration-time-unit\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Q.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:dn,decorators:[{type:n,args:[{selector:"tb-action-node-gps-geofencing-config",template:'
\n \n tb.rulenode.latitude-key-name\n \n \n {{ \'tb.rulenode.latitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.longitude-key-name\n \n \n {{ \'tb.rulenode.longitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.perimeter-type\n \n \n {{ perimeterTypeTranslationMap.get(type) | translate }}\n \n \n \n \n {{ \'tb.rulenode.fetch-perimeter-info-from-metadata\' | translate }}\n \n \n tb.rulenode.perimeter-key-name\n \n \n {{ \'tb.rulenode.perimeter-key-name-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.circle-center-latitude\n \n \n {{ \'tb.rulenode.circle-center-latitude-required\' | translate }}\n \n \n \n tb.rulenode.circle-center-longitude\n \n \n {{ \'tb.rulenode.circle-center-longitude-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.range\n \n \n {{ \'tb.rulenode.range-required\' | translate }}\n \n \n \n tb.rulenode.range-units\n \n \n {{ rangeUnitTranslationMap.get(type) | translate }}\n \n \n \n
\n
\n
\n \n tb.rulenode.polygon-definition\n \n \n {{ \'tb.rulenode.polygon-definition-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.min-inside-duration\n \n \n {{ \'tb.rulenode.min-inside-duration-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n tb.rulenode.min-inside-duration-time-unit\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n \n tb.rulenode.min-outside-duration\n \n \n {{ \'tb.rulenode.min-outside-duration-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n tb.rulenode.min-outside-duration-time-unit\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class un extends f{constructor(e,t,n,o){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=n,this.translate=o,this.tbelEnabled=re(this.store).tbelEnabled,this.scriptLanguage=x,this.changeScript=new r,this.hasScript=!0,this.testScriptLabel="tb.rulenode.test-to-string-function"}configForm(){return this.logConfigForm}onConfigurationSet(e){this.logConfigForm=this.fb.group({scriptLang:[e?e.scriptLang:x.JS,[O.required]],jsScript:[e?e.jsScript:null,[]],tbelScript:[e?e.tbelScript:null,[]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.logConfigForm.get("scriptLang").value;t!==x.TBEL||this.tbelEnabled||(t=x.JS,this.logConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.logConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.logConfigForm.get("jsScript").setValidators(t===x.JS?[O.required]:[]),this.logConfigForm.get("jsScript").updateValueAndValidity({emitEvent:e}),this.logConfigForm.get("tbelScript").setValidators(t===x.TBEL?[O.required]:[]),this.logConfigForm.get("tbelScript").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=x.JS)),e}testScript(e){const t=this.logConfigForm.get("scriptLang").value,n=t===x.JS?"jsScript":"tbelScript",r=t===x.JS?"rulenode/log_node_script_fn":"rulenode/tbel/log_node_script_fn",o=this.logConfigForm.get(n).value;this.nodeScriptTestService.testNodeScript(o,"string",this.translate.instant("tb.rulenode.to-string"),"ToString",["msg","metadata","msgType"],this.ruleNodeId,r,t,e).subscribe((e=>{e&&(this.logConfigForm.get(n).setValue(e),this.changeScript.emit())}))}onValidate(){this.logConfigForm.get("scriptLang").value===x.JS&&this.jsFuncComponent.validateOnSubmit()}}e("LogConfigComponent",un),un.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:un,deps:[{token:P.Store},{token:R.UntypedFormBuilder},{token:oe.NodeScriptTestService},{token:Z.TranslateService}],target:t.ɵɵFactoryTarget.Component}),un.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:un,selector:"tb-action-node-log-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n \n \n
\n \n
\n
\n',dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:pe.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:de.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:de.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:fe.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:un,decorators:[{type:n,args:[{selector:"tb-action-node-log-config",template:'
\n \n \n \n \n \n \n \n
\n \n
\n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder},{type:oe.NodeScriptTestService},{type:Z.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}});class cn extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.msgCountConfigForm}onConfigurationSet(e){this.msgCountConfigForm=this.fb.group({interval:[e?e.interval:null,[O.required,O.min(1)]],telemetryPrefix:[e?e.telemetryPrefix:null,[O.required]]})}}e("MsgCountConfigComponent",cn),cn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:cn,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),cn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:cn,selector:"tb-action-node-msg-count-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.interval-seconds\n \n \n {{ \'tb.rulenode.interval-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-interval-seconds-message\' | translate }}\n \n \n \n tb.rulenode.output-timeseries-key-prefix\n \n \n {{ \'tb.rulenode.output-timeseries-key-prefix-required\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:cn,decorators:[{type:n,args:[{selector:"tb-action-node-msg-count-config",template:'
\n \n tb.rulenode.interval-seconds\n \n \n {{ \'tb.rulenode.interval-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-interval-seconds-message\' | translate }}\n \n \n \n tb.rulenode.output-timeseries-key-prefix\n \n \n {{ \'tb.rulenode.output-timeseries-key-prefix-required\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class fn extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.msgDelayConfigForm}onConfigurationSet(e){this.msgDelayConfigForm=this.fb.group({useMetadataPeriodInSecondsPatterns:[!!e&&e.useMetadataPeriodInSecondsPatterns,[]],periodInSeconds:[e?e.periodInSeconds:null,[]],periodInSecondsPattern:[e?e.periodInSecondsPattern:null,[]],maxPendingMsgs:[e?e.maxPendingMsgs:null,[O.required,O.min(1),O.max(1e5)]]})}validatorTriggers(){return["useMetadataPeriodInSecondsPatterns"]}updateValidators(e){this.msgDelayConfigForm.get("useMetadataPeriodInSecondsPatterns").value?(this.msgDelayConfigForm.get("periodInSecondsPattern").setValidators([O.required]),this.msgDelayConfigForm.get("periodInSeconds").setValidators([])):(this.msgDelayConfigForm.get("periodInSecondsPattern").setValidators([]),this.msgDelayConfigForm.get("periodInSeconds").setValidators([O.required,O.min(0)])),this.msgDelayConfigForm.get("periodInSecondsPattern").updateValueAndValidity({emitEvent:e}),this.msgDelayConfigForm.get("periodInSeconds").updateValueAndValidity({emitEvent:e})}}e("MsgDelayConfigComponent",fn),fn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:fn,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),fn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:fn,selector:"tb-action-node-msg-delay-config",usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.use-metadata-period-in-seconds-patterns\' | translate }}\n \n
tb.rulenode.use-metadata-period-in-seconds-patterns-hint
\n \n tb.rulenode.period-seconds\n \n \n {{ \'tb.rulenode.period-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-period-0-seconds-message\' | translate }}\n \n \n \n \n tb.rulenode.period-in-seconds-pattern\n \n \n {{ \'tb.rulenode.period-in-seconds-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n \n tb.rulenode.max-pending-messages\n \n \n {{ \'tb.rulenode.max-pending-messages-required\' | translate }}\n \n \n {{ \'tb.rulenode.max-pending-messages-range\' | translate }}\n \n \n {{ \'tb.rulenode.max-pending-messages-range\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Q.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:fn,decorators:[{type:n,args:[{selector:"tb-action-node-msg-delay-config",template:'
\n \n {{ \'tb.rulenode.use-metadata-period-in-seconds-patterns\' | translate }}\n \n
tb.rulenode.use-metadata-period-in-seconds-patterns-hint
\n \n tb.rulenode.period-seconds\n \n \n {{ \'tb.rulenode.period-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-period-0-seconds-message\' | translate }}\n \n \n \n \n tb.rulenode.period-in-seconds-pattern\n \n \n {{ \'tb.rulenode.period-in-seconds-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n \n tb.rulenode.max-pending-messages\n \n \n {{ \'tb.rulenode.max-pending-messages-required\' | translate }}\n \n \n {{ \'tb.rulenode.max-pending-messages-range\' | translate }}\n \n \n {{ \'tb.rulenode.max-pending-messages-range\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class gn extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.attributeScopes=Object.keys(g),this.telemetryTypeTranslationsMap=y}configForm(){return this.pushToCloudConfigForm}onConfigurationSet(e){this.pushToCloudConfigForm=this.fb.group({scope:[e?e.scope:null,[O.required]]})}}e("PushToCloudConfigComponent",gn),gn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:gn,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),gn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:gn,selector:"tb-action-node-push-to-cloud-config",usesInheritance:!0,ngImport:t,template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:gn,decorators:[{type:n,args:[{selector:"tb-action-node-push-to-cloud-config",template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class yn extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.attributeScopes=Object.keys(g),this.telemetryTypeTranslationsMap=y}configForm(){return this.pushToEdgeConfigForm}onConfigurationSet(e){this.pushToEdgeConfigForm=this.fb.group({scope:[e?e.scope:null,[O.required]]})}}e("PushToEdgeConfigComponent",yn),yn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:yn,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),yn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:yn,selector:"tb-action-node-push-to-edge-config",usesInheritance:!0,ngImport:t,template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:yn,decorators:[{type:n,args:[{selector:"tb-action-node-push-to-edge-config",template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class xn extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.rpcReplyConfigForm}onConfigurationSet(e){this.rpcReplyConfigForm=this.fb.group({requestIdMetaDataAttribute:[e?e.requestIdMetaDataAttribute:null,[]]})}}e("RpcReplyConfigComponent",xn),xn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:xn,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),xn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:xn,selector:"tb-action-node-rpc-reply-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.request-id-metadata-attribute\n \n \n
\n',dependencies:[{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:xn,decorators:[{type:n,args:[{selector:"tb-action-node-rpc-reply-config",template:'
\n \n tb.rulenode.request-id-metadata-attribute\n \n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class bn extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.rpcRequestConfigForm}onConfigurationSet(e){this.rpcRequestConfigForm=this.fb.group({timeoutInSeconds:[e?e.timeoutInSeconds:null,[O.required,O.min(0)]]})}}e("RpcRequestConfigComponent",bn),bn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:bn,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),bn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:bn,selector:"tb-action-node-rpc-request-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.timeout-sec\n \n \n {{ \'tb.rulenode.timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-timeout-message\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:bn,decorators:[{type:n,args:[{selector:"tb-action-node-rpc-request-config",template:'
\n \n tb.rulenode.timeout-sec\n \n \n {{ \'tb.rulenode.timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-timeout-message\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class hn extends L{get required(){return this.requiredValue}set required(e){this.requiredValue=Fe(e)}constructor(e,t,n,r){super(e),this.store=e,this.translate=t,this.injector=n,this.fb=r,this.propagateChange=null,this.valueChangeSubscription=null}ngOnInit(){this.ngControl=this.injector.get(_),null!=this.ngControl&&(this.ngControl.valueAccessor=this),this.kvListFormGroup=this.fb.group({}),this.kvListFormGroup.addControl("keyVals",this.fb.array([]))}keyValsFormArray(){return this.kvListFormGroup.get("keyVals")}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.kvListFormGroup.disable({emitEvent:!1}):this.kvListFormGroup.enable({emitEvent:!1})}writeValue(e){this.valueChangeSubscription&&this.valueChangeSubscription.unsubscribe();const t=[];if(e)for(const n of Object.keys(e))Object.prototype.hasOwnProperty.call(e,n)&&t.push(this.fb.group({key:[n,[O.required]],value:[e[n],[O.required]]}));this.kvListFormGroup.setControl("keyVals",this.fb.array(t)),this.valueChangeSubscription=this.kvListFormGroup.valueChanges.subscribe((()=>{this.updateModel()}))}removeKeyVal(e){this.kvListFormGroup.get("keyVals").removeAt(e)}addKeyVal(){this.kvListFormGroup.get("keyVals").push(this.fb.group({key:["",[O.required]],value:["",[O.required]]}))}validate(e){const t=this.kvListFormGroup.get("keyVals").value;if(!t.length&&this.required)return{kvMapRequired:!0};if(!this.kvListFormGroup.valid)return{kvFieldsRequired:!0};if(this.uniqueKeyValuePairValidator)for(const e of t)if(e.key===e.value)return{uniqueKeyValuePair:!0};return null}updateModel(){const e=this.kvListFormGroup.get("keyVals").value;if(this.required&&!e.length||!this.kvListFormGroup.valid)this.propagateChange(null);else{const t={};e.forEach((e=>{t[e.key]=e.value})),this.propagateChange(t)}}}e("KvMapConfigOldComponent",hn),hn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:hn,deps:[{token:P.Store},{token:Z.TranslateService},{token:t.Injector},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),hn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:hn,selector:"tb-kv-map-config-old",inputs:{disabled:"disabled",uniqueKeyValuePairValidator:"uniqueKeyValuePairValidator",requiredText:"requiredText",keyText:"keyText",keyRequiredText:"keyRequiredText",valText:"valText",valRequiredText:"valRequiredText",hintText:"hintText",required:"required"},providers:[{provide:B,useExisting:a((()=>hn)),multi:!0},{provide:K,useExisting:a((()=>hn)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n
\n {{ keyText | translate }}\n {{ valText | translate }}\n \n
\n
\n
\n \n \n \n {{ keyRequiredText | translate }}\n \n \n \n \n \n {{ valRequiredText | translate }}\n \n \n \n
\n
\n
\n \n
\n \n
\n
\n',styles:[":host .tb-kv-map-config{margin-bottom:16px}:host .tb-kv-map-config .header{padding-left:5px;padding-right:5px;padding-bottom:5px}:host .tb-kv-map-config .header .cell{padding-left:5px;padding-right:5px;color:#757575;font-size:12px;font-weight:700;white-space:nowrap}:host .tb-kv-map-config .body{padding-left:5px;padding-right:5px;padding-bottom:0;max-height:300px;overflow:auto}:host .tb-kv-map-config .body .cell{padding-left:5px;padding-right:5px}:host .tb-kv-map-config tb-error{display:block;margin-top:-12px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Te.TbErrorComponent,selector:"tb-error",inputs:["noMargin","error"]},{kind:"component",type:de.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:de.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:W.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:Ie.DefaultShowHideDirective,selector:" [fxShow], [fxShow.print], [fxShow.xs], [fxShow.sm], [fxShow.md], [fxShow.lg], [fxShow.xl], [fxShow.lt-sm], [fxShow.lt-md], [fxShow.lt-lg], [fxShow.lt-xl], [fxShow.gt-xs], [fxShow.gt-sm], [fxShow.gt-md], [fxShow.gt-lg], [fxHide], [fxHide.print], [fxHide.xs], [fxHide.sm], [fxHide.md], [fxHide.lg], [fxHide.xl], [fxHide.lt-sm], [fxHide.lt-md], [fxHide.lt-lg], [fxHide.lt-xl], [fxHide.gt-xs], [fxHide.gt-sm], [fxHide.gt-md], [fxHide.gt-lg]",inputs:["fxShow","fxShow.print","fxShow.xs","fxShow.sm","fxShow.md","fxShow.lg","fxShow.xl","fxShow.lt-sm","fxShow.lt-md","fxShow.lt-lg","fxShow.lt-xl","fxShow.gt-xs","fxShow.gt-sm","fxShow.gt-md","fxShow.gt-lg","fxHide","fxHide.print","fxHide.xs","fxHide.sm","fxHide.md","fxHide.lg","fxHide.xl","fxHide.lt-sm","fxHide.lt-md","fxHide.lt-lg","fxHide.lt-xl","fxHide.gt-xs","fxHide.gt-sm","fxHide.gt-md","fxHide.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormControlDirective,selector:"[formControl]",inputs:["formControl","disabled","ngModel"],outputs:["ngModelChange"],exportAs:["ngForm"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormArrayName,selector:"[formArrayName]",inputs:["formArrayName"]},{kind:"pipe",type:H.AsyncPipe,name:"async"},{kind:"pipe",type:he.SafePipe,name:"safe"},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:hn,decorators:[{type:n,args:[{selector:"tb-kv-map-config-old",providers:[{provide:B,useExisting:a((()=>hn)),multi:!0},{provide:K,useExisting:a((()=>hn)),multi:!0}],template:'
\n
\n {{ keyText | translate }}\n {{ valText | translate }}\n \n
\n
\n
\n \n \n \n {{ keyRequiredText | translate }}\n \n \n \n \n \n {{ valRequiredText | translate }}\n \n \n \n
\n
\n
\n \n
\n \n
\n
\n',styles:[":host .tb-kv-map-config{margin-bottom:16px}:host .tb-kv-map-config .header{padding-left:5px;padding-right:5px;padding-bottom:5px}:host .tb-kv-map-config .header .cell{padding-left:5px;padding-right:5px;color:#757575;font-size:12px;font-weight:700;white-space:nowrap}:host .tb-kv-map-config .body{padding-left:5px;padding-right:5px;padding-bottom:0;max-height:300px;overflow:auto}:host .tb-kv-map-config .body .cell{padding-left:5px;padding-right:5px}:host .tb-kv-map-config tb-error{display:block;margin-top:-12px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:P.Store},{type:Z.TranslateService},{type:t.Injector},{type:R.FormBuilder}]},propDecorators:{disabled:[{type:i}],uniqueKeyValuePairValidator:[{type:i}],requiredText:[{type:i}],keyText:[{type:i}],keyRequiredText:[{type:i}],valText:[{type:i}],valRequiredText:[{type:i}],hintText:[{type:i}],required:[{type:i}]}});class vn extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.saveToCustomTableConfigForm}onConfigurationSet(e){this.saveToCustomTableConfigForm=this.fb.group({tableName:[e?e.tableName:null,[O.required,O.pattern(/.*\S.*/)]],fieldsMapping:[e?e.fieldsMapping:null,[O.required]]})}prepareOutputConfig(e){return e.tableName=e.tableName.trim(),e}}e("SaveToCustomTableConfigComponent",vn),vn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:vn,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),vn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:vn,selector:"tb-action-node-custom-table-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.custom-table-name\n \n \n {{ \'tb.rulenode.custom-table-name-required\' | translate }}\n \n tb.rulenode.custom-table-hint\n \n \n \n \n
\n',dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:hn,selector:"tb-kv-map-config-old",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:vn,decorators:[{type:n,args:[{selector:"tb-action-node-custom-table-config",template:'
\n \n tb.rulenode.custom-table-name\n \n \n {{ \'tb.rulenode.custom-table-name-required\' | translate }}\n \n tb.rulenode.custom-table-hint\n \n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class Cn extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.timeseriesConfigForm}onConfigurationSet(e){this.timeseriesConfigForm=this.fb.group({defaultTTL:[e?e.defaultTTL:null,[O.required,O.min(0)]],skipLatestPersistence:[!!e&&e.skipLatestPersistence,[]],useServerTs:[!!e&&e.useServerTs,[]]})}}e("TimeseriesConfigComponent",Cn),Cn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Cn,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Cn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Cn,selector:"tb-action-node-timeseries-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.default-ttl\n \n \n {{ \'tb.rulenode.default-ttl-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-default-ttl-message\' | translate }}\n \n \n \n {{ \'tb.rulenode.skip-latest-persistence\' | translate }}\n \n \n {{ \'tb.rulenode.use-server-ts\' | translate }}\n \n
tb.rulenode.use-server-ts-hint
\n
\n',dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Q.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Cn,decorators:[{type:n,args:[{selector:"tb-action-node-timeseries-config",template:'
\n \n tb.rulenode.default-ttl\n \n \n {{ \'tb.rulenode.default-ttl-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-default-ttl-message\' | translate }}\n \n \n \n {{ \'tb.rulenode.skip-latest-persistence\' | translate }}\n \n \n {{ \'tb.rulenode.use-server-ts\' | translate }}\n \n
tb.rulenode.use-server-ts-hint
\n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class Fn extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.unassignCustomerConfigForm}onConfigurationSet(e){this.unassignCustomerConfigForm=this.fb.group({customerNamePattern:[e?e.customerNamePattern:null,[O.required,O.pattern(/.*\S.*/)]],customerCacheExpiration:[e?e.customerCacheExpiration:null,[O.required,O.min(0)]]})}prepareOutputConfig(e){return e.customerNamePattern=e.customerNamePattern.trim(),e}}e("UnassignCustomerConfigComponent",Fn),Fn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Fn,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Fn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Fn,selector:"tb-action-node-un-assign-to-customer-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.customer-name-pattern\n \n \n {{ \'tb.rulenode.customer-name-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.customer-cache-expiration\n \n \n {{ \'tb.rulenode.customer-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.customer-cache-expiration-range\' | translate }}\n \n tb.rulenode.customer-cache-expiration-hint\n \n
\n',dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Fn,decorators:[{type:n,args:[{selector:"tb-action-node-un-assign-to-customer-config",template:'
\n \n tb.rulenode.customer-name-pattern\n \n \n {{ \'tb.rulenode.customer-name-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.customer-cache-expiration\n \n \n {{ \'tb.rulenode.customer-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.customer-cache-expiration-range\' | translate }}\n \n tb.rulenode.customer-cache-expiration-hint\n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class kn extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.attributeScopeMap=g,this.attributeScopes=Object.keys(g),this.telemetryTypeTranslationsMap=y,this.separatorKeysCodes=[ge,ye,xe]}configForm(){return this.deleteAttributesConfigForm}onConfigurationSet(e){this.deleteAttributesConfigForm=this.fb.group({scope:[e?e.scope:null,[O.required]],keys:[e?e.keys:null,[O.required]],sendAttributesDeletedNotification:[!!e&&e.sendAttributesDeletedNotification,[]],notifyDevice:[!!e&&e.notifyDevice,[]]}),this.deleteAttributesConfigForm.get("scope").valueChanges.subscribe((e=>{e!==g.SHARED_SCOPE&&this.deleteAttributesConfigForm.get("notifyDevice").patchValue(!1,{emitEvent:!1})}))}removeKey(e){const t=this.deleteAttributesConfigForm.get("keys").value,n=t.indexOf(e);n>=0&&(t.splice(n,1),this.deleteAttributesConfigForm.get("keys").patchValue(t,{emitEvent:!0}))}addKey(e){const t=e.input;let n=e.value;if((n||"").trim()){n=n.trim();let e=this.deleteAttributesConfigForm.get("keys").value;e&&-1!==e.indexOf(n)||(e||(e=[]),e.push(n),this.deleteAttributesConfigForm.get("keys").patchValue(e,{emitEvent:!0}))}t&&(t.value="")}}e("DeleteAttributesConfigComponent",kn),kn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:kn,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),kn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:kn,selector:"tb-action-node-delete-attributes-config",viewQueries:[{propertyName:"attributeChipList",first:!0,predicate:["attributeChipList"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'attribute.attributes-scope\' | translate }}\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n \n {{ \'tb.rulenode.attributes-keys\' | translate }}\n \n \n {{key}}\n close\n \n \n \n {{ \'tb.rulenode.attributes-keys-required\' | translate }}\n tb.rulenode.general-pattern-hint\n \n \n {{ \'tb.rulenode.send-attributes-deleted-notification\' | translate }}\n \n
tb.rulenode.send-attributes-deleted-notification-hint
\n
\n \n {{ \'tb.rulenode.notify-device\' | translate }}\n \n
tb.rulenode.notify-device-on-delete-hint
\n
\n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Q.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:be.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:be.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:be.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:be.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:kn,decorators:[{type:n,args:[{selector:"tb-action-node-delete-attributes-config",template:'
\n \n {{ \'attribute.attributes-scope\' | translate }}\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n \n {{ \'tb.rulenode.attributes-keys\' | translate }}\n \n \n {{key}}\n close\n \n \n \n {{ \'tb.rulenode.attributes-keys-required\' | translate }}\n tb.rulenode.general-pattern-hint\n \n \n {{ \'tb.rulenode.send-attributes-deleted-notification\' | translate }}\n \n
tb.rulenode.send-attributes-deleted-notification-hint
\n
\n \n {{ \'tb.rulenode.notify-device\' | translate }}\n \n
tb.rulenode.notify-device-on-delete-hint
\n
\n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]},propDecorators:{attributeChipList:[{type:o,args:["attributeChipList"]}]}});class Ln extends L{get function(){return this.functionValue}set function(e){e&&this.functionValue!==e&&(this.functionValue=e,this.setupArgumentsFormGroup(!0))}constructor(e,t){super(e),this.store=e,this.fb=t,this.maxArgs=16,this.minArgs=1,this.displayArgumentName=!1,this.mathFunctionMap=Wt,this.ArgumentType=Zt,this.attributeScopeMap=pn,this.argumentTypeMap=on,this.arguments=Object.values(Zt),this.attributeScope=Object.values(sn),this.propagateChange=null,this.valueChangeSubscription=[]}ngOnInit(){this.argumentsFormGroup=this.fb.group({arguments:this.fb.array([])}),this.valueChangeSubscription.push(this.argumentsFormGroup.valueChanges.subscribe((()=>{this.updateModel()}))),this.setupArgumentsFormGroup()}onDrop(e){const t=this.argumentsFormArray,n=t.at(e.previousIndex);t.removeAt(e.previousIndex),t.insert(e.currentIndex,n),this.updateArgumentNames()}get argumentsFormArray(){return this.argumentsFormGroup.get("arguments")}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.argumentsFormGroup.disable({emitEvent:!1}):(this.argumentsFormGroup.enable({emitEvent:!1}),this.argumentsFormArray.controls.forEach((e=>this.updateArgumentControlValidators(e))))}ngOnDestroy(){this.valueChangeSubscription.length&&this.valueChangeSubscription.forEach((e=>e.unsubscribe()))}writeValue(e){const t=[];e&&e.forEach(((e,n)=>{t.push(this.createArgumentControl(e,n))})),this.argumentsFormGroup.setControl("arguments",this.fb.array(t),{emitEvent:!1}),this.setupArgumentsFormGroup()}removeArgument(e){this.argumentsFormArray.removeAt(e),this.updateArgumentNames()}addArgument(e=!0){const t=this.argumentsFormArray,n=this.createArgumentControl(null,t.length);t.push(n,{emitEvent:e})}validate(e){return this.argumentsFormGroup.valid?null:{argumentsRequired:!0}}setupArgumentsFormGroup(e=!1){if(this.function&&(this.maxArgs=this.mathFunctionMap.get(this.function).maxArgs,this.minArgs=this.mathFunctionMap.get(this.function).minArgs,this.displayArgumentName=this.function===Yt.CUSTOM),this.argumentsFormGroup){for(this.argumentsFormGroup.get("arguments").setValidators([O.minLength(this.minArgs),O.maxLength(this.maxArgs)]);this.argumentsFormArray.length>this.maxArgs;)this.removeArgument(this.maxArgs-1);for(;this.argumentsFormArray.length{this.updateArgumentControlValidators(n),n.get("attributeScope").updateValueAndValidity({emitEvent:!1}),n.get("defaultValue").updateValueAndValidity({emitEvent:!1})}))),n}updateArgumentControlValidators(e){const t=e.get("type").value;t===Zt.ATTRIBUTE?e.get("attributeScope").enable({emitEvent:!1}):e.get("attributeScope").disable({emitEvent:!1}),t&&t!==Zt.CONSTANT?e.get("defaultValue").enable({emitEvent:!1}):e.get("defaultValue").disable({emitEvent:!1})}updateArgumentNames(){this.argumentsFormArray.controls.forEach(((e,t)=>{e.get("name").setValue(ln[t])}))}updateModel(){const e=this.argumentsFormArray.value;e.length&&this.argumentsFormGroup.valid?this.propagateChange(e):this.propagateChange(null)}}e("ArgumentsMapConfigComponent",Ln),Ln.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Ln,deps:[{token:P.Store},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Ln.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Ln,selector:"tb-arguments-map-config",inputs:{disabled:"disabled",function:"function"},providers:[{provide:B,useExisting:a((()=>Ln)),multi:!0},{provide:K,useExisting:a((()=>Ln)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n\n
\n \n \n
\n \n
\n {{argumentControl.get(\'name\').value}}.\n
\n \n tb.rulenode.argument-source-field-input\n \n \n {{ argumentTypeMap.get(argumentControl.get(\'type\').value)?.name | translate }}\n \n \n {{ argumentTypeMap.get(argument).name | translate }}\n \n {{ argumentTypeMap.get(argument).description }}\n \n \n \n \n tb.rulenode.argument-source-field-input-required\n \n \n
\n \n tb.rulenode.argument-key-field-input\n \n \n help\n \n \n tb.rulenode.argument-key-field-input-required\n \n \n \n tb.rulenode.constant-value-field-input\n \n \n tb.rulenode.constant-value-field-input-required\n \n \n \n tb.rulenode.default-value-field-input\n \n \n
\n \n tb.rulenode.attribute-scope-field-input\n \n \n {{ attributeScopeMap.get(scope) | translate }}\n \n \n \n tb.rulenode.attribute-scope-field-input-required\n \n \n
\n \n
\n
\n
\n
\n
\n
\n tb.rulenode.no-arguments-prompt\n
\n \n
\n',styles:[":host .mat-mdc-list-item.tb-argument{border:solid rgba(0,0,0,.25) 1px;border-radius:4px;padding:10px 0;margin-bottom:16px}:host .arguments-list{padding:0}\n"],dependencies:[{kind:"directive",type:H.NgClass,selector:"[ngClass]",inputs:["class","ngClass"]},{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:de.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:de.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Y.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"directive",type:X.MatSelectTrigger,selector:"mat-select-trigger"},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:Ne.MatList,selector:"mat-list",exportAs:["matList"]},{kind:"component",type:Ne.MatListItem,selector:"mat-list-item, a[mat-list-item], button[mat-list-item]",inputs:["activated"],exportAs:["matListItem"]},{kind:"directive",type:Se.CdkDropList,selector:"[cdkDropList], cdk-drop-list",inputs:["cdkDropListConnectedTo","cdkDropListData","cdkDropListOrientation","id","cdkDropListLockAxis","cdkDropListDisabled","cdkDropListSortingDisabled","cdkDropListEnterPredicate","cdkDropListSortPredicate","cdkDropListAutoScrollDisabled","cdkDropListAutoScrollStep"],outputs:["cdkDropListDropped","cdkDropListEntered","cdkDropListExited","cdkDropListSorted"],exportAs:["cdkDropList"]},{kind:"directive",type:Se.CdkDrag,selector:"[cdkDrag]",inputs:["cdkDragData","cdkDragLockAxis","cdkDragRootElement","cdkDragBoundary","cdkDragStartDelay","cdkDragFreeDragPosition","cdkDragDisabled","cdkDragConstrainPosition","cdkDragPreviewClass","cdkDragPreviewContainer"],outputs:["cdkDragStarted","cdkDragReleased","cdkDragEnded","cdkDragEntered","cdkDragExited","cdkDragDropped","cdkDragMoved"],exportAs:["cdkDrag"]},{kind:"directive",type:Se.CdkDragHandle,selector:"[cdkDragHandle]",inputs:["cdkDragHandleDisabled"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:W.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:Ie.DefaultClassDirective,selector:" [ngClass], [ngClass.xs], [ngClass.sm], [ngClass.md], [ngClass.lg], [ngClass.xl], [ngClass.lt-sm], [ngClass.lt-md], [ngClass.lt-lg], [ngClass.lt-xl], [ngClass.gt-xs], [ngClass.gt-sm], [ngClass.gt-md], [ngClass.gt-lg]",inputs:["ngClass","ngClass.xs","ngClass.sm","ngClass.md","ngClass.lg","ngClass.xl","ngClass.lt-sm","ngClass.lt-md","ngClass.lt-lg","ngClass.lt-xl","ngClass.gt-xs","ngClass.gt-sm","ngClass.gt-md","ngClass.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.FormControlDirective,selector:"[formControl]",inputs:["formControl","disabled","ngModel"],outputs:["ngModelChange"],exportAs:["ngForm"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormArrayName,selector:"[formArrayName]",inputs:["formArrayName"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Ln,decorators:[{type:n,args:[{selector:"tb-arguments-map-config",providers:[{provide:B,useExisting:a((()=>Ln)),multi:!0},{provide:K,useExisting:a((()=>Ln)),multi:!0}],template:'
\n\n
\n \n \n
\n \n
\n {{argumentControl.get(\'name\').value}}.\n
\n \n tb.rulenode.argument-source-field-input\n \n \n {{ argumentTypeMap.get(argumentControl.get(\'type\').value)?.name | translate }}\n \n \n {{ argumentTypeMap.get(argument).name | translate }}\n \n {{ argumentTypeMap.get(argument).description }}\n \n \n \n \n tb.rulenode.argument-source-field-input-required\n \n \n
\n \n tb.rulenode.argument-key-field-input\n \n \n help\n \n \n tb.rulenode.argument-key-field-input-required\n \n \n \n tb.rulenode.constant-value-field-input\n \n \n tb.rulenode.constant-value-field-input-required\n \n \n \n tb.rulenode.default-value-field-input\n \n \n
\n \n tb.rulenode.attribute-scope-field-input\n \n \n {{ attributeScopeMap.get(scope) | translate }}\n \n \n \n tb.rulenode.attribute-scope-field-input-required\n \n \n
\n \n
\n
\n
\n
\n
\n
\n tb.rulenode.no-arguments-prompt\n
\n \n
\n',styles:[":host .mat-mdc-list-item.tb-argument{border:solid rgba(0,0,0,.25) 1px;border-radius:4px;padding:10px 0;margin-bottom:16px}:host .arguments-list{padding:0}\n"]}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder}]},propDecorators:{disabled:[{type:i}],function:[{type:i}]}});class Tn extends L{get required(){return this.requiredValue}set required(e){this.requiredValue=Fe(e)}constructor(e,t,n,r){super(e),this.store=e,this.translate=t,this.injector=n,this.fb=r,this.searchText="",this.dirty=!1,this.mathOperation=[...Wt.values()],this.propagateChange=null}ngOnInit(){this.mathFunctionForm=this.fb.group({operation:[""]}),this.filteredOptions=this.mathFunctionForm.get("operation").valueChanges.pipe(qe((e=>{let t;t="string"==typeof e&&Yt[e]?Yt[e]:null,this.updateView(t)})),Ae((e=>(this.searchText=e||"",e?this._filter(e):this.mathOperation.slice()))))}_filter(e){const t=e.toLowerCase();return this.mathOperation.filter((e=>e.name.toLowerCase().includes(t)||e.value.toLowerCase().includes(t)))}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.mathFunctionForm.disable({emitEvent:!1}):this.mathFunctionForm.enable({emitEvent:!1})}mathFunctionDisplayFn(e){if(e){const t=Wt.get(e);return t.value+" | "+t.name}return""}writeValue(e){this.modelValue=e,this.mathFunctionForm.get("operation").setValue(e,{emitEvent:!1}),this.dirty=!0}updateView(e){this.modelValue!==e&&(this.modelValue=e,this.propagateChange(this.modelValue))}onFocus(){this.dirty&&(this.mathFunctionForm.get("operation").updateValueAndValidity({onlySelf:!0}),this.dirty=!1)}clear(){this.mathFunctionForm.get("operation").patchValue(""),setTimeout((()=>{this.operationInput.nativeElement.blur(),this.operationInput.nativeElement.focus()}),0)}}e("MathFunctionAutocompleteComponent",Tn),Tn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Tn,deps:[{token:P.Store},{token:Z.TranslateService},{token:t.Injector},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Tn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Tn,selector:"tb-math-function-autocomplete",inputs:{required:"required",disabled:"disabled"},providers:[{provide:B,useExisting:a((()=>Tn)),multi:!0}],viewQueries:[{propertyName:"operationInput",first:!0,predicate:["operationInput"],descendants:!0,static:!0}],usesInheritance:!0,ngImport:t,template:'\n tb.rulenode.functions-field-input\n \n \n \n \n \n \n {{ option.description }}\n \n \n \n tb.rulenode.no-option-found\n \n \n\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:de.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:Ve.MatAutocomplete,selector:"mat-autocomplete",inputs:["disableRipple","hideSingleSelectionIndicator"],exportAs:["matAutocomplete"]},{kind:"directive",type:Ve.MatAutocompleteTrigger,selector:"input[matAutocomplete], textarea[matAutocomplete]",exportAs:["matAutocompleteTrigger"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:H.AsyncPipe,name:"async"},{kind:"pipe",type:Pe.HighlightPipe,name:"highlight"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Tn,decorators:[{type:n,args:[{selector:"tb-math-function-autocomplete",providers:[{provide:B,useExisting:a((()=>Tn)),multi:!0}],template:'\n tb.rulenode.functions-field-input\n \n \n \n \n \n \n {{ option.description }}\n \n \n \n tb.rulenode.no-option-found\n \n \n\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:Z.TranslateService},{type:t.Injector},{type:R.UntypedFormBuilder}]},propDecorators:{required:[{type:i}],disabled:[{type:i}],operationInput:[{type:o,args:["operationInput",{static:!0}]}]}});class In extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.MathFunction=Yt,this.ArgumentTypeResult=Xt,this.argumentTypeResultMap=an,this.attributeScopeMap=pn,this.argumentsResult=Object.values(Xt),this.attributeScopeResult=Object.values(mn)}configForm(){return this.mathFunctionConfigForm}onConfigurationSet(e){this.mathFunctionConfigForm=this.fb.group({operation:[e?e.operation:null,[O.required]],arguments:[e?e.arguments:null,[O.required]],customFunction:[e?e.customFunction:"",[O.required]],result:this.fb.group({type:[e?e.result.type:null,[O.required]],attributeScope:[e?e.result.attributeScope:null,[O.required]],key:[e?e.result.key:"",[O.required]],resultValuePrecision:[e?e.result.resultValuePrecision:0],addToBody:[!!e&&e.result.addToBody],addToMetadata:[!!e&&e.result.addToMetadata]})})}updateValidators(e){const t=this.mathFunctionConfigForm.get("operation").value,n=this.mathFunctionConfigForm.get("result.type").value;t===Yt.CUSTOM?(this.mathFunctionConfigForm.get("customFunction").enable({emitEvent:!1}),null===this.mathFunctionConfigForm.get("customFunction").value&&this.mathFunctionConfigForm.get("customFunction").patchValue("(x - 32) / 1.8",{emitEvent:!1})):this.mathFunctionConfigForm.get("customFunction").disable({emitEvent:!1}),n===Xt.ATTRIBUTE?this.mathFunctionConfigForm.get("result.attributeScope").enable({emitEvent:!1}):this.mathFunctionConfigForm.get("result.attributeScope").disable({emitEvent:!1}),this.mathFunctionConfigForm.get("customFunction").updateValueAndValidity({emitEvent:e}),this.mathFunctionConfigForm.get("result.attributeScope").updateValueAndValidity({emitEvent:e})}validatorTriggers(){return["operation","result.type"]}}e("MathFunctionConfigComponent",In),In.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:In,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),In.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:In,selector:"tb-action-node-math-function-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n
\n tb.rulenode.argument-tile\n \n \n
\n
\n {{\'tb.rulenode.custom-expression-field-input\' | translate }} *\n \n \n \n tb.rulenode.custom-expression-field-input-required\n \n tb.rulenode.custom-expression-field-input-hint\n \n
\n
\n tb.rulenode.result-title\n
\n \n tb.rulenode.type-field-input\n \n \n {{ argumentTypeResultMap.get(mathFunctionConfigForm.get(\'result.type\').value)?.name | translate }}\n \n \n {{ argumentTypeResultMap.get(argument).name | translate }}\n \n {{ argumentTypeResultMap.get(argument).description }}\n \n \n \n \n tb.rulenode.type-field-input-required\n \n \n
\n \n tb.rulenode.attribute-scope-field-input\n \n \n {{ attributeScopeMap.get(scope) | translate }}\n \n \n \n \n tb.rulenode.key-field-input\n \n help\n \n tb.rulenode.key-field-input-required\n \n \n
\n
\n \n tb.rulenode.number-floating-point-field-input\n \n \n \n
\n
\n \n {{\'tb.rulenode.add-to-message-field-input\' | translate }}\n \n \n {{\'tb.rulenode.add-to-metadata-field-input\' | translate}}\n \n
\n
\n
\n
\n',styles:[":host ::ng-deep .fields-group{padding:0 16px 8px;margin:10px 0;border:1px groove rgba(0,0,0,.25);border-radius:4px}:host ::ng-deep .fields-group .mat-mdc-form-field .mat-mdc-form-field-infix{width:100%}:host ::ng-deep .fields-group legend{color:#000000b3;width:-moz-fit-content;width:fit-content}:host ::ng-deep .fields-group legend+*{display:block}:host ::ng-deep .fields-group legend+*.no-margin-top{margin-top:0}\n"],dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Q.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Y.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"directive",type:X.MatSelectTrigger,selector:"mat-select-trigger"},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:W.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:R.FormGroupName,selector:"[formGroupName]",inputs:["formGroupName"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Ln,selector:"tb-arguments-map-config",inputs:["disabled","function"]},{kind:"component",type:Tn,selector:"tb-math-function-autocomplete",inputs:["required","disabled"]},{kind:"pipe",type:he.SafePipe,name:"safe"},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:In,decorators:[{type:n,args:[{selector:"tb-action-node-math-function-config",template:'
\n \n \n
\n tb.rulenode.argument-tile\n \n \n
\n
\n {{\'tb.rulenode.custom-expression-field-input\' | translate }} *\n \n \n \n tb.rulenode.custom-expression-field-input-required\n \n tb.rulenode.custom-expression-field-input-hint\n \n
\n
\n tb.rulenode.result-title\n
\n \n tb.rulenode.type-field-input\n \n \n {{ argumentTypeResultMap.get(mathFunctionConfigForm.get(\'result.type\').value)?.name | translate }}\n \n \n {{ argumentTypeResultMap.get(argument).name | translate }}\n \n {{ argumentTypeResultMap.get(argument).description }}\n \n \n \n \n tb.rulenode.type-field-input-required\n \n \n
\n \n tb.rulenode.attribute-scope-field-input\n \n \n {{ attributeScopeMap.get(scope) | translate }}\n \n \n \n \n tb.rulenode.key-field-input\n \n help\n \n tb.rulenode.key-field-input-required\n \n \n
\n
\n \n tb.rulenode.number-floating-point-field-input\n \n \n \n
\n
\n \n {{\'tb.rulenode.add-to-message-field-input\' | translate }}\n \n \n {{\'tb.rulenode.add-to-metadata-field-input\' | translate}}\n \n
\n
\n
\n
\n',styles:[":host ::ng-deep .fields-group{padding:0 16px 8px;margin:10px 0;border:1px groove rgba(0,0,0,.25);border-radius:4px}:host ::ng-deep .fields-group .mat-mdc-form-field .mat-mdc-form-field-infix{width:100%}:host ::ng-deep .fields-group legend{color:#000000b3;width:-moz-fit-content;width:fit-content}:host ::ng-deep .fields-group legend+*{display:block}:host ::ng-deep .fields-group legend+*.no-margin-top{margin-top:0}\n"]}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class Nn{constructor(){this.textAlign="left"}}e("ExampleHintComponent",Nn),Nn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Nn,deps:[],target:t.ɵɵFactoryTarget.Component}),Nn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Nn,selector:"tb-example-hint",inputs:{hintText:"hintText",popupHelpLink:"popupHelpLink",textAlign:"textAlign"},ngImport:t,template:'
\n
\n
\n
\n
\n',styles:[":host .space-between{display:flex;justify-content:space-between;gap:20px}:host .space-between .see-example{display:flex;flex-shrink:0}:host .hint-text{width:100%}\n"],dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:He.HelpPopupComponent,selector:"[tb-help-popup], [tb-help-popup-content]",inputs:["tb-help-popup","tb-help-popup-content","trigger-text","trigger-style","tb-help-popup-placement","tb-help-popup-style","hintMode"]},{kind:"pipe",type:he.SafePipe,name:"safe"},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Nn,decorators:[{type:n,args:[{selector:"tb-example-hint",template:'
\n
\n
\n
\n
\n',styles:[":host .space-between{display:flex;justify-content:space-between;gap:20px}:host .space-between .see-example{display:flex;flex-shrink:0}:host .hint-text{width:100%}\n"]}]}],propDecorators:{hintText:[{type:i}],popupHelpLink:[{type:i}],textAlign:[{type:i}]}});class Sn{constructor(e,t){this.injector=e,this.fb=t,this.propagateChange=()=>{},this.destroy$=new _e,this.disabled=!1,this.uniqueKeyValuePairValidator=!1,this.required=!1,this.duplicateValuesValidator=e=>e.controls.key.value===e.controls.value.value&&e.controls.key.value&&e.controls.value.value?{uniqueKeyValuePair:!0}:null,this.oneMapRequiredValidator=e=>e.get("keyVals").value.length,this.propagateNestedErrors=e=>{if(this.kvListFormGroup&&this.kvListFormGroup.get("keyVals")&&"VALID"===this.kvListFormGroup.get("keyVals")?.status)return null;const t={};if(this.kvListFormGroup&&this.kvListFormGroup.setErrors(null),e instanceof z||e instanceof U){if(e.errors)for(const n of Object.keys(e.errors))t[n]=!0;for(const n of Object.keys(e.controls)){const r=this.propagateNestedErrors(e.controls[n]);if(r&&Object.keys(r).length)for(const e of Object.keys(r))t[e]=!0}return t}if(e.errors)for(const n of Object.keys(e.errors))t[n]=!0;return ae(t,{})?null:t}}ngOnInit(){this.ngControl=this.injector.get(_),null!=this.ngControl&&(this.ngControl.valueAccessor=this),this.kvListFormGroup=this.fb.group({keyVals:this.fb.array([])},{validators:[this.propagateNestedErrors,this.oneMapRequiredValidator]}),this.kvListFormGroup.valueChanges.pipe(Be(this.destroy$)).subscribe((()=>{this.updateModel()}))}ngOnDestroy(){this.destroy$.next(),this.destroy$.complete()}keyValsFormArray(){return this.kvListFormGroup.get("keyVals")}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.kvListFormGroup.disable({emitEvent:!1}):this.kvListFormGroup.enable({emitEvent:!1})}writeValue(e){const t=Object.keys(e).map((t=>({key:t,value:e[t]})));if(this.keyValsFormArray().length===t.length)this.keyValsFormArray().patchValue(t,{emitEvent:!1});else{const e=[];t.forEach((t=>{e.push(this.fb.group({key:[t.key,[O.required,O.pattern(/(?:.|\s)*\S(&:.|\s)*/)]],value:[t.value,[O.required,O.pattern(/(?:.|\s)*\S(&:.|\s)*/)]]},{validators:this.uniqueKeyValuePairValidator?[this.duplicateValuesValidator]:[]}))})),this.kvListFormGroup.setControl("keyVals",this.fb.array(e,this.propagateNestedErrors),{emitEvent:!1})}}removeKeyVal(e){this.keyValsFormArray().removeAt(e)}addKeyVal(){this.keyValsFormArray().push(this.fb.group({key:["",[O.required,O.pattern(/(?:.|\s)*\S(&:.|\s)*/)]],value:["",[O.required,O.pattern(/(?:.|\s)*\S(&:.|\s)*/)]]},{validators:this.uniqueKeyValuePairValidator?[this.duplicateValuesValidator]:[]}))}validate(){const e=this.kvListFormGroup.get("keyVals").value;if(!e.length&&this.required)return{kvMapRequired:!0};if(!this.kvListFormGroup.valid)return{kvFieldsRequired:!0};if(this.uniqueKeyValuePairValidator)for(const t of e)if(t.key===t.value)return{uniqueKeyValuePair:!0};return null}updateModel(){const e=this.kvListFormGroup.get("keyVals").value;if(this.required&&!e.length||!this.kvListFormGroup.valid)this.propagateChange(null);else{const t={};e.forEach((e=>{t[e.key]=e.value})),this.propagateChange(t)}}}e("KvMapConfigComponent",Sn),Sn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Sn,deps:[{token:t.Injector},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Sn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Sn,selector:"tb-kv-map-config",inputs:{disabled:"disabled",uniqueKeyValuePairValidator:"uniqueKeyValuePairValidator",labelText:"labelText",requiredText:"requiredText",keyText:"keyText",keyRequiredText:"keyRequiredText",valText:"valText",valRequiredText:"valRequiredText",hintText:"hintText",popupHelpLink:"popupHelpLink",required:"required"},providers:[{provide:B,useExisting:a((()=>Sn)),multi:!0},{provide:K,useExisting:a((()=>Sn)),multi:!0}],ngImport:t,template:'
\n
\n
{{ labelText }}
\n
\n {{ requiredText }}\n
\n
\n tb.rulenode.map-fields-required\n
\n
\n {{ \'tb.key-val.unique-key-value-pair-error\' | translate:\n {\n valText: valText,\n keyText: keyText\n } }}\n
\n
\n
\n
\n
\n
{{ keyText }}
\n
{{ valText }}
\n
\n
\n
\n
\n \n \n \n \n \n \n
\n \n
\n
\n
\n
\n
\n
\n \n
\n \n
\n',styles:[":host .field-space{flex:1 1 50%}:host .actions-header{width:40px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:de.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:de.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.FormControlDirective,selector:"[formControl]",inputs:["formControl","disabled","ngModel"],outputs:["ngModelChange"],exportAs:["ngForm"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Nn,selector:"tb-example-hint",inputs:["hintText","popupHelpLink","textAlign"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),Oe([T()],Sn.prototype,"disabled",void 0),Oe([T()],Sn.prototype,"uniqueKeyValuePairValidator",void 0),Oe([T()],Sn.prototype,"required",void 0),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Sn,decorators:[{type:n,args:[{selector:"tb-kv-map-config",providers:[{provide:B,useExisting:a((()=>Sn)),multi:!0},{provide:K,useExisting:a((()=>Sn)),multi:!0}],template:'
\n
\n
{{ labelText }}
\n
\n {{ requiredText }}\n
\n
\n tb.rulenode.map-fields-required\n
\n
\n {{ \'tb.key-val.unique-key-value-pair-error\' | translate:\n {\n valText: valText,\n keyText: keyText\n } }}\n
\n
\n
\n
\n
\n
{{ keyText }}
\n
{{ valText }}
\n
\n
\n
\n
\n \n \n \n \n \n \n
\n \n
\n
\n
\n
\n
\n
\n \n
\n \n
\n',styles:[":host .field-space{flex:1 1 50%}:host .actions-header{width:40px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:t.Injector},{type:R.FormBuilder}]},propDecorators:{disabled:[{type:i}],uniqueKeyValuePairValidator:[{type:i}],labelText:[{type:i}],requiredText:[{type:i}],keyText:[{type:i}],keyRequiredText:[{type:i}],valText:[{type:i}],valRequiredText:[{type:i}],hintText:[{type:i}],popupHelpLink:[{type:i}],required:[{type:i}]}});class qn extends L{get required(){return this.requiredValue}set required(e){this.requiredValue=Fe(e)}constructor(e,t){super(e),this.store=e,this.fb=t,this.directionTypes=Object.values(v),this.directionTypeTranslations=C,this.entityType=F,this.propagateChange=null}ngOnInit(){this.deviceRelationsQueryFormGroup=this.fb.group({fetchLastLevelOnly:[!1,[]],direction:[null,[O.required]],maxLevel:[null,[O.min(1)]],relationType:[null],deviceTypes:[null,[O.required]]}),this.deviceRelationsQueryFormGroup.valueChanges.subscribe((e=>{this.deviceRelationsQueryFormGroup.valid?this.propagateChange(e):this.propagateChange(null)}))}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.deviceRelationsQueryFormGroup.disable({emitEvent:!1}):this.deviceRelationsQueryFormGroup.enable({emitEvent:!1})}writeValue(e){this.deviceRelationsQueryFormGroup.reset(e,{emitEvent:!1})}}e("DeviceRelationsQueryConfigComponent",qn),qn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:qn,deps:[{token:P.Store},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),qn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:qn,selector:"tb-device-relations-query-config",inputs:{disabled:"disabled",required:"required"},providers:[{provide:B,useExisting:a((()=>qn)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }} tb.rulenode.relations-query-config-direction-suffix\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n {{ \'tb.rulenode.max-relation-level-error\' | translate }}\n \n \n
\n
\n \n {{ \'alias.last-level-relation\' | translate }}\n \n
\n \n \n \n help\n \n
\n',styles:[":host .last-level-slide-toggle{margin:8px 0 24px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:je.EntitySubTypeListComponent,selector:"tb-entity-subtype-list",inputs:["required","floatLabel","label","disabled","entityType","emptyInputPlaceholder","filledInputPlaceholder","appearance","subscriptSizing","additionalClasses"]},{kind:"component",type:$e.RelationTypeAutocompleteComponent,selector:"tb-relation-type-autocomplete",inputs:["showLabel","additionalClasses","appearance","required","disabled","subscriptSizing"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Y.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:te.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:ne.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:qn,decorators:[{type:n,args:[{selector:"tb-device-relations-query-config",providers:[{provide:B,useExisting:a((()=>qn)),multi:!0}],template:'
\n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }} tb.rulenode.relations-query-config-direction-suffix\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n {{ \'tb.rulenode.max-relation-level-error\' | translate }}\n \n \n
\n
\n \n {{ \'alias.last-level-relation\' | translate }}\n \n
\n \n \n \n help\n \n
\n',styles:[":host .last-level-slide-toggle{margin:8px 0 24px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder}]},propDecorators:{disabled:[{type:i}],required:[{type:i}]}});class An extends L{get required(){return this.requiredValue}set required(e){this.requiredValue=Fe(e)}constructor(e,t){super(e),this.store=e,this.fb=t,this.directionTypes=Object.values(v),this.directionTypeTranslations=C,this.propagateChange=null}ngOnInit(){this.relationsQueryFormGroup=this.fb.group({fetchLastLevelOnly:[!1,[]],direction:[null,[O.required]],maxLevel:[null,[O.min(1)]],filters:[null]}),this.relationsQueryFormGroup.valueChanges.subscribe((e=>{this.relationsQueryFormGroup.valid?this.propagateChange(e):this.propagateChange(null)}))}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.relationsQueryFormGroup.disable({emitEvent:!1}):this.relationsQueryFormGroup.enable({emitEvent:!1})}writeValue(e){this.relationsQueryFormGroup.reset(e||{},{emitEvent:!1})}}e("RelationsQueryConfigComponent",An),An.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:An,deps:[{token:P.Store},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),An.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:An,selector:"tb-relations-query-config",inputs:{disabled:"disabled",required:"required"},providers:[{provide:B,useExisting:a((()=>An)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n
tb.rulenode.relations-query
\n
\n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }} tb.rulenode.relations-query-config-direction-suffix\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n {{ \'tb.rulenode.max-relation-level-error\' | translate }}\n \n \n
\n
\n \n {{ \'alias.last-level-relation\' | translate }}\n \n
\n
\n
\n
relation.relation-filters
\n \n \n
\n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:te.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:ne.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"component",type:Qe.RelationFiltersComponent,selector:"tb-relation-filters",inputs:["disabled","allowedEntityTypes"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:An,decorators:[{type:n,args:[{selector:"tb-relations-query-config",providers:[{provide:B,useExisting:a((()=>An)),multi:!0}],template:'
\n
tb.rulenode.relations-query
\n
\n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }} tb.rulenode.relations-query-config-direction-suffix\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n {{ \'tb.rulenode.max-relation-level-error\' | translate }}\n \n \n
\n
\n \n {{ \'alias.last-level-relation\' | translate }}\n \n
\n
\n
\n
relation.relation-filters
\n \n \n
\n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder}]},propDecorators:{disabled:[{type:i}],required:[{type:i}]}});class Mn extends L{get required(){return this.requiredValue}set required(e){this.requiredValue=Fe(e)}constructor(e,t,n,r){super(e),this.store=e,this.translate=t,this.truncate=n,this.fb=r,this.placeholder="tb.rulenode.add-message-type",this.separatorKeysCodes=[ge,ye,xe],this.messageTypes=[],this.messageTypesList=[],this.searchText="",this.propagateChange=e=>{},this.messageTypeConfigForm=this.fb.group({messageType:[null]});for(const e of Object.keys(I))this.messageTypesList.push({name:N.get(I[e]),value:e})}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}ngOnInit(){this.filteredMessageTypes=this.messageTypeConfigForm.get("messageType").valueChanges.pipe(Me(""),Ae((e=>e||"")),Ee((e=>this.fetchMessageTypes(e))),Ge())}setDisabledState(e){this.disabled=e,this.disabled?this.messageTypeConfigForm.disable({emitEvent:!1}):this.messageTypeConfigForm.enable({emitEvent:!1})}writeValue(e){this.searchText="",this.messageTypes.length=0,e&&e.forEach((e=>{const t=this.messageTypesList.find((t=>t.value===e));t?this.messageTypes.push({name:t.name,value:t.value}):this.messageTypes.push({name:e,value:e})}))}displayMessageTypeFn(e){return e?e.name:void 0}textIsNotEmpty(e){return e&&e.length>0}createMessageType(e,t){e.preventDefault(),this.transformMessageType(t)}add(e){this.transformMessageType(e.value)}fetchMessageTypes(e){if(this.searchText=e,this.searchText&&this.searchText.length){const e=this.searchText.toUpperCase();return Ke(this.messageTypesList.filter((t=>t.name.toUpperCase().includes(e))))}return Ke(this.messageTypesList)}transformMessageType(e){if((e||"").trim()){let t;const n=e.trim(),r=this.messageTypesList.find((e=>e.name===n));t=r?{name:r.name,value:r.value}:{name:n,value:n},t&&this.addMessageType(t)}this.clear("")}remove(e){const t=this.messageTypes.indexOf(e);t>=0&&(this.messageTypes.splice(t,1),this.updateModel())}selected(e){this.addMessageType(e.option.value),this.clear("")}addMessageType(e){-1===this.messageTypes.findIndex((t=>t.value===e.value))&&(this.messageTypes.push(e),this.updateModel())}onFocus(){this.messageTypeConfigForm.get("messageType").updateValueAndValidity({onlySelf:!0,emitEvent:!0})}clear(e=""){this.messageTypeInput.nativeElement.value=e,this.messageTypeConfigForm.get("messageType").patchValue(null,{emitEvent:!0}),setTimeout((()=>{this.messageTypeInput.nativeElement.blur(),this.messageTypeInput.nativeElement.focus()}),0)}updateModel(){const e=this.messageTypes.map((e=>e.value));this.required?(this.chipList.errorState=!e.length,this.propagateChange(e.length>0?e:null)):(this.chipList.errorState=!1,this.propagateChange(e))}}e("MessageTypesConfigComponent",Mn),Mn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Mn,deps:[{token:P.Store},{token:Z.TranslateService},{token:S.TruncatePipe},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Mn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Mn,selector:"tb-message-types-config",inputs:{required:"required",label:"label",placeholder:"placeholder",disabled:"disabled"},providers:[{provide:B,useExisting:a((()=>Mn)),multi:!0}],viewQueries:[{propertyName:"chipList",first:!0,predicate:["chipList"],descendants:!0},{propertyName:"matAutocomplete",first:!0,predicate:["messageTypeAutocomplete"],descendants:!0},{propertyName:"messageTypeInput",first:!0,predicate:["messageTypeInput"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'\n {{ label }}\n \n \n {{messageType.name}}\n close\n \n \n \n \n \n \n \n \n
\n
\n tb.rulenode.no-message-types-found\n
\n \n \n {{ \'tb.rulenode.no-message-type-matching\' | translate :\n {messageType: truncate.transform(searchText, true, 6, '...')}\n }}\n \n \n \n tb.rulenode.create-new-message-type\n \n
\n
\n
\n help\n \n {{ \'tb.rulenode.select-message-types-required\' | translate }}\n \n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Y.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:Ve.MatAutocomplete,selector:"mat-autocomplete",inputs:["disableRipple","hideSingleSelectionIndicator"],exportAs:["matAutocomplete"]},{kind:"directive",type:Ve.MatAutocompleteTrigger,selector:"input[matAutocomplete], textarea[matAutocomplete]",exportAs:["matAutocompleteTrigger"]},{kind:"directive",type:Ve.MatAutocompleteOrigin,selector:"[matAutocompleteOrigin]",exportAs:["matAutocompleteOrigin"]},{kind:"component",type:be.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:be.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:be.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:be.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:H.AsyncPipe,name:"async"},{kind:"pipe",type:Pe.HighlightPipe,name:"highlight"},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Mn,decorators:[{type:n,args:[{selector:"tb-message-types-config",providers:[{provide:B,useExisting:a((()=>Mn)),multi:!0}],template:'\n {{ label }}\n \n \n {{messageType.name}}\n close\n \n \n \n \n \n \n \n \n
\n
\n tb.rulenode.no-message-types-found\n
\n \n \n {{ \'tb.rulenode.no-message-type-matching\' | translate :\n {messageType: truncate.transform(searchText, true, 6, '...')}\n }}\n \n \n \n tb.rulenode.create-new-message-type\n \n
\n
\n
\n help\n \n {{ \'tb.rulenode.select-message-types-required\' | translate }}\n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:Z.TranslateService},{type:S.TruncatePipe},{type:R.FormBuilder}]},propDecorators:{required:[{type:i}],label:[{type:i}],placeholder:[{type:i}],disabled:[{type:i}],chipList:[{type:o,args:["chipList",{static:!1}]}],matAutocomplete:[{type:o,args:["messageTypeAutocomplete",{static:!1}]}],messageTypeInput:[{type:o,args:["messageTypeInput",{static:!1}]}]}});class En extends L{get required(){return this.requiredValue}set required(e){this.requiredValue=Fe(e)}constructor(e,t){super(e),this.store=e,this.fb=t,this.subscriptions=[],this.disableCertPemCredentials=!1,this.passwordFieldRequired=!0,this.allCredentialsTypes=zt,this.credentialsTypeTranslationsMap=Ut,this.propagateChange=e=>{}}ngOnInit(){this.credentialsConfigFormGroup=this.fb.group({type:[null,[O.required]],username:[null,[]],password:[null,[]],caCert:[null,[]],caCertFileName:[null,[]],privateKey:[null,[]],privateKeyFileName:[null,[]],cert:[null,[]],certFileName:[null,[]]}),this.subscriptions.push(this.credentialsConfigFormGroup.valueChanges.subscribe((()=>{this.updateView()}))),this.subscriptions.push(this.credentialsConfigFormGroup.get("type").valueChanges.subscribe((()=>{this.credentialsTypeChanged()})))}ngOnChanges(e){for(const t of Object.keys(e)){const n=e[t];if(!n.firstChange&&n.currentValue!==n.previousValue&&n.currentValue&&"disableCertPemCredentials"===t){"cert.PEM"===this.credentialsConfigFormGroup.get("type").value&&setTimeout((()=>{this.credentialsConfigFormGroup.get("type").patchValue("anonymous",{emitEvent:!0})}))}}}ngOnDestroy(){this.subscriptions.forEach((e=>e.unsubscribe()))}writeValue(e){ie(e)&&(this.credentialsConfigFormGroup.reset(e,{emitEvent:!1}),this.updateValidators())}setDisabledState(e){e?this.credentialsConfigFormGroup.disable({emitEvent:!1}):(this.credentialsConfigFormGroup.enable({emitEvent:!1}),this.updateValidators())}updateView(){let e=this.credentialsConfigFormGroup.value;const t=e.type;switch(t){case"anonymous":e={type:t};break;case"basic":e={type:t,username:e.username,password:e.password};break;case"cert.PEM":delete e.username}this.propagateChange(e)}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}validate(e){return this.credentialsConfigFormGroup.valid?null:{credentialsConfig:{valid:!1}}}credentialsTypeChanged(){this.credentialsConfigFormGroup.patchValue({username:null,password:null,caCert:null,caCertFileName:null,privateKey:null,privateKeyFileName:null,cert:null,certFileName:null}),this.updateValidators()}updateValidators(e=!1){const t=this.credentialsConfigFormGroup.get("type").value;switch(e&&this.credentialsConfigFormGroup.reset({type:t},{emitEvent:!1}),this.credentialsConfigFormGroup.setValidators([]),this.credentialsConfigFormGroup.get("username").setValidators([]),this.credentialsConfigFormGroup.get("password").setValidators([]),t){case"anonymous":break;case"basic":this.credentialsConfigFormGroup.get("username").setValidators([O.required]),this.credentialsConfigFormGroup.get("password").setValidators(this.passwordFieldRequired?[O.required]:[]);break;case"cert.PEM":this.credentialsConfigFormGroup.setValidators([this.requiredFilesSelected(O.required,[["caCert","caCertFileName"],["privateKey","privateKeyFileName","cert","certFileName"]])])}this.credentialsConfigFormGroup.get("username").updateValueAndValidity({emitEvent:e}),this.credentialsConfigFormGroup.get("password").updateValueAndValidity({emitEvent:e}),this.credentialsConfigFormGroup.updateValueAndValidity({emitEvent:e})}requiredFilesSelected(e,t=null){return n=>{t||(t=[Object.keys(n.controls)]);return n?.controls&&t.some((t=>t.every((t=>!e(n.controls[t])))))?null:{notAllRequiredFilesSelected:!0}}}}e("CredentialsConfigComponent",En),En.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:En,deps:[{token:P.Store},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),En.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:En,selector:"tb-credentials-config",inputs:{required:"required",disableCertPemCredentials:"disableCertPemCredentials",passwordFieldRequired:"passwordFieldRequired"},providers:[{provide:B,useExisting:a((()=>En)),multi:!0},{provide:K,useExisting:a((()=>En)),multi:!0}],usesInheritance:!0,usesOnChanges:!0,ngImport:t,template:'
\n \n \n tb.rulenode.credentials\n \n {{ credentialsTypeTranslationsMap.get(credentialsConfigFormGroup.get(\'type\').value) | translate }}\n \n \n \n \n tb.rulenode.credentials-type\n \n \n {{ credentialsTypeTranslationsMap.get(credentialsType) | translate }}\n \n \n \n {{ \'tb.rulenode.credentials-type-required\' | translate }}\n \n \n
\n \n \n \n \n tb.rulenode.username\n \n \n {{ \'tb.rulenode.username-required\' | translate }}\n \n \n \n tb.rulenode.password\n \n \n \n {{ \'tb.rulenode.password-required\' | translate }}\n \n \n \n \n
{{ \'tb.rulenode.credentials-pem-hint\' | translate }}
\n \n \n \n \n \n \n \n tb.rulenode.private-key-password\n \n \n \n
\n
\n
\n
\n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:H.NgSwitch,selector:"[ngSwitch]",inputs:["ngSwitch"]},{kind:"directive",type:H.NgSwitchCase,selector:"[ngSwitchCase]",inputs:["ngSwitchCase"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Y.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:Je.MatExpansionPanel,selector:"mat-expansion-panel",inputs:["disabled","expanded","hideToggle","togglePosition"],outputs:["opened","closed","expandedChange","afterExpand","afterCollapse"],exportAs:["matExpansionPanel"]},{kind:"component",type:Je.MatExpansionPanelHeader,selector:"mat-expansion-panel-header",inputs:["tabIndex","expandedHeight","collapsedHeight"]},{kind:"directive",type:Je.MatExpansionPanelTitle,selector:"mat-panel-title"},{kind:"directive",type:Je.MatExpansionPanelDescription,selector:"mat-panel-description"},{kind:"directive",type:Je.MatExpansionPanelContent,selector:"ng-template[matExpansionPanelContent]"},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:Ye.FileInputComponent,selector:"tb-file-input",inputs:["label","hint","accept","noFileText","inputId","allowedExtensions","dropLabel","contentConvertFunction","required","requiredAsError","disabled","existingFileName","readAsBinary","workFromFileObj","multipleFile"],outputs:["fileNameChanged"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:We.TogglePasswordComponent,selector:"tb-toggle-password"},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:En,decorators:[{type:n,args:[{selector:"tb-credentials-config",providers:[{provide:B,useExisting:a((()=>En)),multi:!0},{provide:K,useExisting:a((()=>En)),multi:!0}],template:'
\n \n \n tb.rulenode.credentials\n \n {{ credentialsTypeTranslationsMap.get(credentialsConfigFormGroup.get(\'type\').value) | translate }}\n \n \n \n \n tb.rulenode.credentials-type\n \n \n {{ credentialsTypeTranslationsMap.get(credentialsType) | translate }}\n \n \n \n {{ \'tb.rulenode.credentials-type-required\' | translate }}\n \n \n
\n \n \n \n \n tb.rulenode.username\n \n \n {{ \'tb.rulenode.username-required\' | translate }}\n \n \n \n tb.rulenode.password\n \n \n \n {{ \'tb.rulenode.password-required\' | translate }}\n \n \n \n \n
{{ \'tb.rulenode.credentials-pem-hint\' | translate }}
\n \n \n \n \n \n \n \n tb.rulenode.private-key-password\n \n \n \n
\n
\n
\n
\n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder}]},propDecorators:{required:[{type:i}],disableCertPemCredentials:[{type:i}],passwordFieldRequired:[{type:i}]}});const Gn=new l("WindowToken","undefined"!=typeof window&&window.document?{providedIn:"root",factory:()=>window}:{providedIn:"root",factory:()=>{}});class Dn{constructor(e,t,n){this.ngZone=e,this.document=t,this.window=n,this.copySubject=new _e,this.copyResponse$=this.copySubject.asObservable(),this.config={}}configure(e){this.config=e}copy(e){if(!this.isSupported||!e)return this.pushCopyResponse({isSuccess:!1,content:e});const t=this.copyFromContent(e);return t?this.pushCopyResponse({content:e,isSuccess:t}):this.pushCopyResponse({isSuccess:!1,content:e})}get isSupported(){return!!this.document.queryCommandSupported&&!!this.document.queryCommandSupported("copy")&&!!this.window}isTargetValid(e){if(e instanceof HTMLInputElement||e instanceof HTMLTextAreaElement){if(e.hasAttribute("disabled"))throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');return!0}throw new Error("Target should be input or textarea")}copyFromInputElement(e,t=!0){try{this.selectTarget(e);const n=this.copyText();return this.clearSelection(t?e:void 0,this.window),n&&this.isCopySuccessInIE11()}catch(e){return!1}}isCopySuccessInIE11(){const e=this.window.clipboardData;return!(e&&e.getData&&!e.getData("Text"))}copyFromContent(e,t=this.document.body){if(this.tempTextArea&&!t.contains(this.tempTextArea)&&this.destroy(this.tempTextArea.parentElement||void 0),!this.tempTextArea){this.tempTextArea=this.createTempTextArea(this.document,this.window);try{t.appendChild(this.tempTextArea)}catch(e){throw new Error("Container should be a Dom element")}}this.tempTextArea.value=e;const n=this.copyFromInputElement(this.tempTextArea,!1);return this.config.cleanUpAfterCopy&&this.destroy(this.tempTextArea.parentElement||void 0),n}destroy(e=this.document.body){this.tempTextArea&&(e.removeChild(this.tempTextArea),this.tempTextArea=void 0)}selectTarget(e){return e.select(),e.setSelectionRange(0,e.value.length),e.value.length}copyText(){return this.document.execCommand("copy")}clearSelection(e,t){e&&e.focus(),t.getSelection()?.removeAllRanges()}createTempTextArea(e,t){const n="rtl"===e.documentElement.getAttribute("dir");let r;r=e.createElement("textarea"),r.style.fontSize="12pt",r.style.border="0",r.style.padding="0",r.style.margin="0",r.style.position="absolute",r.style[n?"right":"left"]="-9999px";const o=t.pageYOffset||e.documentElement.scrollTop;return r.style.top=o+"px",r.setAttribute("readonly",""),r}pushCopyResponse(e){this.copySubject.observers.length>0&&this.ngZone.run((()=>{this.copySubject.next(e)}))}pushCopyReponse(e){this.pushCopyResponse(e)}}Dn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"13.0.1",ngImport:t,type:Dn,deps:[{token:t.NgZone},{token:j},{token:Gn,optional:!0}],target:t.ɵɵFactoryTarget.Injectable}),Dn.ɵprov=t.ɵɵngDeclareInjectable({minVersion:"12.0.0",version:"13.0.1",ngImport:t,type:Dn,providedIn:"root"}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"13.0.1",ngImport:t,type:Dn,decorators:[{type:s,args:[{providedIn:"root"}]}],ctorParameters:function(){return[{type:t.NgZone},{type:void 0,decorators:[{type:m,args:[j]}]},{type:void 0,decorators:[{type:p},{type:m,args:[Gn]}]}]}});class wn{constructor(e,t,n,o){this.ngZone=e,this.host=t,this.renderer=n,this.clipboardSrv=o,this.cbOnSuccess=new r,this.cbOnError=new r,this.onClick=e=>{this.clipboardSrv.isSupported?this.targetElm&&this.clipboardSrv.isTargetValid(this.targetElm)?this.handleResult(this.clipboardSrv.copyFromInputElement(this.targetElm),this.targetElm.value,e):this.cbContent&&this.handleResult(this.clipboardSrv.copyFromContent(this.cbContent,this.container),this.cbContent,e):this.handleResult(!1,void 0,e)}}ngOnInit(){this.ngZone.runOutsideAngular((()=>{this.clickListener=this.renderer.listen(this.host.nativeElement,"click",this.onClick)}))}ngOnDestroy(){this.clickListener&&this.clickListener(),this.clipboardSrv.destroy(this.container)}handleResult(e,t,n){let r={isSuccess:e,content:t,successMessage:this.cbSuccessMsg,event:n};e?this.cbOnSuccess.observed&&this.ngZone.run((()=>{this.cbOnSuccess.emit(r)})):this.cbOnError.observed&&this.ngZone.run((()=>{this.cbOnError.emit(r)})),this.clipboardSrv.pushCopyResponse(r)}}wn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"13.0.1",ngImport:t,type:wn,deps:[{token:t.NgZone},{token:t.ElementRef},{token:t.Renderer2},{token:Dn}],target:t.ɵɵFactoryTarget.Directive}),wn.ɵdir=t.ɵɵngDeclareDirective({minVersion:"12.0.0",version:"13.0.1",type:wn,selector:"[ngxClipboard]",inputs:{targetElm:["ngxClipboard","targetElm"],container:"container",cbContent:"cbContent",cbSuccessMsg:"cbSuccessMsg"},outputs:{cbOnSuccess:"cbOnSuccess",cbOnError:"cbOnError"},ngImport:t}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"13.0.1",ngImport:t,type:wn,decorators:[{type:d,args:[{selector:"[ngxClipboard]"}]}],ctorParameters:function(){return[{type:t.NgZone},{type:t.ElementRef},{type:t.Renderer2},{type:Dn}]},propDecorators:{targetElm:[{type:i,args:["ngxClipboard"]}],container:[{type:i}],cbContent:[{type:i}],cbSuccessMsg:[{type:i}],cbOnSuccess:[{type:u}],cbOnError:[{type:u}]}});class Vn{constructor(e,t,n){this._clipboardService=e,this._viewContainerRef=t,this._templateRef=n}ngOnInit(){this._clipboardService.isSupported&&this._viewContainerRef.createEmbeddedView(this._templateRef)}}Vn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"13.0.1",ngImport:t,type:Vn,deps:[{token:Dn},{token:t.ViewContainerRef},{token:t.TemplateRef}],target:t.ɵɵFactoryTarget.Directive}),Vn.ɵdir=t.ɵɵngDeclareDirective({minVersion:"12.0.0",version:"13.0.1",type:Vn,selector:"[ngxClipboardIfSupported]",ngImport:t}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"13.0.1",ngImport:t,type:Vn,decorators:[{type:d,args:[{selector:"[ngxClipboardIfSupported]"}]}],ctorParameters:function(){return[{type:Dn},{type:t.ViewContainerRef},{type:t.TemplateRef}]}});class Pn{}Pn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"13.0.1",ngImport:t,type:Pn,deps:[],target:t.ɵɵFactoryTarget.NgModule}),Pn.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"12.0.0",version:"13.0.1",ngImport:t,type:Pn,declarations:[wn,Vn],imports:[$],exports:[wn,Vn]}),Pn.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"13.0.1",ngImport:t,type:Pn,imports:[[$]]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"13.0.1",ngImport:t,type:Pn,decorators:[{type:c,args:[{imports:[$],declarations:[wn,Vn],exports:[wn,Vn]}]}]});class Rn{set required(e){this.requiredValue!==e&&(this.requiredValue=e,this.updateValidators())}get required(){return this.requiredValue}constructor(e){this.fb=e,this.subscriptSizing="fixed",this.messageTypes=[{name:"Post attributes",value:"POST_ATTRIBUTES_REQUEST"},{name:"Post telemetry",value:"POST_TELEMETRY_REQUEST"},{name:"Custom",value:""}],this.propagateChange=()=>{},this.destroy$=new _e,this.messageTypeFormGroup=this.fb.group({messageTypeAlias:[null,[O.required]],messageType:[{value:null,disabled:!0},[O.maxLength(255)]]}),this.messageTypeFormGroup.get("messageTypeAlias").valueChanges.pipe(Be(this.destroy$)).subscribe((e=>this.updateMessageTypeValue(e))),this.messageTypeFormGroup.valueChanges.pipe(Be(this.destroy$)).subscribe((()=>this.updateView()))}ngOnDestroy(){this.destroy$.next(),this.destroy$.complete()}registerOnTouched(e){}registerOnChange(e){this.propagateChange=e}writeValue(e){this.modelValue=e;let t=this.messageTypes.find((t=>t.value===e));t||(t=this.messageTypes.find((e=>""===e.value))),this.messageTypeFormGroup.get("messageTypeAlias").patchValue(t,{emitEvent:!1}),this.messageTypeFormGroup.get("messageType").patchValue(e,{emitEvent:!1})}validate(){return this.messageTypeFormGroup.valid?null:{messageTypeInvalid:!0}}setDisabledState(e){this.disabled=e,e?this.messageTypeFormGroup.disable({emitEvent:!1}):(this.messageTypeFormGroup.enable({emitEvent:!1}),"Custom"!==this.messageTypeFormGroup.get("messageTypeAlias").value?.name&&this.messageTypeFormGroup.get("messageType").disable({emitEvent:!1}))}updateView(){const e=this.messageTypeFormGroup.getRawValue().messageType;this.modelValue!==e&&(this.modelValue=e,this.propagateChange(this.modelValue))}updateValidators(){this.messageTypeFormGroup.get("messageType").setValidators(this.required?[O.required,O.maxLength(255)]:[O.maxLength(255)]),this.messageTypeFormGroup.get("messageType").updateValueAndValidity({emitEvent:!1})}updateMessageTypeValue(e){"Custom"!==e?.name?this.messageTypeFormGroup.get("messageType").disable({emitEvent:!1}):this.messageTypeFormGroup.get("messageType").enable({emitEvent:!1}),this.messageTypeFormGroup.get("messageType").patchValue(e.value??null)}}e("OutputMessageTypeAutocompleteComponent",Rn),Rn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Rn,deps:[{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Rn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Rn,selector:"tb-output-message-type-autocomplete",inputs:{subscriptSizing:"subscriptSizing",disabled:"disabled",required:"required"},providers:[{provide:B,useExisting:a((()=>Rn)),multi:!0},{provide:K,useExisting:a((()=>Rn)),multi:!0}],ngImport:t,template:'
\n \n {{\'tb.rulenode.output-message-type\' | translate}}\n \n \n {{msgType.name}}\n \n \n \n \n {{\'tb.rulenode.message-type-value\' | translate}}\n \n \n \n {{ \'tb.rulenode.message-type-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.message-type-value-max-length\' | translate }}\n \n \n
\n\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:de.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Y.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:wn,selector:"[ngxClipboard]",inputs:["ngxClipboard","container","cbContent","cbSuccessMsg"],outputs:["cbOnSuccess","cbOnError"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),Oe([T()],Rn.prototype,"disabled",void 0),Oe([T()],Rn.prototype,"required",null),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Rn,decorators:[{type:n,args:[{selector:"tb-output-message-type-autocomplete",providers:[{provide:B,useExisting:a((()=>Rn)),multi:!0},{provide:K,useExisting:a((()=>Rn)),multi:!0}],template:'
\n \n {{\'tb.rulenode.output-message-type\' | translate}}\n \n \n {{msgType.name}}\n \n \n \n \n {{\'tb.rulenode.message-type-value\' | translate}}\n \n \n \n {{ \'tb.rulenode.message-type-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.message-type-value-max-length\' | translate }}\n \n \n
\n\n'}]}],ctorParameters:function(){return[{type:R.FormBuilder}]},propDecorators:{subscriptSizing:[{type:i}],disabled:[{type:i}],required:[{type:i}]}});class On{constructor(e,t){this.fb=e,this.translate=t,this.translation=nn,this.propagateChange=()=>{},this.destroy$=new _e,this.selectOptions=[]}ngOnInit(){this.initOptions(),this.chipControlGroup=this.fb.group({chipControl:[null,[]]}),this.chipControlGroup.get("chipControl").valueChanges.pipe(De(this.destroy$)).subscribe((e=>{e&&this.propagateChange(e)}))}ngOnDestroy(){this.destroy$.next(),this.destroy$.complete()}initOptions(){for(const e of this.translation.keys())this.selectOptions.push({value:e,name:this.translate.instant(this.translation.get(e))})}writeValue(e){this.chipControlGroup.get("chipControl").patchValue(e,{emitEvent:!1})}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){e?this.chipControlGroup.disable({emitEvent:!1}):this.chipControlGroup.enable({emitEvent:!1})}}e("MsgMetadataChipComponent",On),On.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:On,deps:[{token:R.FormBuilder},{token:Z.TranslateService}],target:t.ɵɵFactoryTarget.Component}),On.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:On,selector:"tb-msg-metadata-chip",inputs:{labelText:"labelText",translation:"translation"},providers:[{provide:B,useExisting:a((()=>On)),multi:!0}],ngImport:t,template:'
\n
{{ labelText }}
\n \n {{ option.name }}\n \n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"component",type:be.MatChipListbox,selector:"mat-chip-listbox",inputs:["tabIndex","multiple","aria-orientation","selectable","compareWith","required","hideSingleSelectionIndicator","value"],outputs:["change"]},{kind:"component",type:be.MatChipOption,selector:"mat-basic-chip-option, [mat-basic-chip-option], mat-chip-option, [mat-chip-option]",inputs:["color","disabled","disableRipple","tabIndex","selectable","selected"],outputs:["selectionChange"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:On,decorators:[{type:n,args:[{selector:"tb-msg-metadata-chip",providers:[{provide:B,useExisting:a((()=>On)),multi:!0}],template:'
\n
{{ labelText }}
\n \n {{ option.name }}\n \n
\n'}]}],ctorParameters:function(){return[{type:R.FormBuilder},{type:Z.TranslateService}]},propDecorators:{labelText:[{type:i}],translation:[{type:i}]}});class _n extends L{constructor(e,t,n,r){super(e),this.store=e,this.translate=t,this.injector=n,this.fb=r,this.destroy$=new _e,this.sourceFieldSubcritption=[],this.propagateChange=null,this.disabled=!1,this.required=!1,this.oneMapRequiredValidator=e=>e.get("keyVals").value.length,this.propagateNestedErrors=e=>{if(this.svListFormGroup&&this.svListFormGroup.get("keyVals")&&"VALID"===this.svListFormGroup.get("keyVals")?.status)return null;const t={};if(this.svListFormGroup&&this.svListFormGroup.setErrors(null),e instanceof z||e instanceof U){if(e.errors)for(const n of Object.keys(e.errors))t[n]=!0;for(const n of Object.keys(e.controls)){const r=this.propagateNestedErrors(e.controls[n]);if(r&&Object.keys(r).length)for(const e of Object.keys(r))t[e]=!0}return t}if(e.errors)for(const n of Object.keys(e.errors))t[n]=!0;return ae(t,{})?null:t}}ngOnInit(){this.ngControl=this.injector.get(_),null!=this.ngControl&&(this.ngControl.valueAccessor=this),this.svListFormGroup=this.fb.group({keyVals:this.fb.array([])},{validators:[this.propagateNestedErrors,this.oneMapRequiredValidator]}),this.svListFormGroup.valueChanges.pipe(De(this.destroy$)).subscribe((()=>{this.updateModel()}))}ngOnDestroy(){this.destroy$.next(),this.destroy$.complete()}keyValsFormArray(){return this.svListFormGroup.get("keyVals")}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.svListFormGroup.disable({emitEvent:!1}):this.svListFormGroup.enable({emitEvent:!1})}writeValue(e){const t=Object.keys(e).map((t=>({key:t,value:e[t]})));if(this.keyValsFormArray().length===t.length)this.keyValsFormArray().patchValue(t,{emitEvent:!1});else{const e=[];t.forEach((t=>{e.push(this.fb.group({key:[t.key,[O.required]],value:[t.value,[O.required,O.pattern(/(?:.|\s)*\S(&:.|\s)*/)]]}))})),this.svListFormGroup.setControl("keyVals",this.fb.array(e,this.propagateNestedErrors),{emitEvent:!1});for(const e of this.keyValsFormArray().controls)this.keyChangeSubscribe(e)}}filterSelectOptions(e){const t=[];for(const e of this.svListFormGroup.get("keyVals").value){const n=this.selectOptions.find((t=>t.value===e.key));n&&t.push(n)}const n=[];for(const r of this.selectOptions)ie(t.find((e=>e.value===r.value)))&&r.value!==e?.get("key").value||n.push(r);return n}removeKeyVal(e){this.keyValsFormArray().removeAt(e),this.sourceFieldSubcritption[e].unsubscribe(),this.sourceFieldSubcritption.splice(e,1)}addKeyVal(){this.keyValsFormArray().push(this.fb.group({key:["",[O.required]],value:["",[O.required,O.pattern(/(?:.|\s)*\S(&:.|\s)*/)]]})),this.keyChangeSubscribe(this.keyValsFormArray().at(this.keyValsFormArray().length-1))}keyChangeSubscribe(e){this.sourceFieldSubcritption.push(e.get("key").valueChanges.pipe(De(this.destroy$)).subscribe((t=>{const n=Lt.get(t);e.get("value").patchValue(this.targetKeyPrefix+n[0].toUpperCase()+n.slice(1))})))}validate(e){return!this.svListFormGroup.get("keyVals").value.length&&this.required?{svMapRequired:!0}:this.svListFormGroup.valid?null:{svFieldsRequired:!0}}updateModel(){const e=this.svListFormGroup.get("keyVals").value;if(this.required&&!e.length||!this.svListFormGroup.valid)this.propagateChange(null);else{const t={};e.forEach((e=>{t[e.key]=e.value})),this.propagateChange(t)}}}e("SvMapConfigComponent",_n),_n.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:_n,deps:[{token:P.Store},{token:Z.TranslateService},{token:t.Injector},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),_n.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:_n,selector:"tb-sv-map-config",inputs:{selectOptions:"selectOptions",disabled:"disabled",labelText:"labelText",requiredText:"requiredText",targetKeyPrefix:"targetKeyPrefix",selectText:"selectText",selectRequiredText:"selectRequiredText",valText:"valText",valRequiredText:"valRequiredText",hintText:"hintText",popupHelpLink:"popupHelpLink",required:"required"},providers:[{provide:B,useExisting:a((()=>_n)),multi:!0},{provide:K,useExisting:a((()=>_n)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n
\n
{{ labelText }}
\n
\n tb.rulenode.map-fields-required\n
\n
\n {{ requiredText }}\n
\n
\n
\n
\n
\n
{{ selectText }}
\n
{{ valText }}
\n
\n
\n
\n
\n \n \n \n {{option.name}}\n \n \n \n \n \n \n
\n \n
\n
\n
\n
\n
\n
\n \n
\n \n
\n',styles:[":host .field-space{flex:1 1 50%}:host .actions-header{width:40px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:H.NgClass,selector:"[ngClass]",inputs:["class","ngClass"]},{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:de.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:de.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:Ie.DefaultClassDirective,selector:" [ngClass], [ngClass.xs], [ngClass.sm], [ngClass.md], [ngClass.lg], [ngClass.xl], [ngClass.lt-sm], [ngClass.lt-md], [ngClass.lt-lg], [ngClass.lt-xl], [ngClass.gt-xs], [ngClass.gt-sm], [ngClass.gt-md], [ngClass.gt-lg]",inputs:["ngClass","ngClass.xs","ngClass.sm","ngClass.md","ngClass.lg","ngClass.xl","ngClass.lt-sm","ngClass.lt-md","ngClass.lt-lg","ngClass.lt-xl","ngClass.gt-xs","ngClass.gt-sm","ngClass.gt-md","ngClass.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormControlDirective,selector:"[formControl]",inputs:["formControl","disabled","ngModel"],outputs:["ngModelChange"],exportAs:["ngForm"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Nn,selector:"tb-example-hint",inputs:["hintText","popupHelpLink","textAlign"]},{kind:"pipe",type:H.AsyncPipe,name:"async"},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),Oe([T()],_n.prototype,"disabled",void 0),Oe([T()],_n.prototype,"required",void 0),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:_n,decorators:[{type:n,args:[{selector:"tb-sv-map-config",providers:[{provide:B,useExisting:a((()=>_n)),multi:!0},{provide:K,useExisting:a((()=>_n)),multi:!0}],template:'
\n
\n
{{ labelText }}
\n
\n tb.rulenode.map-fields-required\n
\n
\n {{ requiredText }}\n
\n
\n
\n
\n
\n
{{ selectText }}
\n
{{ valText }}
\n
\n
\n
\n
\n \n \n \n {{option.name}}\n \n \n \n \n \n \n
\n \n
\n
\n
\n
\n
\n
\n \n
\n \n
\n',styles:[":host .field-space{flex:1 1 50%}:host .actions-header{width:40px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:P.Store},{type:Z.TranslateService},{type:t.Injector},{type:R.FormBuilder}]},propDecorators:{selectOptions:[{type:i}],disabled:[{type:i}],labelText:[{type:i}],requiredText:[{type:i}],targetKeyPrefix:[{type:i}],selectText:[{type:i}],selectRequiredText:[{type:i}],valText:[{type:i}],valRequiredText:[{type:i}],hintText:[{type:i}],popupHelpLink:[{type:i}],required:[{type:i}]}});class Bn extends L{get required(){return this.requiredValue}set required(e){this.requiredValue=Fe(e)}constructor(e,t){super(e),this.store=e,this.fb=t,this.directionTypes=Object.keys(v),this.directionTypeTranslations=C,this.propagateChange=null}ngOnInit(){this.relationsQueryFormGroup=this.fb.group({fetchLastLevelOnly:[!1,[]],direction:[null,[O.required]],maxLevel:[null,[]],filters:[null]}),this.relationsQueryFormGroup.valueChanges.subscribe((e=>{this.relationsQueryFormGroup.valid?this.propagateChange(e):this.propagateChange(null)}))}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.relationsQueryFormGroup.disable({emitEvent:!1}):this.relationsQueryFormGroup.enable({emitEvent:!1})}writeValue(e){this.relationsQueryFormGroup.reset(e||{},{emitEvent:!1})}}e("RelationsQueryConfigOldComponent",Bn),Bn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Bn,deps:[{token:P.Store},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Bn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Bn,selector:"tb-relations-query-config-old",inputs:{disabled:"disabled",required:"required"},providers:[{provide:B,useExisting:a((()=>Bn)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'alias.last-level-relation\' | translate }}\n \n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n
\n
relation.relation-filters
\n \n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"component",type:Q.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Qe.RelationFiltersComponent,selector:"tb-relation-filters",inputs:["disabled","allowedEntityTypes"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Bn,decorators:[{type:n,args:[{selector:"tb-relations-query-config-old",providers:[{provide:B,useExisting:a((()=>Bn)),multi:!0}],template:'
\n \n {{ \'alias.last-level-relation\' | translate }}\n \n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n
\n
relation.relation-filters
\n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder}]},propDecorators:{disabled:[{type:i}],required:[{type:i}]}});class Kn{constructor(e,t){this.translate=e,this.fb=t,this.propagateChange=e=>{},this.destroy$=new _e,this.separatorKeysCodes=[ge,ye,xe],this.onTouched=()=>{}}ngOnInit(){this.attributeControlGroup=this.fb.group({clientAttributeNames:[[],[]],sharedAttributeNames:[[],[]],serverAttributeNames:[[],[]],latestTsKeyNames:[[],[]],getLatestValueWithTs:[!1,[]]},{validators:this.atLeastOne(O.required,["clientAttributeNames","sharedAttributeNames","serverAttributeNames","latestTsKeyNames"])}),this.attributeControlGroup.valueChanges.pipe(De(this.destroy$)).subscribe((e=>{this.propagateChange(this.preparePropagateValue(e))}))}preparePropagateValue(e){const t={};for(const n in e)t[n]="getLatestValueWithTs"===n||ie(e[n])?e[n]:[];return t}validate(){return this.attributeControlGroup.valid?null:{atLeastOneRequired:!0}}atLeastOne(e,t=null){return n=>{t||(t=Object.keys(n.controls));return n?.controls&&t.some((t=>!e(n.controls[t])))?null:{atLeastOne:!0}}}writeValue(e){this.attributeControlGroup.setValue(e,{emitEvent:!1})}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){this.onTouched=e}setDisabledState(e){e?this.attributeControlGroup.disable({emitEvent:!1}):this.attributeControlGroup.enable({emitEvent:!1})}ngOnDestroy(){this.destroy$.next(null),this.destroy$.complete()}}e("SelectAttributesComponent",Kn),Kn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Kn,deps:[{token:Z.TranslateService},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Kn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Kn,selector:"tb-select-attributes",inputs:{popupHelpLink:"popupHelpLink"},providers:[{provide:B,useExisting:a((()=>Kn)),multi:!0},{provide:K,useExisting:Kn,multi:!0}],ngImport:t,template:'
\n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n \n {{ \'tb.rulenode.fetch-latest-telemetry-with-timestamp\' | translate }}\n \n
\n
\n\n\n help\n\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:H.NgTemplateOutlet,selector:"[ngTemplateOutlet]",inputs:["ngTemplateOutletContext","ngTemplateOutlet","ngTemplateOutletInjector"]},{kind:"component",type:Ze.StringItemsListComponent,selector:"tb-string-items-list",inputs:["required","disabled","label","placeholder","hint","requiredText","floatLabel","appearance","editable","subscriptSizing","predefinedValues"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:Y.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:te.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:ne.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"component",type:Nn,selector:"tb-example-hint",inputs:["hintText","popupHelpLink","textAlign"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Kn,decorators:[{type:n,args:[{selector:"tb-select-attributes",providers:[{provide:B,useExisting:a((()=>Kn)),multi:!0},{provide:K,useExisting:Kn,multi:!0}],template:'
\n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n \n {{ \'tb.rulenode.fetch-latest-telemetry-with-timestamp\' | translate }}\n \n
\n
\n\n\n help\n\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:Z.TranslateService},{type:R.FormBuilder}]},propDecorators:{popupHelpLink:[{type:i}]}});class zn extends L{constructor(e,t){super(e),this.store=e,this.fb=t,this.propagateChange=null,this.destroy$=new _e,this.alarmStatus=q,this.alarmStatusTranslations=A}ngOnInit(){this.alarmStatusGroup=this.fb.group({alarmStatus:[null,[]]}),this.alarmStatusGroup.get("alarmStatus").valueChanges.pipe(De(this.destroy$)).subscribe((e=>{this.propagateChange(e)}))}setDisabledState(e){e?this.alarmStatusGroup.disable({emitEvent:!1}):this.alarmStatusGroup.enable({emitEvent:!1})}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}ngOnDestroy(){this.destroy$.next(),this.destroy$.complete()}writeValue(e){this.alarmStatusGroup.get("alarmStatus").patchValue(e,{emitEvent:!1})}}e("AlarmStatusSelectComponent",zn),zn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:zn,deps:[{token:P.Store},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),zn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:zn,selector:"tb-alarm-status-select",providers:[{provide:B,useExisting:a((()=>zn)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n
\n \n {{ alarmStatusTranslations.get(alarmStatus.ACTIVE_UNACK) | translate }}\n \n \n {{ alarmStatusTranslations.get(alarmStatus.ACTIVE_ACK) | translate }}\n \n
\n
\n \n {{ alarmStatusTranslations.get(alarmStatus.CLEARED_UNACK) | translate }}\n \n \n {{ alarmStatusTranslations.get(alarmStatus.CLEARED_ACK) | translate }}\n \n
\n
\n
\n',styles:[":host .chip-listbox{max-width:460px;width:100%}:host .chip-listbox .toggle-column{display:flex;flex:1 1 100%;gap:8px}:host .chip-listbox .option{margin:0}@media screen and (max-width: 959px){:host .chip-listbox{max-width:360px}:host .chip-listbox .toggle-column{flex-direction:column}}:host ::ng-deep .chip-listbox .mdc-evolution-chip-set__chips{gap:8px}:host ::ng-deep .chip-listbox .option button{flex-basis:100%;justify-content:start}:host ::ng-deep .chip-listbox .option .mdc-evolution-chip__graphic{flex-grow:0}\n"],dependencies:[{kind:"component",type:be.MatChipListbox,selector:"mat-chip-listbox",inputs:["tabIndex","multiple","aria-orientation","selectable","compareWith","required","hideSingleSelectionIndicator","value"],outputs:["change"]},{kind:"component",type:be.MatChipOption,selector:"mat-basic-chip-option, [mat-basic-chip-option], mat-chip-option, [mat-chip-option]",inputs:["color","disabled","disableRipple","tabIndex","selectable","selected"],outputs:["selectionChange"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:zn,decorators:[{type:n,args:[{selector:"tb-alarm-status-select",providers:[{provide:B,useExisting:a((()=>zn)),multi:!0}],template:'
\n \n
\n \n {{ alarmStatusTranslations.get(alarmStatus.ACTIVE_UNACK) | translate }}\n \n \n {{ alarmStatusTranslations.get(alarmStatus.ACTIVE_ACK) | translate }}\n \n
\n
\n \n {{ alarmStatusTranslations.get(alarmStatus.CLEARED_UNACK) | translate }}\n \n \n {{ alarmStatusTranslations.get(alarmStatus.CLEARED_ACK) | translate }}\n \n
\n
\n
\n',styles:[":host .chip-listbox{max-width:460px;width:100%}:host .chip-listbox .toggle-column{display:flex;flex:1 1 100%;gap:8px}:host .chip-listbox .option{margin:0}@media screen and (max-width: 959px){:host .chip-listbox{max-width:360px}:host .chip-listbox .toggle-column{flex-direction:column}}:host ::ng-deep .chip-listbox .mdc-evolution-chip-set__chips{gap:8px}:host ::ng-deep .chip-listbox .option button{flex-basis:100%;justify-content:start}:host ::ng-deep .chip-listbox .option .mdc-evolution-chip__graphic{flex-grow:0}\n"]}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder}]}});class Un{}e("RulenodeCoreConfigCommonModule",Un),Un.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Un,deps:[],target:t.ɵɵFactoryTarget.NgModule}),Un.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.10",ngImport:t,type:Un,declarations:[Sn,qn,An,Mn,En,Ln,Tn,Rn,hn,On,_n,Bn,Kn,zn,Nn],imports:[$,M,Re],exports:[Sn,qn,An,Mn,En,Ln,Tn,Rn,hn,On,_n,Bn,Kn,zn,Nn]}),Un.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Un,imports:[$,M,Re]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Un,decorators:[{type:c,args:[{declarations:[Sn,qn,An,Mn,En,Ln,Tn,Rn,hn,On,_n,Bn,Kn,zn,Nn],imports:[$,M,Re],exports:[Sn,qn,An,Mn,En,Ln,Tn,Rn,hn,On,_n,Bn,Kn,zn,Nn]}]}]});class Hn{}e("RuleNodeCoreConfigActionModule",Hn),Hn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Hn,deps:[],target:t.ɵɵFactoryTarget.NgModule}),Hn.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.10",ngImport:t,type:Hn,declarations:[kn,ct,Cn,bn,un,ut,ft,gt,yt,fn,xt,ht,dn,cn,xn,vn,Fn,bt,yn,gn,In],imports:[$,M,Re,Un],exports:[kn,ct,Cn,bn,un,ut,ft,gt,yt,fn,xt,ht,dn,cn,xn,vn,Fn,bt,yn,gn,In]}),Hn.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Hn,imports:[$,M,Re,Un]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Hn,decorators:[{type:c,args:[{declarations:[kn,ct,Cn,bn,un,ut,ft,gt,yt,fn,xt,ht,dn,cn,xn,vn,Fn,bt,yn,gn,In],imports:[$,M,Re,Un],exports:[kn,ct,Cn,bn,un,ut,ft,gt,yt,fn,xt,ht,dn,cn,xn,vn,Fn,bt,yn,gn,In]}]}]});class jn extends f{constructor(e,t,n){super(e),this.store=e,this.translate=t,this.fb=n,this.separatorKeysCodes=[ge,ye,xe]}configForm(){return this.calculateDeltaConfigForm}onConfigurationSet(e){this.calculateDeltaConfigForm=this.fb.group({inputValueKey:[e.inputValueKey,[O.required,O.pattern(/(?:.|\s)*\S(&:.|\s)*/)]],outputValueKey:[e.outputValueKey,[O.required,O.pattern(/(?:.|\s)*\S(&:.|\s)*/)]],useCache:[e.useCache,[]],addPeriodBetweenMsgs:[e.addPeriodBetweenMsgs,[]],periodValueKey:[e.periodValueKey,[]],round:[e.round,[O.min(0),O.max(15)]],tellFailureIfDeltaIsNegative:[e.tellFailureIfDeltaIsNegative,[]]})}prepareInputConfig(e){return{inputValueKey:ie(e?.inputValueKey)?e.inputValueKey:null,outputValueKey:ie(e?.outputValueKey)?e.outputValueKey:null,useCache:!ie(e?.useCache)||e.useCache,addPeriodBetweenMsgs:!!ie(e?.addPeriodBetweenMsgs)&&e.addPeriodBetweenMsgs,periodValueKey:ie(e?.periodValueKey)?e.periodValueKey:null,round:ie(e?.round)?e.round:null,tellFailureIfDeltaIsNegative:!ie(e?.tellFailureIfDeltaIsNegative)||e.tellFailureIfDeltaIsNegative}}prepareOutputConfig(e){return le(e)}updateValidators(e){this.calculateDeltaConfigForm.get("addPeriodBetweenMsgs").value?this.calculateDeltaConfigForm.get("periodValueKey").setValidators([O.required]):this.calculateDeltaConfigForm.get("periodValueKey").setValidators([]),this.calculateDeltaConfigForm.get("periodValueKey").updateValueAndValidity({emitEvent:e})}validatorTriggers(){return["addPeriodBetweenMsgs"]}}e("CalculateDeltaConfigComponent",jn),jn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:jn,deps:[{token:P.Store},{token:Z.TranslateService},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),jn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:jn,selector:"tb-enrichment-node-calculate-delta-config",usesInheritance:!0,ngImport:t,template:"
\n
\n \n {{ 'tb.rulenode.input-value-key' | translate }}\n \n \n {{ 'tb.rulenode.input-value-key-required' | translate }}\n \n \n \n {{ 'tb.rulenode.output-value-key' | translate }}\n \n \n {{ 'tb.rulenode.output-value-key-required' | translate }}\n \n \n
\n \n {{ 'tb.rulenode.number-of-digits-after-floating-point' | translate }}\n \n \n {{ 'tb.rulenode.number-of-digits-after-floating-point-range' | translate }}\n \n \n {{ 'tb.rulenode.number-of-digits-after-floating-point-range' | translate }}\n \n \n
\n
\n \n {{ 'tb.rulenode.failure-if-delta-negative' | translate }}\n \n
\n
\n \n {{ 'tb.rulenode.use-caching' | translate }}\n \n
\n
\n
\n \n {{ 'tb.rulenode.add-time-difference-between-readings' | translate:\n { inputValueKey: calculateDeltaConfigForm.get('inputValueKey').valid ?\n calculateDeltaConfigForm.get('inputValueKey').value : 'tb.rulenode.input-value-key' | translate } }}\n \n
\n \n {{ 'tb.rulenode.period-value-key' | translate }}\n \n \n {{ 'tb.rulenode.period-value-key-required' | translate }}\n \n \n
\n
\n
\n",dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:te.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:ne.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:jn,decorators:[{type:n,args:[{selector:"tb-enrichment-node-calculate-delta-config",template:"
\n
\n \n {{ 'tb.rulenode.input-value-key' | translate }}\n \n \n {{ 'tb.rulenode.input-value-key-required' | translate }}\n \n \n \n {{ 'tb.rulenode.output-value-key' | translate }}\n \n \n {{ 'tb.rulenode.output-value-key-required' | translate }}\n \n \n
\n \n {{ 'tb.rulenode.number-of-digits-after-floating-point' | translate }}\n \n \n {{ 'tb.rulenode.number-of-digits-after-floating-point-range' | translate }}\n \n \n {{ 'tb.rulenode.number-of-digits-after-floating-point-range' | translate }}\n \n \n
\n
\n \n {{ 'tb.rulenode.failure-if-delta-negative' | translate }}\n \n
\n
\n \n {{ 'tb.rulenode.use-caching' | translate }}\n \n
\n
\n
\n \n {{ 'tb.rulenode.add-time-difference-between-readings' | translate:\n { inputValueKey: calculateDeltaConfigForm.get('inputValueKey').valid ?\n calculateDeltaConfigForm.get('inputValueKey').value : 'tb.rulenode.input-value-key' | translate } }}\n \n
\n \n {{ 'tb.rulenode.period-value-key' | translate }}\n \n \n {{ 'tb.rulenode.period-value-key-required' | translate }}\n \n \n
\n
\n
\n"}]}],ctorParameters:function(){return[{type:P.Store},{type:Z.TranslateService},{type:R.FormBuilder}]}});class $n extends f{constructor(e,t,n){super(e),this.store=e,this.fb=t,this.translate=n,this.fetchToData=[],this.DataToFetch=Pt;for(const e of Rt.keys())e!==Pt.FIELDS&&this.fetchToData.push({value:e,name:this.translate.instant(Rt.get(e))})}configForm(){return this.customerAttributesConfigForm}prepareOutputConfig(e){const t={};for(const n of Object.keys(e.dataMapping))t[n.trim()]=e.dataMapping[n];return e.dataMapping=t,le(e)}prepareInputConfig(e){let t,n;return t=ie(e?.telemetry)?e.telemetry?Pt.LATEST_TELEMETRY:Pt.ATTRIBUTES:ie(e?.dataToFetch)?e.dataToFetch:Pt.ATTRIBUTES,n=ie(e?.attrMapping)?e.attrMapping:ie(e?.dataMapping)?e.dataMapping:null,{dataToFetch:t,dataMapping:n,fetchTo:ie(e?.fetchTo)?e.fetchTo:en.METADATA}}selectTranslation(e,t){return this.customerAttributesConfigForm.get("dataToFetch").value===Pt.LATEST_TELEMETRY?e:t}onConfigurationSet(e){this.customerAttributesConfigForm=this.fb.group({dataToFetch:[e.dataToFetch,[]],dataMapping:[e.dataMapping,[O.required]],fetchTo:[e.fetchTo]})}}e("CustomerAttributesConfigComponent",$n),$n.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:$n,deps:[{token:P.Store},{token:R.FormBuilder},{token:Z.TranslateService}],target:t.ɵɵFactoryTarget.Component}),$n.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:$n,selector:"tb-enrichment-node-customer-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n
tb.rulenode.mapping-of-customers
\n
\n
\n \n \n {{ data.name }}\n \n \n
\n
\n \n \n \n \n
\n',styles:[":host .fetch-to-data-toggle{max-width:420px;width:100%}\n"],dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:W.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"directive",type:Xe.ToggleOption,selector:"tb-toggle-option",inputs:["value"]},{kind:"component",type:et.ToggleSelectComponent,selector:"tb-toggle-select",inputs:["disabled","selectMediaBreakpoint","appearance","disablePagination"]},{kind:"component",type:Sn,selector:"tb-kv-map-config",inputs:["disabled","uniqueKeyValuePairValidator","labelText","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","popupHelpLink","required"]},{kind:"component",type:On,selector:"tb-msg-metadata-chip",inputs:["labelText","translation"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:$n,decorators:[{type:n,args:[{selector:"tb-enrichment-node-customer-attributes-config",template:'
\n
tb.rulenode.mapping-of-customers
\n
\n
\n \n \n {{ data.name }}\n \n \n
\n
\n \n \n \n \n
\n',styles:[":host .fetch-to-data-toggle{max-width:420px;width:100%}\n"]}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder},{type:Z.TranslateService}]}});class Qn extends f{constructor(e,t,n){super(e),this.store=e,this.translate=t,this.fb=n}configForm(){return this.deviceAttributesConfigForm}onConfigurationSet(e){this.deviceAttributesConfigForm=this.fb.group({deviceRelationsQuery:[e.deviceRelationsQuery,[O.required]],tellFailureIfAbsent:[e.tellFailureIfAbsent,[]],fetchTo:[e.fetchTo,[]],attributesControl:[e.attributesControl,[]]})}prepareInputConfig(e){return se(e)&&(e.attributesControl={clientAttributeNames:ie(e?.clientAttributeNames)?e.clientAttributeNames:[],latestTsKeyNames:ie(e?.latestTsKeyNames)?e.latestTsKeyNames:[],serverAttributeNames:ie(e?.serverAttributeNames)?e.serverAttributeNames:[],sharedAttributeNames:ie(e?.sharedAttributeNames)?e.sharedAttributeNames:[],getLatestValueWithTs:!!ie(e?.getLatestValueWithTs)&&e.getLatestValueWithTs}),{deviceRelationsQuery:ie(e?.deviceRelationsQuery)?e.deviceRelationsQuery:null,tellFailureIfAbsent:!ie(e?.tellFailureIfAbsent)||e.tellFailureIfAbsent,fetchTo:ie(e?.fetchTo)?e.fetchTo:en.METADATA,attributesControl:e?e.attributesControl:null}}prepareOutputConfig(e){for(const t of Object.keys(e.attributesControl))e[t]=e.attributesControl[t];return delete e.attributesControl,e}}e("DeviceAttributesConfigComponent",Qn),Qn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Qn,deps:[{token:P.Store},{token:Z.TranslateService},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Qn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Qn,selector:"tb-enrichment-node-device-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n
\n
tb.rulenode.device-relations-query
\n \n \n
\n
\n
\n
tb.rulenode.related-device-attributes
\n
\n tb.rulenode.at-least-one-field-required\n
\n
\n \n \n
\n
\n \n {{ \'tb.rulenode.tell-failure\' | translate }}\n \n
\n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"component",type:te.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:ne.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"component",type:qn,selector:"tb-device-relations-query-config",inputs:["disabled","required"]},{kind:"component",type:On,selector:"tb-msg-metadata-chip",inputs:["labelText","translation"]},{kind:"component",type:Kn,selector:"tb-select-attributes",inputs:["popupHelpLink"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Qn,decorators:[{type:n,args:[{selector:"tb-enrichment-node-device-attributes-config",template:'
\n
\n
tb.rulenode.device-relations-query
\n \n \n
\n
\n
\n
tb.rulenode.related-device-attributes
\n
\n tb.rulenode.at-least-one-field-required\n
\n
\n \n \n
\n
\n \n {{ \'tb.rulenode.tell-failure\' | translate }}\n \n
\n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:P.Store},{type:Z.TranslateService},{type:R.FormBuilder}]}});class Jn extends f{constructor(e,t,n){super(e),this.store=e,this.translate=t,this.fb=n,this.predefinedValues=[];for(const e of Object.keys(Mt))this.predefinedValues.push({value:Mt[e],name:this.translate.instant(Et.get(Mt[e]))})}ngOnInit(){super.ngOnInit()}configForm(){return this.entityDetailsConfigForm}prepareInputConfig(e){let t;return t=ie(e?.addToMetadata)?e.addToMetadata?en.METADATA:en.DATA:e?.fetchTo?e.fetchTo:en.DATA,{detailsList:ie(e?.detailsList)?e.detailsList:null,fetchTo:t}}onConfigurationSet(e){this.entityDetailsConfigForm=this.fb.group({detailsList:[e.detailsList,[O.required]],fetchTo:[e.fetchTo,[]]})}}e("EntityDetailsConfigComponent",Jn),Jn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Jn,deps:[{token:P.Store},{token:Z.TranslateService},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Jn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Jn,selector:"tb-enrichment-node-entity-details-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n help\n \n \n \n \n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"component",type:Ze.StringItemsListComponent,selector:"tb-string-items-list",inputs:["required","disabled","label","placeholder","hint","requiredText","floatLabel","appearance","editable","subscriptSizing","predefinedValues"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:Y.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:On,selector:"tb-msg-metadata-chip",inputs:["labelText","translation"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Jn,decorators:[{type:n,args:[{selector:"tb-enrichment-node-entity-details-config",template:'
\n \n \n help\n \n \n \n \n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:P.Store},{type:Z.TranslateService},{type:R.FormBuilder}]}});class Yn extends f{constructor(e,t,n){super(e),this.store=e,this.translate=t,this.fb=n,this.separatorKeysCodes=[ge,ye,xe],this.aggregationTypes=E,this.aggregations=Object.values(E),this.aggregationTypesTranslations=G,this.fetchMode=Gt,this.samplingOrders=Object.values(Vt),this.samplingOrdersTranslate=_t,this.timeUnits=Object.values(Nt),this.timeUnitsTranslationMap=St,this.deduplicationStrategiesHintTranslations=wt,this.headerOptions=[],this.timeUnitMap={[Nt.MILLISECONDS]:1,[Nt.SECONDS]:1e3,[Nt.MINUTES]:6e4,[Nt.HOURS]:36e5,[Nt.DAYS]:864e5},this.intervalValidator=()=>e=>e.get("startInterval").value*this.timeUnitMap[e.get("startIntervalTimeUnit").value]<=e.get("endInterval").value*this.timeUnitMap[e.get("endIntervalTimeUnit").value]?{intervalError:!0}:null;for(const e of Dt.keys())this.headerOptions.push({value:e,name:this.translate.instant(Dt.get(e))})}configForm(){return this.getTelemetryFromDatabaseConfigForm}onConfigurationSet(e){this.getTelemetryFromDatabaseConfigForm=this.fb.group({latestTsKeyNames:[e.latestTsKeyNames,[O.required]],aggregation:[e.aggregation,[O.required]],fetchMode:[e.fetchMode,[O.required]],orderBy:[e.orderBy,[]],limit:[e.limit,[]],useMetadataIntervalPatterns:[e.useMetadataIntervalPatterns,[]],interval:this.fb.group({startInterval:[e.interval.startInterval,[]],startIntervalTimeUnit:[e.interval.startIntervalTimeUnit,[]],endInterval:[e.interval.endInterval,[]],endIntervalTimeUnit:[e.interval.endIntervalTimeUnit,[]]}),startIntervalPattern:[e.startIntervalPattern,[]],endIntervalPattern:[e.endIntervalPattern,[]]})}validatorTriggers(){return["fetchMode","useMetadataIntervalPatterns"]}toggleChange(e){this.getTelemetryFromDatabaseConfigForm.get("fetchMode").patchValue(e,{emitEvent:!0})}prepareOutputConfig(e){return e.startInterval=e.interval.startInterval,e.startIntervalTimeUnit=e.interval.startIntervalTimeUnit,e.endInterval=e.interval.endInterval,e.endIntervalTimeUnit=e.interval.endIntervalTimeUnit,delete e.interval,le(e)}prepareInputConfig(e){return se(e)&&(e.interval={startInterval:e.startInterval,startIntervalTimeUnit:e.startIntervalTimeUnit,endInterval:e.endInterval,endIntervalTimeUnit:e.endIntervalTimeUnit}),{latestTsKeyNames:ie(e?.latestTsKeyNames)?e.latestTsKeyNames:null,aggregation:ie(e?.aggregation)?e.aggregation:E.NONE,fetchMode:ie(e?.fetchMode)?e.fetchMode:Gt.FIRST,orderBy:ie(e?.orderBy)?e.orderBy:Vt.ASC,limit:ie(e?.limit)?e.limit:1e3,useMetadataIntervalPatterns:!!ie(e?.useMetadataIntervalPatterns)&&e.useMetadataIntervalPatterns,interval:{startInterval:ie(e?.interval?.startInterval)?e.interval.startInterval:2,startIntervalTimeUnit:ie(e?.interval?.startIntervalTimeUnit)?e.interval.startIntervalTimeUnit:Nt.MINUTES,endInterval:ie(e?.interval?.endInterval)?e.interval.endInterval:1,endIntervalTimeUnit:ie(e?.interval?.endIntervalTimeUnit)?e.interval.endIntervalTimeUnit:Nt.MINUTES},startIntervalPattern:ie(e?.startIntervalPattern)?e.startIntervalPattern:null,endIntervalPattern:ie(e?.endIntervalPattern)?e.endIntervalPattern:null}}updateValidators(e){const t=this.getTelemetryFromDatabaseConfigForm.get("fetchMode").value,n=this.getTelemetryFromDatabaseConfigForm.get("useMetadataIntervalPatterns").value;t&&t===Gt.ALL?(this.getTelemetryFromDatabaseConfigForm.get("aggregation").setValidators([O.required]),this.getTelemetryFromDatabaseConfigForm.get("orderBy").setValidators([O.required]),this.getTelemetryFromDatabaseConfigForm.get("limit").setValidators([O.required,O.min(2),O.max(1e3)])):(this.getTelemetryFromDatabaseConfigForm.get("aggregation").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("orderBy").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("limit").setValidators([])),n?(this.getTelemetryFromDatabaseConfigForm.get("interval.startInterval").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("interval.startIntervalTimeUnit").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("interval.endInterval").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("interval.endIntervalTimeUnit").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("interval").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("startIntervalPattern").setValidators([O.required,O.pattern(/(?:.|\s)*\S(&:.|\s)*/)]),this.getTelemetryFromDatabaseConfigForm.get("endIntervalPattern").setValidators([O.required,O.pattern(/(?:.|\s)*\S(&:.|\s)*/)])):(this.getTelemetryFromDatabaseConfigForm.get("interval.startInterval").setValidators([O.required,O.min(1),O.max(2147483647)]),this.getTelemetryFromDatabaseConfigForm.get("interval.startIntervalTimeUnit").setValidators([O.required]),this.getTelemetryFromDatabaseConfigForm.get("interval.endInterval").setValidators([O.required,O.min(1),O.max(2147483647)]),this.getTelemetryFromDatabaseConfigForm.get("interval.endIntervalTimeUnit").setValidators([O.required]),this.getTelemetryFromDatabaseConfigForm.get("interval").setValidators([this.intervalValidator()]),this.getTelemetryFromDatabaseConfigForm.get("startIntervalPattern").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("endIntervalPattern").setValidators([])),this.getTelemetryFromDatabaseConfigForm.get("aggregation").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("orderBy").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("limit").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("interval.startInterval").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("interval.startIntervalTimeUnit").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("interval.endInterval").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("interval.endIntervalTimeUnit").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("interval").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("startIntervalPattern").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("endIntervalPattern").updateValueAndValidity({emitEvent:e})}removeKey(e,t){const n=this.getTelemetryFromDatabaseConfigForm.get(t).value,r=n.indexOf(e);r>=0&&(n.splice(r,1),this.getTelemetryFromDatabaseConfigForm.get(t).setValue(n,{emitEvent:!0}))}clearChipGrid(){this.getTelemetryFromDatabaseConfigForm.get("latestTsKeyNames").patchValue([],{emitEvent:!0})}addKey(e,t){const n=e.input;let r=e.value;if((r||"").trim()){r=r.trim();let e=this.getTelemetryFromDatabaseConfigForm.get(t).value;e&&-1!==e.indexOf(r)||(e||(e=[]),e.push(r),this.getTelemetryFromDatabaseConfigForm.get(t).setValue(e,{emitEvent:!0}))}n&&(n.value="")}defaultPaddingEnable(){return this.getTelemetryFromDatabaseConfigForm.get("fetchMode").value===Gt.ALL&&this.getTelemetryFromDatabaseConfigForm.get("aggregation").value===E.NONE}}e("GetTelemetryFromDatabaseConfigComponent",Yn),Yn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Yn,deps:[{token:P.Store},{token:Z.TranslateService},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Yn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Yn,selector:"tb-enrichment-node-get-telemetry-from-database",usesInheritance:!0,ngImport:t,template:'
\n \n
\n help\n \n
\n
\n
tb.rulenode.fetch-interval
\n
\n \n {{ \'tb.rulenode.use-metadata-dynamic-interval\' | translate }}\n \n
\n
\n
\n \n {{ \'tb.rulenode.interval-start\' | translate }}\n \n \n {{ \'tb.rulenode.start-interval-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n {{ \'tb.rulenode.time-unit\' | translate }}\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n \n {{ \'tb.rulenode.interval-end\' | translate }}\n \n \n {{ \'tb.rulenode.end-interval-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n {{ \'tb.rulenode.time-unit\' | translate }}\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n error_outline\n
\n \n {{ \'tb.rulenode.fetch-timeseries-from-to\' | translate:\n {\n startInterval: getTelemetryFromDatabaseConfigForm.get(\'interval.startInterval\').value,\n endInterval: getTelemetryFromDatabaseConfigForm.get(\'interval.endInterval\').value,\n startIntervalTimeUnit: getTelemetryFromDatabaseConfigForm.get(\'interval.startIntervalTimeUnit\').value.toLowerCase(),\n endIntervalTimeUnit: getTelemetryFromDatabaseConfigForm.get(\'interval.endIntervalTimeUnit\').value.toLowerCase()\n } }}\n \n \n {{ "tb.rulenode.fetch-timeseries-from-to-invalid" | translate }}\n \n
\n
\n
\n \n
\n \n {{ \'tb.rulenode.start-interval\' | translate }}\n \n \n {{ \'tb.rulenode.start-interval-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.end-interval\' | translate }}\n \n \n {{ \'tb.rulenode.end-interval-required\' | translate }}\n \n \n \n \n
\n
\n
\n
\n
tb.rulenode.fetch-strategy
\n
\n
\n \n \n {{ data.name }}\n \n \n
\n
\n {{ deduplicationStrategiesHintTranslations.get(getTelemetryFromDatabaseConfigForm.get(\'fetchMode\').value) | translate }}\n
\n
\n
\n \n {{ \'aggregation.function\' | translate }}\n \n \n {{ aggregationTypesTranslations.get(aggregationTypes[aggregation]) | translate }}\n \n \n \n
\n \n {{ "tb.rulenode.order-by-timestamp" | translate }} \n \n \n {{ samplingOrdersTranslate.get(order) | translate }}\n \n \n \n \n {{ "tb.rulenode.limit" | translate }}\n \n {{ "tb.rulenode.limit-hint" | translate }}\n \n {{ \'tb.rulenode.limit-required\' | translate }}\n \n \n {{ \'tb.rulenode.limit-range\' | translate }}\n \n \n {{ \'tb.rulenode.limit-range\' | translate }}\n \n \n
\n
\n
\n
\n',styles:[":host .see-example{display:inline-block}:host .description-block{display:flex;align-items:center;border-radius:6px;border:1px solid #EAEAEA}:host .description-block .description-icon{font-size:24px;height:24px;min-height:24px;width:24px;min-width:24px;line-height:24px;color:#d9d9d9;margin:4px}:host .description-block .description-text{font-size:12px;line-height:16px;letter-spacing:.25px;margin:6px}:host .description-block.error{color:var(--mdc-theme-error, #f44336)}:host .description-block.error .description-icon{color:var(--mdc-theme-error, #f44336)}:host .item-center{align-items:center}:host .item-center .fetch-mod-toggle{width:100%}:host .hint-container{width:100%}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:He.HelpPopupComponent,selector:"[tb-help-popup], [tb-help-popup-content]",inputs:["tb-help-popup","tb-help-popup-content","trigger-text","trigger-style","tb-help-popup-placement","tb-help-popup-style","hintMode"]},{kind:"component",type:Ze.StringItemsListComponent,selector:"tb-string-items-list",inputs:["required","disabled","label","placeholder","hint","requiredText","floatLabel","appearance","editable","subscriptSizing","predefinedValues"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Y.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:te.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:R.FormGroupName,selector:"[formGroupName]",inputs:["formGroupName"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"directive",type:Xe.ToggleOption,selector:"tb-toggle-option",inputs:["value"]},{kind:"component",type:et.ToggleSelectComponent,selector:"tb-toggle-select",inputs:["disabled","selectMediaBreakpoint","appearance","disablePagination"]},{kind:"component",type:ne.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"component",type:Nn,selector:"tb-example-hint",inputs:["hintText","popupHelpLink","textAlign"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Yn,decorators:[{type:n,args:[{selector:"tb-enrichment-node-get-telemetry-from-database",template:'
\n \n
\n help\n \n
\n
\n
tb.rulenode.fetch-interval
\n
\n \n {{ \'tb.rulenode.use-metadata-dynamic-interval\' | translate }}\n \n
\n
\n
\n \n {{ \'tb.rulenode.interval-start\' | translate }}\n \n \n {{ \'tb.rulenode.start-interval-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n {{ \'tb.rulenode.time-unit\' | translate }}\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n \n {{ \'tb.rulenode.interval-end\' | translate }}\n \n \n {{ \'tb.rulenode.end-interval-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n {{ \'tb.rulenode.time-unit\' | translate }}\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n error_outline\n
\n \n {{ \'tb.rulenode.fetch-timeseries-from-to\' | translate:\n {\n startInterval: getTelemetryFromDatabaseConfigForm.get(\'interval.startInterval\').value,\n endInterval: getTelemetryFromDatabaseConfigForm.get(\'interval.endInterval\').value,\n startIntervalTimeUnit: getTelemetryFromDatabaseConfigForm.get(\'interval.startIntervalTimeUnit\').value.toLowerCase(),\n endIntervalTimeUnit: getTelemetryFromDatabaseConfigForm.get(\'interval.endIntervalTimeUnit\').value.toLowerCase()\n } }}\n \n \n {{ "tb.rulenode.fetch-timeseries-from-to-invalid" | translate }}\n \n
\n
\n
\n \n
\n \n {{ \'tb.rulenode.start-interval\' | translate }}\n \n \n {{ \'tb.rulenode.start-interval-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.end-interval\' | translate }}\n \n \n {{ \'tb.rulenode.end-interval-required\' | translate }}\n \n \n \n \n
\n
\n
\n
\n
tb.rulenode.fetch-strategy
\n
\n
\n \n \n {{ data.name }}\n \n \n
\n
\n {{ deduplicationStrategiesHintTranslations.get(getTelemetryFromDatabaseConfigForm.get(\'fetchMode\').value) | translate }}\n
\n
\n
\n \n {{ \'aggregation.function\' | translate }}\n \n \n {{ aggregationTypesTranslations.get(aggregationTypes[aggregation]) | translate }}\n \n \n \n
\n \n {{ "tb.rulenode.order-by-timestamp" | translate }} \n \n \n {{ samplingOrdersTranslate.get(order) | translate }}\n \n \n \n \n {{ "tb.rulenode.limit" | translate }}\n \n {{ "tb.rulenode.limit-hint" | translate }}\n \n {{ \'tb.rulenode.limit-required\' | translate }}\n \n \n {{ \'tb.rulenode.limit-range\' | translate }}\n \n \n {{ \'tb.rulenode.limit-range\' | translate }}\n \n \n
\n
\n
\n
\n',styles:[":host .see-example{display:inline-block}:host .description-block{display:flex;align-items:center;border-radius:6px;border:1px solid #EAEAEA}:host .description-block .description-icon{font-size:24px;height:24px;min-height:24px;width:24px;min-width:24px;line-height:24px;color:#d9d9d9;margin:4px}:host .description-block .description-text{font-size:12px;line-height:16px;letter-spacing:.25px;margin:6px}:host .description-block.error{color:var(--mdc-theme-error, #f44336)}:host .description-block.error .description-icon{color:var(--mdc-theme-error, #f44336)}:host .item-center{align-items:center}:host .item-center .fetch-mod-toggle{width:100%}:host .hint-container{width:100%}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:P.Store},{type:Z.TranslateService},{type:R.FormBuilder}]}});class Wn extends f{constructor(e,t,n){super(e),this.store=e,this.translate=t,this.fb=n}configForm(){return this.originatorAttributesConfigForm}onConfigurationSet(e){this.originatorAttributesConfigForm=this.fb.group({tellFailureIfAbsent:[e.tellFailureIfAbsent,[]],fetchTo:[e.fetchTo,[]],attributesControl:[e.attributesControl,[]]})}prepareInputConfig(e){return se(e)&&(e.attributesControl={clientAttributeNames:ie(e?.clientAttributeNames)?e.clientAttributeNames:[],latestTsKeyNames:ie(e?.latestTsKeyNames)?e.latestTsKeyNames:[],serverAttributeNames:ie(e?.serverAttributeNames)?e.serverAttributeNames:[],sharedAttributeNames:ie(e?.sharedAttributeNames)?e.sharedAttributeNames:[],getLatestValueWithTs:!!ie(e?.getLatestValueWithTs)&&e.getLatestValueWithTs}),{fetchTo:ie(e?.fetchTo)?e.fetchTo:en.METADATA,tellFailureIfAbsent:!!ie(e?.tellFailureIfAbsent)&&e.tellFailureIfAbsent,attributesControl:ie(e?.attributesControl)?e.attributesControl:null}}prepareOutputConfig(e){for(const t of Object.keys(e.attributesControl))e[t]=e.attributesControl[t];return delete e.attributesControl,e}}e("OriginatorAttributesConfigComponent",Wn),Wn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Wn,deps:[{token:P.Store},{token:Z.TranslateService},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Wn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Wn,selector:"tb-enrichment-node-originator-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n
\n
\n
tb.rulenode.originator-attributes
\n
\n tb.rulenode.at-least-one-field-required\n
\n
\n \n \n \n \n
\n
\n \n {{ \'tb.rulenode.tell-failure\' | translate }}\n \n
\n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"component",type:te.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:ne.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"component",type:On,selector:"tb-msg-metadata-chip",inputs:["labelText","translation"]},{kind:"component",type:Kn,selector:"tb-select-attributes",inputs:["popupHelpLink"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Wn,decorators:[{type:n,args:[{selector:"tb-enrichment-node-originator-attributes-config",template:'
\n
\n
\n
tb.rulenode.originator-attributes
\n
\n tb.rulenode.at-least-one-field-required\n
\n
\n \n \n \n \n
\n
\n \n {{ \'tb.rulenode.tell-failure\' | translate }}\n \n
\n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:P.Store},{type:Z.TranslateService},{type:R.FormBuilder}]}});class Zn extends f{constructor(e,t,n){super(e),this.store=e,this.fb=t,this.translate=n,this.originatorFields=[];for(const e of kt)this.originatorFields.push({value:e.value,name:this.translate.instant(e.name)})}configForm(){return this.originatorFieldsConfigForm}prepareOutputConfig(e){return le(e)}prepareInputConfig(e){return{dataMapping:ie(e?.dataMapping)?e.dataMapping:null,ignoreNullStrings:ie(e?.ignoreNullStrings)?e.ignoreNullStrings:null,fetchTo:ie(e?.fetchTo)?e.fetchTo:en.METADATA}}onConfigurationSet(e){this.originatorFieldsConfigForm=this.fb.group({dataMapping:[e.dataMapping,[O.required]],ignoreNullStrings:[e.ignoreNullStrings,[]],fetchTo:[e.fetchTo,[]]})}}e("OriginatorFieldsConfigComponent",Zn),Zn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Zn,deps:[{token:P.Store},{token:R.FormBuilder},{token:Z.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Zn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Zn,selector:"tb-enrichment-node-originator-fields-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n
\n \n {{ \'tb.rulenode.skip-empty-fields\' | translate }}\n \n
\n
\n',dependencies:[{kind:"component",type:te.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:ne.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"component",type:On,selector:"tb-msg-metadata-chip",inputs:["labelText","translation"]},{kind:"component",type:_n,selector:"tb-sv-map-config",inputs:["selectOptions","disabled","labelText","requiredText","targetKeyPrefix","selectText","selectRequiredText","valText","valRequiredText","hintText","popupHelpLink","required"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Zn,decorators:[{type:n,args:[{selector:"tb-enrichment-node-originator-fields-config",template:'
\n \n \n \n \n
\n \n {{ \'tb.rulenode.skip-empty-fields\' | translate }}\n \n
\n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder},{type:Z.TranslateService}]}});class Xn extends f{constructor(e,t,n){super(e),this.store=e,this.fb=t,this.translate=n,this.DataToFetch=Pt,this.msgMetadataLabelTranslations=Ot,this.originatorFields=[],this.fetchToData=[];for(const e of Object.keys(kt))this.originatorFields.push({value:kt[e].value,name:this.translate.instant(kt[e].name)});for(const e of Rt.keys())this.fetchToData.push({value:e,name:this.translate.instant(Rt.get(e))})}configForm(){return this.relatedAttributesConfigForm}prepareOutputConfig(e){e.dataToFetch===Pt.FIELDS?(e.dataMapping=e.svMap,delete e.svMap):(e.dataMapping=e.kvMap,delete e.kvMap);const t={};if(e&&e.dataMapping)for(const n of Object.keys(e.dataMapping))t[n.trim()]=e.dataMapping[n];return e.dataMapping=t,delete e.svMap,delete e.kvMap,le(e)}prepareInputConfig(e){let t,n,r={[k.name.value]:`relatedEntity${this.translate.instant(k.name.name)}`},o={serialNumber:"sn"};return t=ie(e?.telemetry)?e.telemetry?Pt.LATEST_TELEMETRY:Pt.ATTRIBUTES:ie(e?.dataToFetch)?e.dataToFetch:Pt.ATTRIBUTES,n=ie(e?.attrMapping)?e.attrMapping:ie(e?.dataMapping)?e.dataMapping:null,t===Pt.FIELDS?r=n:o=n,{relationsQuery:ie(e?.relationsQuery)?e.relationsQuery:null,dataToFetch:t,svMap:r,kvMap:o,fetchTo:ie(e?.fetchTo)?e.fetchTo:en.METADATA}}selectTranslation(e,t){return this.relatedAttributesConfigForm.get("dataToFetch").value===Pt.LATEST_TELEMETRY?e:t}onConfigurationSet(e){this.relatedAttributesConfigForm=this.fb.group({relationsQuery:[e.relationsQuery,[O.required]],dataToFetch:[e.dataToFetch,[]],kvMap:[e.kvMap,[O.required]],svMap:[e.svMap,[O.required]],fetchTo:[e.fetchTo,[]]})}validatorTriggers(){return["dataToFetch"]}updateValidators(e){this.relatedAttributesConfigForm.get("dataToFetch").value===Pt.FIELDS?(this.relatedAttributesConfigForm.get("svMap").enable({emitEvent:!1}),this.relatedAttributesConfigForm.get("kvMap").disable({emitEvent:!1}),this.relatedAttributesConfigForm.get("svMap").updateValueAndValidity()):(this.relatedAttributesConfigForm.get("svMap").disable({emitEvent:!1}),this.relatedAttributesConfigForm.get("kvMap").enable({emitEvent:!1}),this.relatedAttributesConfigForm.get("kvMap").updateValueAndValidity())}}e("RelatedAttributesConfigComponent",Xn),Xn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Xn,deps:[{token:P.Store},{token:R.FormBuilder},{token:Z.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Xn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Xn,selector:"tb-enrichment-node-related-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n
\n
tb.rulenode.data-to-fetch
\n \n \n {{ data.name }}\n \n \n \n \n \n \n \n \n
\n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"directive",type:Xe.ToggleOption,selector:"tb-toggle-option",inputs:["value"]},{kind:"component",type:et.ToggleSelectComponent,selector:"tb-toggle-select",inputs:["disabled","selectMediaBreakpoint","appearance","disablePagination"]},{kind:"component",type:Sn,selector:"tb-kv-map-config",inputs:["disabled","uniqueKeyValuePairValidator","labelText","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","popupHelpLink","required"]},{kind:"component",type:An,selector:"tb-relations-query-config",inputs:["disabled","required"]},{kind:"component",type:On,selector:"tb-msg-metadata-chip",inputs:["labelText","translation"]},{kind:"component",type:_n,selector:"tb-sv-map-config",inputs:["selectOptions","disabled","labelText","requiredText","targetKeyPrefix","selectText","selectRequiredText","valText","valRequiredText","hintText","popupHelpLink","required"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Xn,decorators:[{type:n,args:[{selector:"tb-enrichment-node-related-attributes-config",template:'
\n \n \n
\n
tb.rulenode.data-to-fetch
\n \n \n {{ data.name }}\n \n \n \n \n \n \n \n \n
\n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder},{type:Z.TranslateService}]}});class er extends f{constructor(e,t,n){super(e),this.store=e,this.fb=t,this.translate=n,this.fetchToData=[],this.DataToFetch=Pt;for(const e of Rt.keys())e!==Pt.FIELDS&&this.fetchToData.push({value:e,name:this.translate.instant(Rt.get(e))})}configForm(){return this.tenantAttributesConfigForm}prepareInputConfig(e){let t,n;return t=ie(e?.telemetry)?e.telemetry?Pt.LATEST_TELEMETRY:Pt.ATTRIBUTES:ie(e?.dataToFetch)?e.dataToFetch:Pt.ATTRIBUTES,n=ie(e?.attrMapping)?e.attrMapping:ie(e?.dataMapping)?e.dataMapping:null,{dataToFetch:t,dataMapping:n,fetchTo:ie(e?.fetchTo)?e.fetchTo:en.METADATA}}selectTranslation(e,t){return this.tenantAttributesConfigForm.get("dataToFetch").value===Pt.LATEST_TELEMETRY?e:t}onConfigurationSet(e){this.tenantAttributesConfigForm=this.fb.group({dataToFetch:[e.dataToFetch,[]],dataMapping:[e.dataMapping,[O.required]],fetchTo:[e.fetchTo,[]]})}}e("TenantAttributesConfigComponent",er),er.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:er,deps:[{token:P.Store},{token:R.FormBuilder},{token:Z.TranslateService}],target:t.ɵɵFactoryTarget.Component}),er.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:er,selector:"tb-enrichment-node-tenant-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n
tb.rulenode.mapping-of-tenant
\n
\n
\n \n \n {{ data.name }}\n \n \n
\n
\n \n \n \n \n
\n',styles:[":host .fetch-to-data-toggle{max-width:420px;width:100%}\n"],dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:W.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"directive",type:Xe.ToggleOption,selector:"tb-toggle-option",inputs:["value"]},{kind:"component",type:et.ToggleSelectComponent,selector:"tb-toggle-select",inputs:["disabled","selectMediaBreakpoint","appearance","disablePagination"]},{kind:"component",type:Sn,selector:"tb-kv-map-config",inputs:["disabled","uniqueKeyValuePairValidator","labelText","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","popupHelpLink","required"]},{kind:"component",type:On,selector:"tb-msg-metadata-chip",inputs:["labelText","translation"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:er,decorators:[{type:n,args:[{selector:"tb-enrichment-node-tenant-attributes-config",template:'
\n
tb.rulenode.mapping-of-tenant
\n
\n
\n \n \n {{ data.name }}\n \n \n
\n
\n \n \n \n \n
\n',styles:[":host .fetch-to-data-toggle{max-width:420px;width:100%}\n"]}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder},{type:Z.TranslateService}]}});class tr extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.fetchDeviceCredentialsConfigForm}prepareInputConfig(e){return{fetchTo:ie(e?.fetchTo)?e.fetchTo:en.METADATA}}onConfigurationSet(e){this.fetchDeviceCredentialsConfigForm=this.fb.group({fetchTo:[e.fetchTo,[]]})}}e("FetchDeviceCredentialsConfigComponent",tr),tr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:tr,deps:[{token:P.Store},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),tr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:tr,selector:"./tb-enrichment-node-fetch-device-credentials-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n
\n',dependencies:[{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:On,selector:"tb-msg-metadata-chip",inputs:["labelText","translation"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:tr,decorators:[{type:n,args:[{selector:"./tb-enrichment-node-fetch-device-credentials-config",template:'
\n \n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder}]}});class nr{}e("RulenodeCoreConfigEnrichmentModule",nr),nr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:nr,deps:[],target:t.ɵɵFactoryTarget.NgModule}),nr.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.10",ngImport:t,type:nr,declarations:[$n,Jn,Qn,Wn,Zn,Yn,Xn,er,jn,tr],imports:[$,M,Un],exports:[$n,Jn,Qn,Wn,Zn,Yn,Xn,er,jn,tr]}),nr.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:nr,imports:[$,M,Un]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:nr,decorators:[{type:c,args:[{declarations:[$n,Jn,Qn,Wn,Zn,Yn,Xn,er,jn,tr],imports:[$,M,Un],exports:[$n,Jn,Qn,Wn,Zn,Yn,Xn,er,jn,tr]}]}]});class rr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.allAzureIotHubCredentialsTypes=Ht,this.azureIotHubCredentialsTypeTranslationsMap=jt}configForm(){return this.azureIotHubConfigForm}onConfigurationSet(e){this.azureIotHubConfigForm=this.fb.group({topicPattern:[e?e.topicPattern:null,[O.required]],host:[e?e.host:null,[O.required]],port:[e?e.port:null,[O.required,O.min(1),O.max(65535)]],connectTimeoutSec:[e?e.connectTimeoutSec:null,[O.required,O.min(1),O.max(200)]],clientId:[e?e.clientId:null,[O.required]],cleanSession:[!!e&&e.cleanSession,[]],ssl:[!!e&&e.ssl,[]],credentials:this.fb.group({type:[e&&e.credentials?e.credentials.type:null,[O.required]],sasKey:[e&&e.credentials?e.credentials.sasKey:null,[]],caCert:[e&&e.credentials?e.credentials.caCert:null,[]],caCertFileName:[e&&e.credentials?e.credentials.caCertFileName:null,[]],privateKey:[e&&e.credentials?e.credentials.privateKey:null,[]],privateKeyFileName:[e&&e.credentials?e.credentials.privateKeyFileName:null,[]],cert:[e&&e.credentials?e.credentials.cert:null,[]],certFileName:[e&&e.credentials?e.credentials.certFileName:null,[]],password:[e&&e.credentials?e.credentials.password:null,[]]})})}prepareOutputConfig(e){const t=e.credentials.type;return"sas"===t&&(e.credentials={type:t,sasKey:e.credentials.sasKey,caCert:e.credentials.caCert,caCertFileName:e.credentials.caCertFileName}),e}validatorTriggers(){return["credentials.type"]}updateValidators(e){const t=this.azureIotHubConfigForm.get("credentials"),n=t.get("type").value;switch(e&&t.reset({type:n},{emitEvent:!1}),t.get("sasKey").setValidators([]),t.get("privateKey").setValidators([]),t.get("privateKeyFileName").setValidators([]),t.get("cert").setValidators([]),t.get("certFileName").setValidators([]),n){case"sas":t.get("sasKey").setValidators([O.required]);break;case"cert.PEM":t.get("privateKey").setValidators([O.required]),t.get("privateKeyFileName").setValidators([O.required]),t.get("cert").setValidators([O.required]),t.get("certFileName").setValidators([O.required])}t.get("sasKey").updateValueAndValidity({emitEvent:e}),t.get("privateKey").updateValueAndValidity({emitEvent:e}),t.get("privateKeyFileName").updateValueAndValidity({emitEvent:e}),t.get("cert").updateValueAndValidity({emitEvent:e}),t.get("certFileName").updateValueAndValidity({emitEvent:e})}}e("AzureIotHubConfigComponent",rr),rr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:rr,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),rr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:rr,selector:"tb-external-node-azure-iot-hub-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.topic\n \n \n {{ \'tb.rulenode.topic-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.hostname\n \n \n {{ \'tb.rulenode.hostname-required\' | translate }}\n \n \n \n tb.rulenode.device-id\n \n \n {{ \'tb.rulenode.device-id-required\' | translate }}\n \n \n \n \n \n tb.rulenode.credentials\n \n {{ azureIotHubCredentialsTypeTranslationsMap.get(azureIotHubConfigForm.get(\'credentials.type\').value) | translate }}\n \n \n
\n \n tb.rulenode.credentials-type\n \n \n {{ azureIotHubCredentialsTypeTranslationsMap.get(credentialsType) | translate }}\n \n \n \n {{ \'tb.rulenode.credentials-type-required\' | translate }}\n \n \n
\n \n \n \n \n tb.rulenode.sas-key\n \n \n \n {{ \'tb.rulenode.sas-key-required\' | translate }}\n \n \n \n \n \n \n \n \n \n \n \n \n \n tb.rulenode.private-key-password\n \n \n \n \n
\n
\n
\n
\n
\n',styles:[":host .tb-mqtt-credentials-panel-group{margin:0 6px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:H.NgSwitch,selector:"[ngSwitch]",inputs:["ngSwitch"]},{kind:"directive",type:H.NgSwitchCase,selector:"[ngSwitchCase]",inputs:["ngSwitchCase"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Y.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:Je.MatAccordion,selector:"mat-accordion",inputs:["multi","hideToggle","displayMode","togglePosition"],exportAs:["matAccordion"]},{kind:"component",type:Je.MatExpansionPanel,selector:"mat-expansion-panel",inputs:["disabled","expanded","hideToggle","togglePosition"],outputs:["opened","closed","expandedChange","afterExpand","afterCollapse"],exportAs:["matExpansionPanel"]},{kind:"component",type:Je.MatExpansionPanelHeader,selector:"mat-expansion-panel-header",inputs:["tabIndex","expandedHeight","collapsedHeight"]},{kind:"directive",type:Je.MatExpansionPanelTitle,selector:"mat-panel-title"},{kind:"directive",type:Je.MatExpansionPanelDescription,selector:"mat-panel-description"},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:R.FormGroupName,selector:"[formGroupName]",inputs:["formGroupName"]},{kind:"component",type:Ye.FileInputComponent,selector:"tb-file-input",inputs:["label","hint","accept","noFileText","inputId","allowedExtensions","dropLabel","contentConvertFunction","required","requiredAsError","disabled","existingFileName","readAsBinary","workFromFileObj","multipleFile"],outputs:["fileNameChanged"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:We.TogglePasswordComponent,selector:"tb-toggle-password"},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:rr,decorators:[{type:n,args:[{selector:"tb-external-node-azure-iot-hub-config",template:'
\n \n tb.rulenode.topic\n \n \n {{ \'tb.rulenode.topic-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.hostname\n \n \n {{ \'tb.rulenode.hostname-required\' | translate }}\n \n \n \n tb.rulenode.device-id\n \n \n {{ \'tb.rulenode.device-id-required\' | translate }}\n \n \n \n \n \n tb.rulenode.credentials\n \n {{ azureIotHubCredentialsTypeTranslationsMap.get(azureIotHubConfigForm.get(\'credentials.type\').value) | translate }}\n \n \n
\n \n tb.rulenode.credentials-type\n \n \n {{ azureIotHubCredentialsTypeTranslationsMap.get(credentialsType) | translate }}\n \n \n \n {{ \'tb.rulenode.credentials-type-required\' | translate }}\n \n \n
\n \n \n \n \n tb.rulenode.sas-key\n \n \n \n {{ \'tb.rulenode.sas-key-required\' | translate }}\n \n \n \n \n \n \n \n \n \n \n \n \n \n tb.rulenode.private-key-password\n \n \n \n \n
\n
\n
\n
\n
\n',styles:[":host .tb-mqtt-credentials-panel-group{margin:0 6px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class or extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.ackValues=["all","-1","0","1"],this.ToByteStandartCharsetTypesValues=Qt,this.ToByteStandartCharsetTypeTranslationMap=Jt}configForm(){return this.kafkaConfigForm}onConfigurationSet(e){this.kafkaConfigForm=this.fb.group({topicPattern:[e?e.topicPattern:null,[O.required]],keyPattern:[e?e.keyPattern:null],bootstrapServers:[e?e.bootstrapServers:null,[O.required]],retries:[e?e.retries:null,[O.min(0)]],batchSize:[e?e.batchSize:null,[O.min(0)]],linger:[e?e.linger:null,[O.min(0)]],bufferMemory:[e?e.bufferMemory:null,[O.min(0)]],acks:[e?e.acks:null,[O.required]],keySerializer:[e?e.keySerializer:null,[O.required]],valueSerializer:[e?e.valueSerializer:null,[O.required]],otherProperties:[e?e.otherProperties:null,[]],addMetadataKeyValuesAsKafkaHeaders:[!!e&&e.addMetadataKeyValuesAsKafkaHeaders,[]],kafkaHeadersCharset:[e?e.kafkaHeadersCharset:null,[]]})}validatorTriggers(){return["addMetadataKeyValuesAsKafkaHeaders"]}updateValidators(e){this.kafkaConfigForm.get("addMetadataKeyValuesAsKafkaHeaders").value?this.kafkaConfigForm.get("kafkaHeadersCharset").setValidators([O.required]):this.kafkaConfigForm.get("kafkaHeadersCharset").setValidators([]),this.kafkaConfigForm.get("kafkaHeadersCharset").updateValueAndValidity({emitEvent:e})}}e("KafkaConfigComponent",or),or.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:or,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),or.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:or,selector:"tb-external-node-kafka-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.topic-pattern\n \n \n {{ \'tb.rulenode.topic-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.key-pattern\n \n tb.rulenode.general-pattern-hint\n \n
tb.rulenode.key-pattern-hint
\n \n tb.rulenode.bootstrap-servers\n \n \n {{ \'tb.rulenode.bootstrap-servers-required\' | translate }}\n \n \n \n tb.rulenode.retries\n \n \n {{ \'tb.rulenode.min-retries-message\' | translate }}\n \n \n \n tb.rulenode.batch-size-bytes\n \n \n {{ \'tb.rulenode.min-batch-size-bytes-message\' | translate }}\n \n \n \n tb.rulenode.linger-ms\n \n \n {{ \'tb.rulenode.min-linger-ms-message\' | translate }}\n \n \n \n tb.rulenode.buffer-memory-bytes\n \n \n {{ \'tb.rulenode.min-buffer-memory-bytes-message\' | translate }}\n \n \n \n tb.rulenode.acks\n \n \n {{ ackValue }}\n \n \n \n \n tb.rulenode.key-serializer\n \n \n {{ \'tb.rulenode.key-serializer-required\' | translate }}\n \n \n \n tb.rulenode.value-serializer\n \n \n {{ \'tb.rulenode.value-serializer-required\' | translate }}\n \n \n \n \n \n \n {{ \'tb.rulenode.add-metadata-key-values-as-kafka-headers\' | translate }}\n \n
tb.rulenode.add-metadata-key-values-as-kafka-headers-hint
\n \n tb.rulenode.charset-encoding\n \n \n {{ ToByteStandartCharsetTypeTranslationMap.get(charset) | translate }}\n \n \n \n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Q.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:hn,selector:"tb-kv-map-config-old",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:or,decorators:[{type:n,args:[{selector:"tb-external-node-kafka-config",template:'
\n \n tb.rulenode.topic-pattern\n \n \n {{ \'tb.rulenode.topic-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.key-pattern\n \n tb.rulenode.general-pattern-hint\n \n
tb.rulenode.key-pattern-hint
\n \n tb.rulenode.bootstrap-servers\n \n \n {{ \'tb.rulenode.bootstrap-servers-required\' | translate }}\n \n \n \n tb.rulenode.retries\n \n \n {{ \'tb.rulenode.min-retries-message\' | translate }}\n \n \n \n tb.rulenode.batch-size-bytes\n \n \n {{ \'tb.rulenode.min-batch-size-bytes-message\' | translate }}\n \n \n \n tb.rulenode.linger-ms\n \n \n {{ \'tb.rulenode.min-linger-ms-message\' | translate }}\n \n \n \n tb.rulenode.buffer-memory-bytes\n \n \n {{ \'tb.rulenode.min-buffer-memory-bytes-message\' | translate }}\n \n \n \n tb.rulenode.acks\n \n \n {{ ackValue }}\n \n \n \n \n tb.rulenode.key-serializer\n \n \n {{ \'tb.rulenode.key-serializer-required\' | translate }}\n \n \n \n tb.rulenode.value-serializer\n \n \n {{ \'tb.rulenode.value-serializer-required\' | translate }}\n \n \n \n \n \n \n {{ \'tb.rulenode.add-metadata-key-values-as-kafka-headers\' | translate }}\n \n
tb.rulenode.add-metadata-key-values-as-kafka-headers-hint
\n \n tb.rulenode.charset-encoding\n \n \n {{ ToByteStandartCharsetTypeTranslationMap.get(charset) | translate }}\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class ar extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.mqttConfigForm}onConfigurationSet(e){this.mqttConfigForm=this.fb.group({topicPattern:[e?e.topicPattern:null,[O.required]],host:[e?e.host:null,[O.required]],port:[e?e.port:null,[O.required,O.min(1),O.max(65535)]],connectTimeoutSec:[e?e.connectTimeoutSec:null,[O.required,O.min(1),O.max(200)]],clientId:[e?e.clientId:null,[]],appendClientIdSuffix:[{value:!!e&&e.appendClientIdSuffix,disabled:!(e&&me(e.clientId))},[]],cleanSession:[!!e&&e.cleanSession,[]],retainedMessage:[!!e&&e.retainedMessage,[]],ssl:[!!e&&e.ssl,[]],credentials:[e?e.credentials:null,[]]})}updateValidators(e){me(this.mqttConfigForm.get("clientId").value)?this.mqttConfigForm.get("appendClientIdSuffix").enable({emitEvent:!1}):this.mqttConfigForm.get("appendClientIdSuffix").disable({emitEvent:!1}),this.mqttConfigForm.get("appendClientIdSuffix").updateValueAndValidity({emitEvent:e})}validatorTriggers(){return["clientId"]}}e("MqttConfigComponent",ar),ar.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ar,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),ar.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:ar,selector:"tb-external-node-mqtt-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.topic-pattern\n \n \n {{ \'tb.rulenode.topic-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n
\n \n tb.rulenode.host\n \n \n {{ \'tb.rulenode.host-required\' | translate }}\n \n \n \n tb.rulenode.port\n \n \n {{ \'tb.rulenode.port-required\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n \n tb.rulenode.connect-timeout\n \n \n {{ \'tb.rulenode.connect-timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.connect-timeout-range\' | translate }}\n \n \n {{ \'tb.rulenode.connect-timeout-range\' | translate }}\n \n \n
\n \n tb.rulenode.client-id\n \n {{\'tb.rulenode.client-id-hint\' | translate}}\n \n \n {{ \'tb.rulenode.append-client-id-suffix\' | translate }}\n \n
{{ "tb.rulenode.client-id-suffix-hint" | translate }}
\n \n {{ \'tb.rulenode.clean-session\' | translate }}\n \n \n {{ "tb.rulenode.retained-message" | translate }}\n \n \n {{ \'tb.rulenode.enable-ssl\' | translate }}\n \n \n
\n',styles:[":host .tb-mqtt-credentials-panel-group{margin:0 6px}\n"],dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Q.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:En,selector:"tb-credentials-config",inputs:["required","disableCertPemCredentials","passwordFieldRequired"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ar,decorators:[{type:n,args:[{selector:"tb-external-node-mqtt-config",template:'
\n \n tb.rulenode.topic-pattern\n \n \n {{ \'tb.rulenode.topic-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n
\n \n tb.rulenode.host\n \n \n {{ \'tb.rulenode.host-required\' | translate }}\n \n \n \n tb.rulenode.port\n \n \n {{ \'tb.rulenode.port-required\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n \n tb.rulenode.connect-timeout\n \n \n {{ \'tb.rulenode.connect-timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.connect-timeout-range\' | translate }}\n \n \n {{ \'tb.rulenode.connect-timeout-range\' | translate }}\n \n \n
\n \n tb.rulenode.client-id\n \n {{\'tb.rulenode.client-id-hint\' | translate}}\n \n \n {{ \'tb.rulenode.append-client-id-suffix\' | translate }}\n \n
{{ "tb.rulenode.client-id-suffix-hint" | translate }}
\n \n {{ \'tb.rulenode.clean-session\' | translate }}\n \n \n {{ "tb.rulenode.retained-message" | translate }}\n \n \n {{ \'tb.rulenode.enable-ssl\' | translate }}\n \n \n
\n',styles:[":host .tb-mqtt-credentials-panel-group{margin:0 6px}\n"]}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class ir extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.notificationType=D,this.entityType=F}configForm(){return this.notificationConfigForm}onConfigurationSet(e){this.notificationConfigForm=this.fb.group({templateId:[e?e.templateId:null,[O.required]],targets:[e?e.targets:[],[O.required]]})}}e("NotificationConfigComponent",ir),ir.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ir,deps:[{token:P.Store},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),ir.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:ir,selector:"tb-external-node-notification-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n
\n',dependencies:[{kind:"component",type:tt.EntityListComponent,selector:"tb-entity-list",inputs:["entityType","subType","labelText","placeholderText","requiredText","required","disabled","subscriptSizing","hint"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:nt.TemplateAutocompleteComponent,selector:"tb-template-autocomplete",inputs:["required","allowCreate","allowEdit","disabled","notificationTypes"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ir,decorators:[{type:n,args:[{selector:"tb-external-node-notification-config",template:'
\n \n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder}]}});class lr extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.pubSubConfigForm}onConfigurationSet(e){this.pubSubConfigForm=this.fb.group({projectId:[e?e.projectId:null,[O.required]],topicName:[e?e.topicName:null,[O.required]],serviceAccountKey:[e?e.serviceAccountKey:null,[O.required]],serviceAccountKeyFileName:[e?e.serviceAccountKeyFileName:null,[O.required]],messageAttributes:[e?e.messageAttributes:null,[]]})}}e("PubSubConfigComponent",lr),lr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:lr,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),lr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:lr,selector:"tb-external-node-pub-sub-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.gcp-project-id\n \n \n {{ \'tb.rulenode.gcp-project-id-required\' | translate }}\n \n \n \n tb.rulenode.pubsub-topic-name\n \n \n {{ \'tb.rulenode.pubsub-topic-name-required\' | translate }}\n \n \n \n \n \n
\n \n \n
\n',dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:Ye.FileInputComponent,selector:"tb-file-input",inputs:["label","hint","accept","noFileText","inputId","allowedExtensions","dropLabel","contentConvertFunction","required","requiredAsError","disabled","existingFileName","readAsBinary","workFromFileObj","multipleFile"],outputs:["fileNameChanged"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:hn,selector:"tb-kv-map-config-old",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:he.SafePipe,name:"safe"},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:lr,decorators:[{type:n,args:[{selector:"tb-external-node-pub-sub-config",template:'
\n \n tb.rulenode.gcp-project-id\n \n \n {{ \'tb.rulenode.gcp-project-id-required\' | translate }}\n \n \n \n tb.rulenode.pubsub-topic-name\n \n \n {{ \'tb.rulenode.pubsub-topic-name-required\' | translate }}\n \n \n \n \n \n
\n \n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class sr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.messageProperties=[null,"BASIC","TEXT_PLAIN","MINIMAL_BASIC","MINIMAL_PERSISTENT_BASIC","PERSISTENT_BASIC","PERSISTENT_TEXT_PLAIN"]}configForm(){return this.rabbitMqConfigForm}onConfigurationSet(e){this.rabbitMqConfigForm=this.fb.group({exchangeNamePattern:[e?e.exchangeNamePattern:null,[]],routingKeyPattern:[e?e.routingKeyPattern:null,[]],messageProperties:[e?e.messageProperties:null,[]],host:[e?e.host:null,[O.required]],port:[e?e.port:null,[O.required,O.min(1),O.max(65535)]],virtualHost:[e?e.virtualHost:null,[]],username:[e?e.username:null,[]],password:[e?e.password:null,[]],automaticRecoveryEnabled:[!!e&&e.automaticRecoveryEnabled,[]],connectionTimeout:[e?e.connectionTimeout:null,[O.min(0)]],handshakeTimeout:[e?e.handshakeTimeout:null,[O.min(0)]],clientProperties:[e?e.clientProperties:null,[]]})}}e("RabbitMqConfigComponent",sr),sr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:sr,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),sr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:sr,selector:"tb-external-node-rabbit-mq-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.exchange-name-pattern\n \n \n \n tb.rulenode.routing-key-pattern\n \n \n \n tb.rulenode.message-properties\n \n \n {{ property }}\n \n \n \n
\n \n tb.rulenode.host\n \n \n {{ \'tb.rulenode.host-required\' | translate }}\n \n \n \n tb.rulenode.port\n \n \n {{ \'tb.rulenode.port-required\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n
\n \n tb.rulenode.virtual-host\n \n \n \n tb.rulenode.username\n \n \n \n tb.rulenode.password\n \n \n \n \n {{ \'tb.rulenode.automatic-recovery\' | translate }}\n \n \n tb.rulenode.connection-timeout-ms\n \n \n {{ \'tb.rulenode.min-connection-timeout-ms-message\' | translate }}\n \n \n \n tb.rulenode.handshake-timeout-ms\n \n \n {{ \'tb.rulenode.min-handshake-timeout-ms-message\' | translate }}\n \n \n \n \n \n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Q.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Y.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:We.TogglePasswordComponent,selector:"tb-toggle-password"},{kind:"component",type:hn,selector:"tb-kv-map-config-old",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:sr,decorators:[{type:n,args:[{selector:"tb-external-node-rabbit-mq-config",template:'
\n \n tb.rulenode.exchange-name-pattern\n \n \n \n tb.rulenode.routing-key-pattern\n \n \n \n tb.rulenode.message-properties\n \n \n {{ property }}\n \n \n \n
\n \n tb.rulenode.host\n \n \n {{ \'tb.rulenode.host-required\' | translate }}\n \n \n \n tb.rulenode.port\n \n \n {{ \'tb.rulenode.port-required\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n
\n \n tb.rulenode.virtual-host\n \n \n \n tb.rulenode.username\n \n \n \n tb.rulenode.password\n \n \n \n \n {{ \'tb.rulenode.automatic-recovery\' | translate }}\n \n \n tb.rulenode.connection-timeout-ms\n \n \n {{ \'tb.rulenode.min-connection-timeout-ms-message\' | translate }}\n \n \n \n tb.rulenode.handshake-timeout-ms\n \n \n {{ \'tb.rulenode.min-handshake-timeout-ms-message\' | translate }}\n \n \n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class mr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.proxySchemes=["http","https"],this.httpRequestTypes=Object.keys($t)}configForm(){return this.restApiCallConfigForm}onConfigurationSet(e){this.restApiCallConfigForm=this.fb.group({restEndpointUrlPattern:[e?e.restEndpointUrlPattern:null,[O.required]],requestMethod:[e?e.requestMethod:null,[O.required]],useSimpleClientHttpFactory:[!!e&&e.useSimpleClientHttpFactory,[]],parseToPlainText:[!!e&&e.parseToPlainText,[]],ignoreRequestBody:[!!e&&e.ignoreRequestBody,[]],enableProxy:[!!e&&e.enableProxy,[]],useSystemProxyProperties:[!!e&&e.enableProxy,[]],proxyScheme:[e?e.proxyHost:null,[]],proxyHost:[e?e.proxyHost:null,[]],proxyPort:[e?e.proxyPort:null,[]],proxyUser:[e?e.proxyUser:null,[]],proxyPassword:[e?e.proxyPassword:null,[]],readTimeoutMs:[e?e.readTimeoutMs:null,[]],maxParallelRequestsCount:[e?e.maxParallelRequestsCount:null,[O.min(0)]],headers:[e?e.headers:null,[]],useRedisQueueForMsgPersistence:[!!e&&e.useRedisQueueForMsgPersistence,[]],trimQueue:[!!e&&e.trimQueue,[]],maxQueueSize:[e?e.maxQueueSize:null,[]],credentials:[e?e.credentials:null,[]]})}validatorTriggers(){return["useSimpleClientHttpFactory","useRedisQueueForMsgPersistence","enableProxy","useSystemProxyProperties"]}updateValidators(e){const t=this.restApiCallConfigForm.get("useSimpleClientHttpFactory").value,n=this.restApiCallConfigForm.get("useRedisQueueForMsgPersistence").value,r=this.restApiCallConfigForm.get("enableProxy").value,o=this.restApiCallConfigForm.get("useSystemProxyProperties").value;r&&!o?(this.restApiCallConfigForm.get("proxyHost").setValidators(r?[O.required]:[]),this.restApiCallConfigForm.get("proxyPort").setValidators(r?[O.required,O.min(1),O.max(65535)]:[])):(this.restApiCallConfigForm.get("proxyHost").setValidators([]),this.restApiCallConfigForm.get("proxyPort").setValidators([]),t?this.restApiCallConfigForm.get("readTimeoutMs").setValidators([]):this.restApiCallConfigForm.get("readTimeoutMs").setValidators([O.min(0)])),n?this.restApiCallConfigForm.get("maxQueueSize").setValidators([O.min(0)]):this.restApiCallConfigForm.get("maxQueueSize").setValidators([]),this.restApiCallConfigForm.get("readTimeoutMs").updateValueAndValidity({emitEvent:e}),this.restApiCallConfigForm.get("maxQueueSize").updateValueAndValidity({emitEvent:e}),this.restApiCallConfigForm.get("proxyHost").updateValueAndValidity({emitEvent:e}),this.restApiCallConfigForm.get("proxyPort").updateValueAndValidity({emitEvent:e}),this.restApiCallConfigForm.get("credentials").updateValueAndValidity({emitEvent:e})}}e("RestApiCallConfigComponent",mr),mr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:mr,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),mr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:mr,selector:"tb-external-node-rest-api-call-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.endpoint-url-pattern\n \n \n {{ \'tb.rulenode.endpoint-url-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.request-method\n \n \n {{ requestType }}\n \n \n \n \n {{ \'tb.rulenode.enable-proxy\' | translate }}\n \n \n {{ \'tb.rulenode.use-simple-client-http-factory\' | translate }}\n \n \n {{ \'tb.rulenode.parse-to-plain-text\' | translate }}\n \n
tb.rulenode.parse-to-plain-text-hint
\n \n {{ \'tb.rulenode.ignore-request-body\' | translate }}\n \n
\n \n {{ \'tb.rulenode.use-system-proxy-properties\' | translate }}\n \n
\n
\n \n tb.rulenode.proxy-scheme\n \n \n {{ proxyScheme }}\n \n \n \n \n tb.rulenode.proxy-host\n \n \n {{ \'tb.rulenode.proxy-host-required\' | translate }}\n \n \n \n tb.rulenode.proxy-port\n \n \n {{ \'tb.rulenode.proxy-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.proxy-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.proxy-user\n \n \n \n tb.rulenode.proxy-password\n \n \n
\n
\n \n tb.rulenode.read-timeout\n \n tb.rulenode.read-timeout-hint\n \n \n tb.rulenode.max-parallel-requests-count\n \n tb.rulenode.max-parallel-requests-count-hint\n \n \n
\n \n \n \n {{ \'tb.rulenode.use-redis-queue\' | translate }}\n \n
\n \n {{ \'tb.rulenode.trim-redis-queue\' | translate }}\n \n \n tb.rulenode.redis-queue-max-size\n \n \n
\n \n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Q.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:En,selector:"tb-credentials-config",inputs:["required","disableCertPemCredentials","passwordFieldRequired"]},{kind:"component",type:hn,selector:"tb-kv-map-config-old",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:he.SafePipe,name:"safe"},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:mr,decorators:[{type:n,args:[{selector:"tb-external-node-rest-api-call-config",template:'
\n \n tb.rulenode.endpoint-url-pattern\n \n \n {{ \'tb.rulenode.endpoint-url-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.request-method\n \n \n {{ requestType }}\n \n \n \n \n {{ \'tb.rulenode.enable-proxy\' | translate }}\n \n \n {{ \'tb.rulenode.use-simple-client-http-factory\' | translate }}\n \n \n {{ \'tb.rulenode.parse-to-plain-text\' | translate }}\n \n
tb.rulenode.parse-to-plain-text-hint
\n \n {{ \'tb.rulenode.ignore-request-body\' | translate }}\n \n
\n \n {{ \'tb.rulenode.use-system-proxy-properties\' | translate }}\n \n
\n
\n \n tb.rulenode.proxy-scheme\n \n \n {{ proxyScheme }}\n \n \n \n \n tb.rulenode.proxy-host\n \n \n {{ \'tb.rulenode.proxy-host-required\' | translate }}\n \n \n \n tb.rulenode.proxy-port\n \n \n {{ \'tb.rulenode.proxy-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.proxy-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.proxy-user\n \n \n \n tb.rulenode.proxy-password\n \n \n
\n
\n \n tb.rulenode.read-timeout\n \n tb.rulenode.read-timeout-hint\n \n \n tb.rulenode.max-parallel-requests-count\n \n tb.rulenode.max-parallel-requests-count-hint\n \n \n
\n \n \n \n {{ \'tb.rulenode.use-redis-queue\' | translate }}\n \n
\n \n {{ \'tb.rulenode.trim-redis-queue\' | translate }}\n \n \n tb.rulenode.redis-queue-max-size\n \n \n
\n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class pr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.smtpProtocols=["smtp","smtps"],this.tlsVersions=["TLSv1","TLSv1.1","TLSv1.2","TLSv1.3"]}configForm(){return this.sendEmailConfigForm}onConfigurationSet(e){this.sendEmailConfigForm=this.fb.group({useSystemSmtpSettings:[!!e&&e.useSystemSmtpSettings,[]],smtpProtocol:[e?e.smtpProtocol:null,[]],smtpHost:[e?e.smtpHost:null,[]],smtpPort:[e?e.smtpPort:null,[]],timeout:[e?e.timeout:null,[]],enableTls:[!!e&&e.enableTls,[]],tlsVersion:[e?e.tlsVersion:null,[]],enableProxy:[!!e&&e.enableProxy,[]],proxyHost:[e?e.proxyHost:null,[]],proxyPort:[e?e.proxyPort:null,[]],proxyUser:[e?e.proxyUser:null,[]],proxyPassword:[e?e.proxyPassword:null,[]],username:[e?e.username:null,[]],password:[e?e.password:null,[]]})}validatorTriggers(){return["useSystemSmtpSettings","enableProxy"]}updateValidators(e){const t=this.sendEmailConfigForm.get("useSystemSmtpSettings").value,n=this.sendEmailConfigForm.get("enableProxy").value;t?(this.sendEmailConfigForm.get("smtpProtocol").setValidators([]),this.sendEmailConfigForm.get("smtpHost").setValidators([]),this.sendEmailConfigForm.get("smtpPort").setValidators([]),this.sendEmailConfigForm.get("timeout").setValidators([]),this.sendEmailConfigForm.get("proxyHost").setValidators([]),this.sendEmailConfigForm.get("proxyPort").setValidators([])):(this.sendEmailConfigForm.get("smtpProtocol").setValidators([O.required]),this.sendEmailConfigForm.get("smtpHost").setValidators([O.required]),this.sendEmailConfigForm.get("smtpPort").setValidators([O.required,O.min(1),O.max(65535)]),this.sendEmailConfigForm.get("timeout").setValidators([O.required,O.min(0)]),this.sendEmailConfigForm.get("proxyHost").setValidators(n?[O.required]:[]),this.sendEmailConfigForm.get("proxyPort").setValidators(n?[O.required,O.min(1),O.max(65535)]:[])),this.sendEmailConfigForm.get("smtpProtocol").updateValueAndValidity({emitEvent:e}),this.sendEmailConfigForm.get("smtpHost").updateValueAndValidity({emitEvent:e}),this.sendEmailConfigForm.get("smtpPort").updateValueAndValidity({emitEvent:e}),this.sendEmailConfigForm.get("timeout").updateValueAndValidity({emitEvent:e}),this.sendEmailConfigForm.get("proxyHost").updateValueAndValidity({emitEvent:e}),this.sendEmailConfigForm.get("proxyPort").updateValueAndValidity({emitEvent:e})}}e("SendEmailConfigComponent",pr),pr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:pr,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),pr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:pr,selector:"tb-external-node-send-email-config",usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.use-system-smtp-settings\' | translate }}\n \n
\n \n tb.rulenode.smtp-protocol\n \n \n {{ smtpProtocol.toUpperCase() }}\n \n \n \n
\n \n tb.rulenode.smtp-host\n \n \n {{ \'tb.rulenode.smtp-host-required\' | translate }}\n \n \n \n tb.rulenode.smtp-port\n \n \n {{ \'tb.rulenode.smtp-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.smtp-port-range\' | translate }}\n \n \n {{ \'tb.rulenode.smtp-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.timeout-msec\n \n \n {{ \'tb.rulenode.timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-timeout-msec-message\' | translate }}\n \n \n \n {{ \'tb.rulenode.enable-tls\' | translate }}\n \n \n tb.rulenode.tls-version\n \n \n {{ tlsVersion }}\n \n \n \n \n {{ \'tb.rulenode.enable-proxy\' | translate }}\n \n
\n
\n \n tb.rulenode.proxy-host\n \n \n {{ \'tb.rulenode.proxy-host-required\' | translate }}\n \n \n \n tb.rulenode.proxy-port\n \n \n {{ \'tb.rulenode.proxy-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.proxy-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.proxy-user\n \n \n \n tb.rulenode.proxy-password\n \n \n
\n \n tb.rulenode.username\n \n \n \n tb.rulenode.password\n \n \n \n
\n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:rt.TbCheckboxComponent,selector:"tb-checkbox",inputs:["disabled","trueValue","falseValue"],outputs:["valueChange"]},{kind:"component",type:Q.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Y.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:We.TogglePasswordComponent,selector:"tb-toggle-password"},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:pr,decorators:[{type:n,args:[{selector:"tb-external-node-send-email-config",template:'
\n \n {{ \'tb.rulenode.use-system-smtp-settings\' | translate }}\n \n
\n \n tb.rulenode.smtp-protocol\n \n \n {{ smtpProtocol.toUpperCase() }}\n \n \n \n
\n \n tb.rulenode.smtp-host\n \n \n {{ \'tb.rulenode.smtp-host-required\' | translate }}\n \n \n \n tb.rulenode.smtp-port\n \n \n {{ \'tb.rulenode.smtp-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.smtp-port-range\' | translate }}\n \n \n {{ \'tb.rulenode.smtp-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.timeout-msec\n \n \n {{ \'tb.rulenode.timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-timeout-msec-message\' | translate }}\n \n \n \n {{ \'tb.rulenode.enable-tls\' | translate }}\n \n \n tb.rulenode.tls-version\n \n \n {{ tlsVersion }}\n \n \n \n \n {{ \'tb.rulenode.enable-proxy\' | translate }}\n \n
\n
\n \n tb.rulenode.proxy-host\n \n \n {{ \'tb.rulenode.proxy-host-required\' | translate }}\n \n \n \n tb.rulenode.proxy-port\n \n \n {{ \'tb.rulenode.proxy-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.proxy-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.proxy-user\n \n \n \n tb.rulenode.proxy-password\n \n \n
\n \n tb.rulenode.username\n \n \n \n tb.rulenode.password\n \n \n \n
\n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class dr extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.sendSmsConfigForm}onConfigurationSet(e){this.sendSmsConfigForm=this.fb.group({numbersToTemplate:[e?e.numbersToTemplate:null,[O.required]],smsMessageTemplate:[e?e.smsMessageTemplate:null,[O.required]],useSystemSmsSettings:[!!e&&e.useSystemSmsSettings,[]],smsProviderConfiguration:[e?e.smsProviderConfiguration:null,[]]})}validatorTriggers(){return["useSystemSmsSettings"]}updateValidators(e){this.sendSmsConfigForm.get("useSystemSmsSettings").value?this.sendSmsConfigForm.get("smsProviderConfiguration").setValidators([]):this.sendSmsConfigForm.get("smsProviderConfiguration").setValidators([O.required]),this.sendSmsConfigForm.get("smsProviderConfiguration").updateValueAndValidity({emitEvent:e})}}e("SendSmsConfigComponent",dr),dr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:dr,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),dr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:dr,selector:"tb-external-node-send-sms-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.numbers-to-template\n \n \n {{ \'tb.rulenode.numbers-to-template-required\' | translate }}\n \n \n \n \n tb.rulenode.sms-message-template\n \n \n {{ \'tb.rulenode.sms-message-template-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n {{ \'tb.rulenode.use-system-sms-settings\' | translate }}\n \n \n \n
\n',dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Q.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:ot.SmsProviderConfigurationComponent,selector:"tb-sms-provider-configuration",inputs:["required","disabled"]},{kind:"pipe",type:he.SafePipe,name:"safe"},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:dr,decorators:[{type:n,args:[{selector:"tb-external-node-send-sms-config",template:'
\n \n tb.rulenode.numbers-to-template\n \n \n {{ \'tb.rulenode.numbers-to-template-required\' | translate }}\n \n \n \n \n tb.rulenode.sms-message-template\n \n \n {{ \'tb.rulenode.sms-message-template-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n {{ \'tb.rulenode.use-system-sms-settings\' | translate }}\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class ur extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.slackChanelTypes=Object.keys(w),this.slackChanelTypesTranslateMap=V}configForm(){return this.slackConfigForm}onConfigurationSet(e){this.slackConfigForm=this.fb.group({botToken:[e?e.botToken:null],useSystemSettings:[!!e&&e.useSystemSettings],messageTemplate:[e?e.messageTemplate:null,[O.required]],conversationType:[e?e.conversationType:null,[O.required]],conversation:[e?e.conversation:null,[O.required]]})}validatorTriggers(){return["useSystemSettings"]}updateValidators(e){this.slackConfigForm.get("useSystemSettings").value?this.slackConfigForm.get("botToken").clearValidators():this.slackConfigForm.get("botToken").setValidators([O.required]),this.slackConfigForm.get("botToken").updateValueAndValidity({emitEvent:e})}}e("SlackConfigComponent",ur),ur.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ur,deps:[{token:P.Store},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),ur.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:ur,selector:"tb-external-node-slack-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.message-template\n \n \n {{ \'tb.rulenode.message-template-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n {{ \'tb.rulenode.use-system-slack-settings\' | translate }}\n \n \n tb.rulenode.slack-api-token\n \n \n {{ \'tb.rulenode.slack-api-token-required\' | translate }}\n \n \n \n \n \n {{ slackChanelTypesTranslateMap.get(slackChanelType) | translate }}\n \n \n \n \n
\n',styles:[":host .tb-title{display:block;padding-bottom:6px}:host ::ng-deep .mat-mdc-radio-group{display:flex;flex-direction:row;margin-bottom:22px;gap:12px}:host ::ng-deep .mat-mdc-radio-group .mat-mdc-radio-button{flex:1 1 100%;padding:4px;border:1px solid rgba(0,0,0,.12);border-radius:6px}@media screen and (max-width: 599px){:host ::ng-deep .mat-mdc-radio-group{flex-direction:column}}\n"],dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Q.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:at.MatRadioGroup,selector:"mat-radio-group",exportAs:["matRadioGroup"]},{kind:"component",type:at.MatRadioButton,selector:"mat-radio-button",inputs:["disableRipple","tabIndex"],exportAs:["matRadioButton"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:it.SlackConversationAutocompleteComponent,selector:"tb-slack-conversation-autocomplete",inputs:["labelText","requiredText","required","disabled","slackChanelType","token"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ur,decorators:[{type:n,args:[{selector:"tb-external-node-slack-config",template:'
\n \n tb.rulenode.message-template\n \n \n {{ \'tb.rulenode.message-template-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n {{ \'tb.rulenode.use-system-slack-settings\' | translate }}\n \n \n tb.rulenode.slack-api-token\n \n \n {{ \'tb.rulenode.slack-api-token-required\' | translate }}\n \n \n \n \n \n {{ slackChanelTypesTranslateMap.get(slackChanelType) | translate }}\n \n \n \n \n
\n',styles:[":host .tb-title{display:block;padding-bottom:6px}:host ::ng-deep .mat-mdc-radio-group{display:flex;flex-direction:row;margin-bottom:22px;gap:12px}:host ::ng-deep .mat-mdc-radio-group .mat-mdc-radio-button{flex:1 1 100%;padding:4px;border:1px solid rgba(0,0,0,.12);border-radius:6px}@media screen and (max-width: 599px){:host ::ng-deep .mat-mdc-radio-group{flex-direction:column}}\n"]}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder}]}});class cr extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.snsConfigForm}onConfigurationSet(e){this.snsConfigForm=this.fb.group({topicArnPattern:[e?e.topicArnPattern:null,[O.required]],accessKeyId:[e?e.accessKeyId:null,[O.required]],secretAccessKey:[e?e.secretAccessKey:null,[O.required]],region:[e?e.region:null,[O.required]]})}}e("SnsConfigComponent",cr),cr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:cr,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),cr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:cr,selector:"tb-external-node-sns-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.topic-arn-pattern\n \n \n {{ \'tb.rulenode.topic-arn-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.aws-access-key-id\n \n \n {{ \'tb.rulenode.aws-access-key-id-required\' | translate }}\n \n \n \n tb.rulenode.aws-secret-access-key\n \n \n {{ \'tb.rulenode.aws-secret-access-key-required\' | translate }}\n \n \n \n tb.rulenode.aws-region\n \n \n {{ \'tb.rulenode.aws-region-required\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:cr,decorators:[{type:n,args:[{selector:"tb-external-node-sns-config",template:'
\n \n tb.rulenode.topic-arn-pattern\n \n \n {{ \'tb.rulenode.topic-arn-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.aws-access-key-id\n \n \n {{ \'tb.rulenode.aws-access-key-id-required\' | translate }}\n \n \n \n tb.rulenode.aws-secret-access-key\n \n \n {{ \'tb.rulenode.aws-secret-access-key-required\' | translate }}\n \n \n \n tb.rulenode.aws-region\n \n \n {{ \'tb.rulenode.aws-region-required\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class fr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.sqsQueueType=Bt,this.sqsQueueTypes=Object.keys(Bt),this.sqsQueueTypeTranslationsMap=Kt}configForm(){return this.sqsConfigForm}onConfigurationSet(e){this.sqsConfigForm=this.fb.group({queueType:[e?e.queueType:null,[O.required]],queueUrlPattern:[e?e.queueUrlPattern:null,[O.required]],delaySeconds:[e?e.delaySeconds:null,[O.min(0),O.max(900)]],messageAttributes:[e?e.messageAttributes:null,[]],accessKeyId:[e?e.accessKeyId:null,[O.required]],secretAccessKey:[e?e.secretAccessKey:null,[O.required]],region:[e?e.region:null,[O.required]]})}}e("SqsConfigComponent",fr),fr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:fr,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),fr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:fr,selector:"tb-external-node-sqs-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.queue-type\n \n \n {{ sqsQueueTypeTranslationsMap.get(type) | translate }}\n \n \n \n \n tb.rulenode.queue-url-pattern\n \n \n {{ \'tb.rulenode.queue-url-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.delay-seconds\n \n \n {{ \'tb.rulenode.min-delay-seconds-message\' | translate }}\n \n \n {{ \'tb.rulenode.max-delay-seconds-message\' | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.aws-access-key-id\n \n \n {{ \'tb.rulenode.aws-access-key-id-required\' | translate }}\n \n \n \n tb.rulenode.aws-secret-access-key\n \n \n {{ \'tb.rulenode.aws-secret-access-key-required\' | translate }}\n \n \n \n tb.rulenode.aws-region\n \n \n {{ \'tb.rulenode.aws-region-required\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:hn,selector:"tb-kv-map-config-old",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:he.SafePipe,name:"safe"},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:fr,decorators:[{type:n,args:[{selector:"tb-external-node-sqs-config",template:'
\n \n tb.rulenode.queue-type\n \n \n {{ sqsQueueTypeTranslationsMap.get(type) | translate }}\n \n \n \n \n tb.rulenode.queue-url-pattern\n \n \n {{ \'tb.rulenode.queue-url-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.delay-seconds\n \n \n {{ \'tb.rulenode.min-delay-seconds-message\' | translate }}\n \n \n {{ \'tb.rulenode.max-delay-seconds-message\' | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.aws-access-key-id\n \n \n {{ \'tb.rulenode.aws-access-key-id-required\' | translate }}\n \n \n \n tb.rulenode.aws-secret-access-key\n \n \n {{ \'tb.rulenode.aws-secret-access-key-required\' | translate }}\n \n \n \n tb.rulenode.aws-region\n \n \n {{ \'tb.rulenode.aws-region-required\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class gr{}e("RulenodeCoreConfigExternalModule",gr),gr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:gr,deps:[],target:t.ɵɵFactoryTarget.NgModule}),gr.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.10",ngImport:t,type:gr,declarations:[cr,fr,lr,or,ar,ir,sr,mr,pr,rr,dr,ur],imports:[$,M,Re,Un],exports:[cr,fr,lr,or,ar,ir,sr,mr,pr,rr,dr,ur]}),gr.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:gr,imports:[$,M,Re,Un]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:gr,decorators:[{type:c,args:[{declarations:[cr,fr,lr,or,ar,ir,sr,mr,pr,rr,dr,ur],imports:[$,M,Re,Un],exports:[cr,fr,lr,or,ar,ir,sr,mr,pr,rr,dr,ur]}]}]});class yr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.searchText=""}configForm(){return this.alarmStatusConfigForm}prepareInputConfig(e){return{alarmStatusList:ie(e?.alarmStatusList)?e.alarmStatusList:null}}onConfigurationSet(e){this.alarmStatusConfigForm=this.fb.group({alarmStatusList:[e.alarmStatusList,[O.required]]})}}e("CheckAlarmStatusComponent",yr),yr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:yr,deps:[{token:P.Store},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),yr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:yr,selector:"tb-filter-node-check-alarm-status-config",usesInheritance:!0,ngImport:t,template:'
\n
\n
tb.rulenode.alarm-status
\n
\n tb.rulenode.alarm-required\n
\n
\n \n
\n\n\n\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:zn,selector:"tb-alarm-status-select"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:yr,decorators:[{type:n,args:[{selector:"tb-filter-node-check-alarm-status-config",template:'
\n
\n
tb.rulenode.alarm-status
\n
\n tb.rulenode.alarm-required\n
\n
\n \n
\n\n\n\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder}]}});class xr extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.checkMessageConfigForm}prepareInputConfig(e){return{messageNames:ie(e?.messageNames)?e.messageNames:[],metadataNames:ie(e?.metadataNames)?e.metadataNames:[],checkAllKeys:!!ie(e?.checkAllKeys)&&e.checkAllKeys}}prepareOutputConfig(e){return{messageNames:ie(e?.messageNames)?e.messageNames:[],metadataNames:ie(e?.metadataNames)?e.metadataNames:[],checkAllKeys:e.checkAllKeys}}atLeastOne(e,t=null){return n=>{t||(t=Object.keys(n.controls));return n?.controls&&t.some((t=>!e(n.controls[t])))?null:{atLeastOne:!0}}}onConfigurationSet(e){this.checkMessageConfigForm=this.fb.group({messageNames:[e.messageNames,[]],metadataNames:[e.metadataNames,[]],checkAllKeys:[e.checkAllKeys,[]]},{validators:this.atLeastOne(O.required,["messageNames","metadataNames"])})}get touchedValidationControl(){return["messageNames","metadataNames"].some((e=>this.checkMessageConfigForm.get(e).touched))}}e("CheckMessageConfigComponent",xr),xr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:xr,deps:[{token:P.Store},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),xr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:xr,selector:"tb-filter-node-check-message-config",usesInheritance:!0,ngImport:t,template:'
\n
\n
tb.rulenode.fields-to-check
\n
\n tb.rulenode.at-least-one-field-required\n
\n
\n \n help\n \n \n help\n \n
\n \n {{ \'tb.rulenode.check-all-keys\' | translate }}\n \n
\n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"component",type:Ze.StringItemsListComponent,selector:"tb-string-items-list",inputs:["required","disabled","label","placeholder","hint","requiredText","floatLabel","appearance","editable","subscriptSizing","predefinedValues"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:Y.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:te.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:ne.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:xr,decorators:[{type:n,args:[{selector:"tb-filter-node-check-message-config",template:'
\n
\n
tb.rulenode.fields-to-check
\n
\n tb.rulenode.at-least-one-field-required\n
\n
\n \n help\n \n \n help\n \n
\n \n {{ \'tb.rulenode.check-all-keys\' | translate }}\n \n
\n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder}]}});class br extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.entitySearchDirection=Object.values(v),this.entitySearchDirectionTranslationsMap=C}configForm(){return this.checkRelationConfigForm}prepareInputConfig(e){return{checkForSingleEntity:!!ie(e?.checkForSingleEntity)&&e.checkForSingleEntity,direction:ie(e?.direction)?e.direction:null,entityType:ie(e?.entityType)?e.entityType:null,entityId:ie(e?.entityId)?e.entityId:null,relationType:ie(e?.relationType)?e.relationType:null}}onConfigurationSet(e){this.checkRelationConfigForm=this.fb.group({checkForSingleEntity:[e.checkForSingleEntity,[]],direction:[e.direction,[]],entityType:[e.entityType,e&&e.checkForSingleEntity?[O.required]:[]],entityId:[e.entityId,e&&e.checkForSingleEntity?[O.required]:[]],relationType:[e.relationType,[O.required]]})}validatorTriggers(){return["checkForSingleEntity"]}updateValidators(e){const t=this.checkRelationConfigForm.get("checkForSingleEntity").value;this.checkRelationConfigForm.get("entityType").setValidators(t?[O.required]:[]),this.checkRelationConfigForm.get("entityType").updateValueAndValidity({emitEvent:e}),this.checkRelationConfigForm.get("entityId").setValidators(t?[O.required]:[]),this.checkRelationConfigForm.get("entityId").updateValueAndValidity({emitEvent:e})}}e("CheckRelationConfigComponent",br),br.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:br,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),br.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:br,selector:"tb-filter-node-check-relation-config",usesInheritance:!0,ngImport:t,template:'
\n
tb.rulenode.relation-search-parameters
\n
\n \n {{ \'relation.direction\' | translate }}\n \n \n {{ entitySearchDirectionTranslationsMap.get(direction) | translate }} tb.rulenode.relations-query-config-direction-suffix\n \n \n \n \n \n
\n \n {{ \'tb.rulenode.check-relation-to-specific-entity\' | translate }}\n \n
\n
\n \n \n \n \n
\n
\n
\n',styles:[":host .slide-toggle{margin-bottom:18px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:lt.EntityAutocompleteComponent,selector:"tb-entity-autocomplete",inputs:["entityType","entitySubtype","excludeEntityIds","labelText","requiredText","useFullEntityId","appearance","required","disabled"],outputs:["entityChanged"]},{kind:"component",type:ve.EntityTypeSelectComponent,selector:"tb-entity-type-select",inputs:["allowedEntityTypes","useAliasEntityTypes","filterAllowedEntityTypes","showLabel","required","disabled"]},{kind:"component",type:$e.RelationTypeAutocompleteComponent,selector:"tb-relation-type-autocomplete",inputs:["showLabel","additionalClasses","appearance","required","disabled","subscriptSizing"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:te.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:ne.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:br,decorators:[{type:n,args:[{selector:"tb-filter-node-check-relation-config",template:'
\n
tb.rulenode.relation-search-parameters
\n
\n \n {{ \'relation.direction\' | translate }}\n \n \n {{ entitySearchDirectionTranslationsMap.get(direction) | translate }} tb.rulenode.relations-query-config-direction-suffix\n \n \n \n \n \n
\n \n {{ \'tb.rulenode.check-relation-to-specific-entity\' | translate }}\n \n
\n
\n \n \n \n \n
\n
\n
\n',styles:[":host .slide-toggle{margin-bottom:18px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class hr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.perimeterType=Tt,this.perimeterTypes=Object.values(Tt),this.perimeterTypeTranslationMap=It,this.rangeUnits=Object.values(qt),this.rangeUnitTranslationMap=At,this.defaultPaddingEnable=!0}configForm(){return this.geoFilterConfigForm}prepareInputConfig(e){return{latitudeKeyName:ie(e?.latitudeKeyName)?e.latitudeKeyName:null,longitudeKeyName:ie(e?.longitudeKeyName)?e.longitudeKeyName:null,perimeterType:ie(e?.perimeterType)?e.perimeterType:null,fetchPerimeterInfoFromMessageMetadata:!!ie(e?.fetchPerimeterInfoFromMessageMetadata)&&e.fetchPerimeterInfoFromMessageMetadata,perimeterKeyName:ie(e?.perimeterKeyName)?e.perimeterKeyName:null,centerLatitude:ie(e?.centerLatitude)?e.centerLatitude:null,centerLongitude:ie(e?.centerLongitude)?e.centerLongitude:null,range:ie(e?.range)?e.range:null,rangeUnit:ie(e?.rangeUnit)?e.rangeUnit:null,polygonsDefinition:ie(e?.polygonsDefinition)?e.polygonsDefinition:null}}onConfigurationSet(e){this.geoFilterConfigForm=this.fb.group({latitudeKeyName:[e.latitudeKeyName,[O.required]],longitudeKeyName:[e.longitudeKeyName,[O.required]],perimeterType:[e.perimeterType,[O.required]],fetchPerimeterInfoFromMessageMetadata:[e.fetchPerimeterInfoFromMessageMetadata,[]],perimeterKeyName:[e.perimeterKeyName,[]],centerLatitude:[e.centerLatitude,[]],centerLongitude:[e.centerLongitude,[]],range:[e.range,[]],rangeUnit:[e.rangeUnit,[]],polygonsDefinition:[e.polygonsDefinition,[]]})}validatorTriggers(){return["fetchPerimeterInfoFromMessageMetadata","perimeterType"]}updateValidators(e){const t=this.geoFilterConfigForm.get("fetchPerimeterInfoFromMessageMetadata").value,n=this.geoFilterConfigForm.get("perimeterType").value;t?this.geoFilterConfigForm.get("perimeterKeyName").setValidators([O.required]):this.geoFilterConfigForm.get("perimeterKeyName").setValidators([]),t||n!==Tt.CIRCLE?(this.geoFilterConfigForm.get("centerLatitude").setValidators([]),this.geoFilterConfigForm.get("centerLongitude").setValidators([]),this.geoFilterConfigForm.get("range").setValidators([]),this.geoFilterConfigForm.get("rangeUnit").setValidators([]),this.defaultPaddingEnable=!0):(this.geoFilterConfigForm.get("centerLatitude").setValidators([O.required,O.min(-90),O.max(90)]),this.geoFilterConfigForm.get("centerLongitude").setValidators([O.required,O.min(-180),O.max(180)]),this.geoFilterConfigForm.get("range").setValidators([O.required,O.min(0)]),this.geoFilterConfigForm.get("rangeUnit").setValidators([O.required]),this.defaultPaddingEnable=!1),t||n!==Tt.POLYGON?this.geoFilterConfigForm.get("polygonsDefinition").setValidators([]):this.geoFilterConfigForm.get("polygonsDefinition").setValidators([O.required]),this.geoFilterConfigForm.get("perimeterKeyName").updateValueAndValidity({emitEvent:e}),this.geoFilterConfigForm.get("centerLatitude").updateValueAndValidity({emitEvent:e}),this.geoFilterConfigForm.get("centerLongitude").updateValueAndValidity({emitEvent:e}),this.geoFilterConfigForm.get("range").updateValueAndValidity({emitEvent:e}),this.geoFilterConfigForm.get("rangeUnit").updateValueAndValidity({emitEvent:e}),this.geoFilterConfigForm.get("polygonsDefinition").updateValueAndValidity({emitEvent:e})}}e("GpsGeoFilterConfigComponent",hr),hr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:hr,deps:[{token:P.Store},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),hr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:hr,selector:"tb-filter-node-gps-geofencing-config",usesInheritance:!0,ngImport:t,template:'
\n
\n
tb.rulenode.coordinate-field-names
\n
\n
\n \n {{ \'tb.rulenode.latitude-field-name\' | translate }}\n \n \n {{ \'tb.rulenode.latitude-field-name-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.longitude-field-name\' | translate }}\n \n \n {{ \'tb.rulenode.longitude-field-name-required\' | translate }}\n \n \n
\n
tb.rulenode.coordinate-field-hint
\n
\n
\n
\n
tb.rulenode.geofence-configuration
\n
\n \n {{ \'tb.rulenode.perimeter-type\' | translate }}\n \n \n {{ perimeterTypeTranslationMap.get(type) | translate }}\n \n \n \n
\n \n {{ \'tb.rulenode.fetch-perimeter-info-from-metadata\' | translate }}\n \n
\n \n {{ \'tb.rulenode.perimeter-key-name\' | translate }}\n \n \n {{ \'tb.rulenode.perimeter-key-name-required\' | translate }}\n \n {{ \'tb.rulenode.perimeter-key-name-hint\' | translate }}\n \n
\n
\n \n {{ \'tb.rulenode.circle-center-latitude\' | translate }}\n \n \n {{ \'tb.rulenode.circle-center-latitude-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.circle-center-longitude\' | translate }}\n \n \n {{ \'tb.rulenode.circle-center-longitude-required\' | translate }}\n \n \n
\n
\n \n {{ \'tb.rulenode.range\' | translate }}\n \n \n {{ \'tb.rulenode.range-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.range-units\' | translate }}\n \n \n {{ rangeUnitTranslationMap.get(type) | translate }}\n \n \n \n {{ \'tb.rulenode.range-units-required\' | translate }}\n \n \n
\n
\n \n {{ \'tb.rulenode.polygon-definition\' | translate }}\n \n {{ \'tb.rulenode.polygon-definition-hint\' | translate }}\n \n {{ \'tb.rulenode.polygon-definition-required\' | translate }}\n \n \n
\n
\n
\n',styles:[":host .slide-toggle{margin-bottom:18px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:te.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:ne.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:hr,decorators:[{type:n,args:[{selector:"tb-filter-node-gps-geofencing-config",template:'
\n
\n
tb.rulenode.coordinate-field-names
\n
\n
\n \n {{ \'tb.rulenode.latitude-field-name\' | translate }}\n \n \n {{ \'tb.rulenode.latitude-field-name-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.longitude-field-name\' | translate }}\n \n \n {{ \'tb.rulenode.longitude-field-name-required\' | translate }}\n \n \n
\n
tb.rulenode.coordinate-field-hint
\n
\n
\n
\n
tb.rulenode.geofence-configuration
\n
\n \n {{ \'tb.rulenode.perimeter-type\' | translate }}\n \n \n {{ perimeterTypeTranslationMap.get(type) | translate }}\n \n \n \n
\n \n {{ \'tb.rulenode.fetch-perimeter-info-from-metadata\' | translate }}\n \n
\n \n {{ \'tb.rulenode.perimeter-key-name\' | translate }}\n \n \n {{ \'tb.rulenode.perimeter-key-name-required\' | translate }}\n \n {{ \'tb.rulenode.perimeter-key-name-hint\' | translate }}\n \n
\n
\n \n {{ \'tb.rulenode.circle-center-latitude\' | translate }}\n \n \n {{ \'tb.rulenode.circle-center-latitude-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.circle-center-longitude\' | translate }}\n \n \n {{ \'tb.rulenode.circle-center-longitude-required\' | translate }}\n \n \n
\n
\n \n {{ \'tb.rulenode.range\' | translate }}\n \n \n {{ \'tb.rulenode.range-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.range-units\' | translate }}\n \n \n {{ rangeUnitTranslationMap.get(type) | translate }}\n \n \n \n {{ \'tb.rulenode.range-units-required\' | translate }}\n \n \n
\n
\n \n {{ \'tb.rulenode.polygon-definition\' | translate }}\n \n {{ \'tb.rulenode.polygon-definition-hint\' | translate }}\n \n {{ \'tb.rulenode.polygon-definition-required\' | translate }}\n \n \n
\n
\n
\n',styles:[":host .slide-toggle{margin-bottom:18px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder}]}});class vr extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.messageTypeConfigForm}prepareInputConfig(e){return{messageTypes:ie(e?.messageTypes)?e.messageTypes:null}}onConfigurationSet(e){this.messageTypeConfigForm=this.fb.group({messageTypes:[e.messageTypes,[O.required]]})}}e("MessageTypeConfigComponent",vr),vr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:vr,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),vr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:vr,selector:"tb-filter-node-message-type-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n
\n',dependencies:[{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:Mn,selector:"tb-message-types-config",inputs:["required","label","placeholder","disabled"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:vr,decorators:[{type:n,args:[{selector:"tb-filter-node-message-type-config",template:'
\n \n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class Cr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.allowedEntityTypes=[F.DEVICE,F.ASSET,F.ENTITY_VIEW,F.TENANT,F.CUSTOMER,F.USER,F.DASHBOARD,F.RULE_CHAIN,F.RULE_NODE]}configForm(){return this.originatorTypeConfigForm}prepareInputConfig(e){return{originatorTypes:ie(e?.originatorTypes)?e.originatorTypes:null}}onConfigurationSet(e){this.originatorTypeConfigForm=this.fb.group({originatorTypes:[e.originatorTypes,[O.required]]})}}e("OriginatorTypeConfigComponent",Cr),Cr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Cr,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Cr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Cr,selector:"tb-filter-node-originator-type-config",usesInheritance:!0,ngImport:t,template:'
\n \n help\n \n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"component",type:st.EntityTypeListComponent,selector:"tb-entity-type-list",inputs:["required","additionalClasses","appearance","label","floatLabel","disabled","subscriptSizing","allowedEntityTypes","emptyInputPlaceholder","filledInputPlaceholder","ignoreAuthorityFilter"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:Y.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Cr,decorators:[{type:n,args:[{selector:"tb-filter-node-originator-type-config",template:'
\n \n help\n \n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class Fr extends f{constructor(e,t,n,o){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=n,this.translate=o,this.tbelEnabled=re(this.store).tbelEnabled,this.scriptLanguage=x,this.changeScript=new r,this.hasScript=!0,this.testScriptLabel="tb.rulenode.test-filter-function"}configForm(){return this.scriptConfigForm}onConfigurationSet(e){this.scriptConfigForm=this.fb.group({scriptLang:[e.scriptLang,[O.required]],jsScript:[e.jsScript,[]],tbelScript:[e.tbelScript,[]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.scriptConfigForm.get("scriptLang").value;t!==x.TBEL||this.tbelEnabled||(t=x.JS,this.scriptConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.scriptConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.scriptConfigForm.get("jsScript").setValidators(t===x.JS?[O.required]:[]),this.scriptConfigForm.get("jsScript").updateValueAndValidity({emitEvent:e}),this.scriptConfigForm.get("tbelScript").setValidators(t===x.TBEL?[O.required]:[]),this.scriptConfigForm.get("tbelScript").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=x.JS)),{scriptLang:ie(e?.scriptLang)?e.scriptLang:x.JS,jsScript:ie(e?.jsScript)?e.jsScript:null,tbelScript:ie(e?.tbelScript)?e.tbelScript:null}}testScript(e){const t=this.scriptConfigForm.get("scriptLang").value,n=t===x.JS?"jsScript":"tbelScript",r=t===x.JS?"rulenode/filter_node_script_fn":"rulenode/tbel/filter_node_script_fn",o=this.scriptConfigForm.get(n).value;this.nodeScriptTestService.testNodeScript(o,"filter",this.translate.instant("tb.rulenode.filter"),"Filter",["msg","metadata","msgType"],this.ruleNodeId,r,t,e).subscribe((e=>{e&&(this.scriptConfigForm.get(n).setValue(e),this.changeScript.emit())}))}onValidate(){this.scriptConfigForm.get("scriptLang").value===x.JS&&this.jsFuncComponent.validateOnSubmit()}}e("ScriptConfigComponent",Fr),Fr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Fr,deps:[{token:P.Store},{token:R.UntypedFormBuilder},{token:oe.NodeScriptTestService},{token:Z.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Fr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Fr,selector:"tb-filter-node-script-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n \n \n \n
\n',dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:pe.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:de.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:de.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:fe.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Fr,decorators:[{type:n,args:[{selector:"tb-filter-node-script-config",template:'
\n \n \n \n \n \n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder},{type:oe.NodeScriptTestService},{type:Z.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}});class kr extends f{constructor(e,t,n,o){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=n,this.translate=o,this.tbelEnabled=re(this.store).tbelEnabled,this.scriptLanguage=x,this.changeScript=new r,this.hasScript=!0,this.testScriptLabel="tb.rulenode.test-switch-function"}configForm(){return this.switchConfigForm}onConfigurationSet(e){this.switchConfigForm=this.fb.group({scriptLang:[e.scriptLang,[O.required]],jsScript:[e.jsScript,[]],tbelScript:[e.tbelScript,[]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.switchConfigForm.get("scriptLang").value;t!==x.TBEL||this.tbelEnabled||(t=x.JS,this.switchConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.switchConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.switchConfigForm.get("jsScript").setValidators(t===x.JS?[O.required]:[]),this.switchConfigForm.get("jsScript").updateValueAndValidity({emitEvent:e}),this.switchConfigForm.get("tbelScript").setValidators(t===x.TBEL?[O.required]:[]),this.switchConfigForm.get("tbelScript").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=x.JS)),{scriptLang:ie(e?.scriptLang)?e.scriptLang:x.JS,jsScript:ie(e?.jsScript)?e.jsScript:null,tbelScript:ie(e?.tbelScript)?e.tbelScript:null}}testScript(e){const t=this.switchConfigForm.get("scriptLang").value,n=t===x.JS?"jsScript":"tbelScript",r=t===x.JS?"rulenode/switch_node_script_fn":"rulenode/tbel/switch_node_script_fn",o=this.switchConfigForm.get(n).value;this.nodeScriptTestService.testNodeScript(o,"switch",this.translate.instant("tb.rulenode.switch"),"Switch",["msg","metadata","msgType"],this.ruleNodeId,r,t,e).subscribe((e=>{e&&(this.switchConfigForm.get(n).setValue(e),this.changeScript.emit())}))}onValidate(){this.switchConfigForm.get("scriptLang").value===x.JS&&this.jsFuncComponent.validateOnSubmit()}}e("SwitchConfigComponent",kr),kr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:kr,deps:[{token:P.Store},{token:R.UntypedFormBuilder},{token:oe.NodeScriptTestService},{token:Z.TranslateService}],target:t.ɵɵFactoryTarget.Component}),kr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:kr,selector:"tb-filter-node-switch-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n \n \n \n
\n',dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:pe.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:de.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:de.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:fe.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:kr,decorators:[{type:n,args:[{selector:"tb-filter-node-switch-config",template:'
\n \n \n \n \n \n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder},{type:oe.NodeScriptTestService},{type:Z.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}});class Lr{}e("RuleNodeCoreConfigFilterModule",Lr),Lr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Lr,deps:[],target:t.ɵɵFactoryTarget.NgModule}),Lr.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.10",ngImport:t,type:Lr,declarations:[xr,br,hr,vr,Cr,Fr,kr,yr],imports:[$,M,Un],exports:[xr,br,hr,vr,Cr,Fr,kr,yr]}),Lr.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Lr,imports:[$,M,Un]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Lr,decorators:[{type:c,args:[{declarations:[xr,br,hr,vr,Cr,Fr,kr,yr],imports:[$,M,Un],exports:[xr,br,hr,vr,Cr,Fr,kr,yr]}]}]});class Tr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.originatorSource=vt,this.originatorSources=Object.keys(vt),this.originatorSourceTranslationMap=Ct,this.originatorSourceDescTranslationMap=Ft,this.allowedEntityTypes=[F.DEVICE,F.ASSET,F.ENTITY_VIEW,F.USER,F.EDGE]}configForm(){return this.changeOriginatorConfigForm}onConfigurationSet(e){this.changeOriginatorConfigForm=this.fb.group({originatorSource:[e?e.originatorSource:null,[O.required]],entityType:[e?e.entityType:null,[]],entityNamePattern:[e?e.entityNamePattern:null,[]],relationsQuery:[e?e.relationsQuery:null,[]]})}validatorTriggers(){return["originatorSource"]}updateValidators(e){const t=this.changeOriginatorConfigForm.get("originatorSource").value;t===vt.RELATED?this.changeOriginatorConfigForm.get("relationsQuery").setValidators([O.required]):this.changeOriginatorConfigForm.get("relationsQuery").setValidators([]),t===vt.ENTITY?(this.changeOriginatorConfigForm.get("entityType").setValidators([O.required]),this.changeOriginatorConfigForm.get("entityNamePattern").setValidators([O.required,O.pattern(/.*\S.*/)])):(this.changeOriginatorConfigForm.get("entityType").patchValue(null,{emitEvent:e}),this.changeOriginatorConfigForm.get("entityNamePattern").patchValue(null,{emitEvent:e}),this.changeOriginatorConfigForm.get("entityType").setValidators([]),this.changeOriginatorConfigForm.get("entityNamePattern").setValidators([])),this.changeOriginatorConfigForm.get("relationsQuery").updateValueAndValidity({emitEvent:e}),this.changeOriginatorConfigForm.get("entityType").updateValueAndValidity({emitEvent:e}),this.changeOriginatorConfigForm.get("entityNamePattern").updateValueAndValidity({emitEvent:e})}}e("ChangeOriginatorConfigComponent",Tr),Tr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Tr,deps:[{token:P.Store},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Tr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Tr,selector:"tb-transformation-node-change-originator-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.new-originator\n \n \n \n {{ originatorSourceTranslationMap.get(changeOriginatorConfigForm.get(\'originatorSource\').value) | translate }}\n \n \n \n \n {{ originatorSourceTranslationMap.get(source) | translate }}\n \n
\n \n {{ originatorSourceDescTranslationMap.get(source) | translate }}\n \n
\n
\n
\n
\n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n \n
\n
\n \n \n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ve.EntityTypeSelectComponent,selector:"tb-entity-type-select",inputs:["allowedEntityTypes","useAliasEntityTypes","filterAllowedEntityTypes","showLabel","required","disabled"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"directive",type:X.MatSelectTrigger,selector:"mat-select-trigger"},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:Ne.MatListItemTitle,selector:"[matListItemTitle]"},{kind:"directive",type:Ne.MatListItemMeta,selector:"[matListItemMeta]"},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:An,selector:"tb-relations-query-config",inputs:["disabled","required"]},{kind:"component",type:Nn,selector:"tb-example-hint",inputs:["hintText","popupHelpLink","textAlign"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Tr,decorators:[{type:n,args:[{selector:"tb-transformation-node-change-originator-config",template:'
\n \n tb.rulenode.new-originator\n \n \n \n {{ originatorSourceTranslationMap.get(changeOriginatorConfigForm.get(\'originatorSource\').value) | translate }}\n \n \n \n \n {{ originatorSourceTranslationMap.get(source) | translate }}\n \n
\n \n {{ originatorSourceDescTranslationMap.get(source) | translate }}\n \n
\n
\n
\n
\n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n \n
\n
\n \n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder}]}});class Ir extends f{constructor(e,t,n,o){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=n,this.translate=o,this.tbelEnabled=re(this.store).tbelEnabled,this.scriptLanguage=x,this.changeScript=new r,this.hasScript=!0,this.testScriptLabel="tb.rulenode.test-transformer-function"}configForm(){return this.scriptConfigForm}onConfigurationSet(e){this.scriptConfigForm=this.fb.group({scriptLang:[e?e.scriptLang:x.JS,[O.required]],jsScript:[e?e.jsScript:null,[O.required]],tbelScript:[e?e.tbelScript:null,[]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.scriptConfigForm.get("scriptLang").value;t!==x.TBEL||this.tbelEnabled||(t=x.JS,this.scriptConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.scriptConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.scriptConfigForm.get("jsScript").setValidators(t===x.JS?[O.required]:[]),this.scriptConfigForm.get("jsScript").updateValueAndValidity({emitEvent:e}),this.scriptConfigForm.get("tbelScript").setValidators(t===x.TBEL?[O.required]:[]),this.scriptConfigForm.get("tbelScript").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=x.JS)),e}testScript(e){const t=this.scriptConfigForm.get("scriptLang").value,n=t===x.JS?"jsScript":"tbelScript",r=t===x.JS?"rulenode/transformation_node_script_fn":"rulenode/tbel/transformation_node_script_fn",o=this.scriptConfigForm.get(n).value;this.nodeScriptTestService.testNodeScript(o,"update",this.translate.instant("tb.rulenode.transformer"),"Transform",["msg","metadata","msgType"],this.ruleNodeId,r,t,e).subscribe((e=>{e&&(this.scriptConfigForm.get(n).setValue(e),this.changeScript.emit())}))}onValidate(){this.scriptConfigForm.get("scriptLang").value===x.JS&&this.jsFuncComponent.validateOnSubmit()}}e("TransformScriptConfigComponent",Ir),Ir.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Ir,deps:[{token:P.Store},{token:R.FormBuilder},{token:oe.NodeScriptTestService},{token:Z.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Ir.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Ir,selector:"tb-transformation-node-script-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n \n \n
\n \n
\n
\n',dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:pe.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:de.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:de.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:fe.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Ir,decorators:[{type:n,args:[{selector:"tb-transformation-node-script-config",template:'
\n \n \n \n \n \n \n \n
\n \n
\n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder},{type:oe.NodeScriptTestService},{type:Z.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}}); + /** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.io/license + */ + const Nr=mt({passive:!0});class Sr{constructor(e,t){this._platform=e,this._ngZone=t,this._monitoredElements=new Map}monitor(e){if(!this._platform.isBrowser)return ze;const t=ke(e),n=this._monitoredElements.get(t);if(n)return n.subject;const r=new _e,o="cdk-text-field-autofilled",a=e=>{"cdk-text-field-autofill-start"!==e.animationName||t.classList.contains(o)?"cdk-text-field-autofill-end"===e.animationName&&t.classList.contains(o)&&(t.classList.remove(o),this._ngZone.run((()=>r.next({target:e.target,isAutofilled:!1})))):(t.classList.add(o),this._ngZone.run((()=>r.next({target:e.target,isAutofilled:!0}))))};return this._ngZone.runOutsideAngular((()=>{t.addEventListener("animationstart",a,Nr),t.classList.add("cdk-text-field-autofill-monitored")})),this._monitoredElements.set(t,{subject:r,unlisten:()=>{t.removeEventListener("animationstart",a,Nr)}}),r}stopMonitoring(e){const t=ke(e),n=this._monitoredElements.get(t);n&&(n.unlisten(),n.subject.complete(),t.classList.remove("cdk-text-field-autofill-monitored"),t.classList.remove("cdk-text-field-autofilled"),this._monitoredElements.delete(t))}ngOnDestroy(){this._monitoredElements.forEach(((e,t)=>this.stopMonitoring(t)))}}Sr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.0-rc.0",ngImport:t,type:Sr,deps:[{token:pt.Platform},{token:t.NgZone}],target:t.ɵɵFactoryTarget.Injectable}),Sr.ɵprov=t.ɵɵngDeclareInjectable({minVersion:"12.0.0",version:"15.2.0-rc.0",ngImport:t,type:Sr,providedIn:"root"}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.0-rc.0",ngImport:t,type:Sr,decorators:[{type:s,args:[{providedIn:"root"}]}],ctorParameters:function(){return[{type:pt.Platform},{type:t.NgZone}]}});class qr{constructor(e,t){this._elementRef=e,this._autofillMonitor=t,this.cdkAutofill=new r}ngOnInit(){this._autofillMonitor.monitor(this._elementRef).subscribe((e=>this.cdkAutofill.emit(e)))}ngOnDestroy(){this._autofillMonitor.stopMonitoring(this._elementRef)}}qr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.0-rc.0",ngImport:t,type:qr,deps:[{token:t.ElementRef},{token:Sr}],target:t.ɵɵFactoryTarget.Directive}),qr.ɵdir=t.ɵɵngDeclareDirective({minVersion:"14.0.0",version:"15.2.0-rc.0",type:qr,selector:"[cdkAutofill]",outputs:{cdkAutofill:"cdkAutofill"},ngImport:t}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.0-rc.0",ngImport:t,type:qr,decorators:[{type:d,args:[{selector:"[cdkAutofill]"}]}],ctorParameters:function(){return[{type:t.ElementRef},{type:Sr}]},propDecorators:{cdkAutofill:[{type:u}]}}); + /** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.io/license + */ + class Ar{get minRows(){return this._minRows}set minRows(e){this._minRows=Le(e),this._setMinHeight()}get maxRows(){return this._maxRows}set maxRows(e){this._maxRows=Le(e),this._setMaxHeight()}get enabled(){return this._enabled}set enabled(e){e=Fe(e),this._enabled!==e&&((this._enabled=e)?this.resizeToFitContent(!0):this.reset())}get placeholder(){return this._textareaElement.placeholder}set placeholder(e){this._cachedPlaceholderHeight=void 0,e?this._textareaElement.setAttribute("placeholder",e):this._textareaElement.removeAttribute("placeholder"),this._cacheTextareaPlaceholderHeight()}constructor(e,t,n,r){this._elementRef=e,this._platform=t,this._ngZone=n,this._destroyed=new _e,this._enabled=!0,this._previousMinRows=-1,this._isViewInited=!1,this._handleFocusEvent=e=>{this._hasFocus="focus"===e.type},this._document=r,this._textareaElement=this._elementRef.nativeElement}_setMinHeight(){const e=this.minRows&&this._cachedLineHeight?this.minRows*this._cachedLineHeight+"px":null;e&&(this._textareaElement.style.minHeight=e)}_setMaxHeight(){const e=this.maxRows&&this._cachedLineHeight?this.maxRows*this._cachedLineHeight+"px":null;e&&(this._textareaElement.style.maxHeight=e)}ngAfterViewInit(){this._platform.isBrowser&&(this._initialHeight=this._textareaElement.style.height,this.resizeToFitContent(),this._ngZone.runOutsideAngular((()=>{const e=this._getWindow();Ue(e,"resize").pipe(we(16),De(this._destroyed)).subscribe((()=>this.resizeToFitContent(!0))),this._textareaElement.addEventListener("focus",this._handleFocusEvent),this._textareaElement.addEventListener("blur",this._handleFocusEvent)})),this._isViewInited=!0,this.resizeToFitContent(!0))}ngOnDestroy(){this._textareaElement.removeEventListener("focus",this._handleFocusEvent),this._textareaElement.removeEventListener("blur",this._handleFocusEvent),this._destroyed.next(),this._destroyed.complete()}_cacheTextareaLineHeight(){if(this._cachedLineHeight)return;let e=this._textareaElement.cloneNode(!1);e.rows=1,e.style.position="absolute",e.style.visibility="hidden",e.style.border="none",e.style.padding="0",e.style.height="",e.style.minHeight="",e.style.maxHeight="",e.style.overflow="hidden",this._textareaElement.parentNode.appendChild(e),this._cachedLineHeight=e.clientHeight,e.remove(),this._setMinHeight(),this._setMaxHeight()}_measureScrollHeight(){const e=this._textareaElement,t=e.style.marginBottom||"",n=this._platform.FIREFOX,r=n&&this._hasFocus,o=n?"cdk-textarea-autosize-measuring-firefox":"cdk-textarea-autosize-measuring";r&&(e.style.marginBottom=`${e.clientHeight}px`),e.classList.add(o);const a=e.scrollHeight-4;return e.classList.remove(o),r&&(e.style.marginBottom=t),a}_cacheTextareaPlaceholderHeight(){if(!this._isViewInited||null!=this._cachedPlaceholderHeight)return;if(!this.placeholder)return void(this._cachedPlaceholderHeight=0);const e=this._textareaElement.value;this._textareaElement.value=this._textareaElement.placeholder,this._cachedPlaceholderHeight=this._measureScrollHeight(),this._textareaElement.value=e}ngDoCheck(){this._platform.isBrowser&&this.resizeToFitContent()}resizeToFitContent(e=!1){if(!this._enabled)return;if(this._cacheTextareaLineHeight(),this._cacheTextareaPlaceholderHeight(),!this._cachedLineHeight)return;const t=this._elementRef.nativeElement,n=t.value;if(!e&&this._minRows===this._previousMinRows&&n===this._previousValue)return;const r=this._measureScrollHeight(),o=Math.max(r,this._cachedPlaceholderHeight||0);t.style.height=`${o}px`,this._ngZone.runOutsideAngular((()=>{"undefined"!=typeof requestAnimationFrame?requestAnimationFrame((()=>this._scrollToCaretPosition(t))):setTimeout((()=>this._scrollToCaretPosition(t)))})),this._previousValue=n,this._previousMinRows=this._minRows}reset(){void 0!==this._initialHeight&&(this._textareaElement.style.height=this._initialHeight)}_noopInputHandler(){}_getDocument(){return this._document||document}_getWindow(){return this._getDocument().defaultView||window}_scrollToCaretPosition(e){const{selectionStart:t,selectionEnd:n}=e;!this._destroyed.isStopped&&this._hasFocus&&e.setSelectionRange(t,n)}}Ar.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.0-rc.0",ngImport:t,type:Ar,deps:[{token:t.ElementRef},{token:pt.Platform},{token:t.NgZone},{token:j,optional:!0}],target:t.ɵɵFactoryTarget.Directive}),Ar.ɵdir=t.ɵɵngDeclareDirective({minVersion:"14.0.0",version:"15.2.0-rc.0",type:Ar,selector:"textarea[cdkTextareaAutosize]",inputs:{minRows:["cdkAutosizeMinRows","minRows"],maxRows:["cdkAutosizeMaxRows","maxRows"],enabled:["cdkTextareaAutosize","enabled"],placeholder:"placeholder"},host:{attributes:{rows:"1"},listeners:{input:"_noopInputHandler()"},classAttribute:"cdk-textarea-autosize"},exportAs:["cdkTextareaAutosize"],ngImport:t}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.0-rc.0",ngImport:t,type:Ar,decorators:[{type:d,args:[{selector:"textarea[cdkTextareaAutosize]",exportAs:"cdkTextareaAutosize",host:{class:"cdk-textarea-autosize",rows:"1","(input)":"_noopInputHandler()"}}]}],ctorParameters:function(){return[{type:t.ElementRef},{type:pt.Platform},{type:t.NgZone},{type:void 0,decorators:[{type:p},{type:m,args:[j]}]}]},propDecorators:{minRows:[{type:i,args:["cdkAutosizeMinRows"]}],maxRows:[{type:i,args:["cdkAutosizeMaxRows"]}],enabled:[{type:i,args:["cdkTextareaAutosize"]}],placeholder:[{type:i}]}}); + /** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.io/license + */ + class Mr{}Mr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.0-rc.0",ngImport:t,type:Mr,deps:[],target:t.ɵɵFactoryTarget.NgModule}),Mr.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.0-rc.0",ngImport:t,type:Mr,declarations:[qr,Ar],exports:[qr,Ar]}),Mr.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.0-rc.0",ngImport:t,type:Mr}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.0-rc.0",ngImport:t,type:Mr,decorators:[{type:c,args:[{declarations:[qr,Ar],exports:[qr,Ar]}]}]});class Er extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.mailBodyTypes=[{name:"tb.mail-body-type.plain-text",description:"tb.mail-body-type.plain-text-description",value:"false"},{name:"tb.mail-body-type.html",description:"tb.mail-body-type.html-text-description",value:"true"},{name:"tb.mail-body-type.use-body-type-template",description:"tb.mail-body-type.dynamic-text-description",value:"dynamic"}]}configForm(){return this.toEmailConfigForm}onConfigurationSet(e){this.toEmailConfigForm=this.fb.group({fromTemplate:[e?e.fromTemplate:null,[O.required]],toTemplate:[e?e.toTemplate:null,[O.required]],ccTemplate:[e?e.ccTemplate:null,[]],bccTemplate:[e?e.bccTemplate:null,[]],subjectTemplate:[e?e.subjectTemplate:null,[O.required]],mailBodyType:[e?e.mailBodyType:null],isHtmlTemplate:[e?e.isHtmlTemplate:null,[O.required]],bodyTemplate:[e?e.bodyTemplate:null,[O.required]]})}prepareInputConfig(e){return{fromTemplate:ie(e?.fromTemplate)?e.fromTemplate:null,toTemplate:ie(e?.toTemplate)?e.toTemplate:null,ccTemplate:ie(e?.ccTemplate)?e.ccTemplate:null,bccTemplate:ie(e?.bccTemplate)?e.bccTemplate:null,subjectTemplate:ie(e?.subjectTemplate)?e.subjectTemplate:null,mailBodyType:ie(e?.mailBodyType)?e.mailBodyType:null,isHtmlTemplate:ie(e?.isHtmlTemplate)?e.isHtmlTemplate:null,bodyTemplate:ie(e?.bodyTemplate)?e.bodyTemplate:null}}updateValidators(e){"dynamic"===this.toEmailConfigForm.get("mailBodyType").value?this.toEmailConfigForm.get("isHtmlTemplate").enable({emitEvent:!1}):this.toEmailConfigForm.get("isHtmlTemplate").disable({emitEvent:!1}),this.toEmailConfigForm.get("isHtmlTemplate").updateValueAndValidity({emitEvent:e})}validatorTriggers(){return["mailBodyType"]}getBodyTypeName(){return this.mailBodyTypes.find((e=>e.value===this.toEmailConfigForm.get("mailBodyType").value)).name}}e("ToEmailConfigComponent",Er),Er.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Er,deps:[{token:P.Store},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Er.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Er,selector:"tb-transformation-node-to-email-config",usesInheritance:!0,ngImport:t,template:'
\n
\n
tb.rulenode.email-sender
\n
\n \n tb.rulenode.from-template\n \n \n {{ \'tb.rulenode.email-from-template-hint\' | translate }}\n \n \n
\n
\n
\n
\n \n {{ \'tb.rulenode.from-template-required\' | translate }}\n \n
\n
\n
\n
\n
\n
tb.rulenode.recipients
\n \n \n
\n
\n \n tb.rulenode.to-template\n \n \n {{ \'tb.rulenode.to-template-required\' | translate }}\n \n \n \n tb.rulenode.cc-template\n \n \n \n tb.rulenode.bcc-template\n \n \n
\n
\n
\n
tb.rulenode.message-subject-and-content
\n \n \n
\n \n tb.rulenode.subject-template\n \n \n {{ \'tb.rulenode.subject-template-required\' | translate }}\n \n \n \n tb.rulenode.mail-body-type\n \n \n \n {{ getBodyTypeName() | translate }}\n \n \n \n \n {{ type.name | translate }}\n \n
\n \n {{ type.description | translate }}\n \n
\n
\n
\n \n tb.rulenode.body-type-template\n \n tb.mail-body-type.after-template-evaluation-hint\n \n \n tb.rulenode.body-template\n \n \n {{ \'tb.rulenode.body-template-required\' | translate }}\n \n \n
\n
\n
\n',styles:[":host .input-bottom-double-hint{display:inline-flex}:host .input-bottom-double-hint .see-example{flex-shrink:0;padding-right:16px}:host textarea.tb-enable-vertical-resize{resize:vertical}\n"],dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:He.HelpPopupComponent,selector:"[tb-help-popup], [tb-help-popup-content]",inputs:["tb-help-popup","tb-help-popup-content","trigger-text","trigger-style","tb-help-popup-placement","tb-help-popup-style","hintMode"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Ar,selector:"textarea[cdkTextareaAutosize]",inputs:["cdkAutosizeMinRows","cdkAutosizeMaxRows","cdkTextareaAutosize","placeholder"],exportAs:["cdkTextareaAutosize"]},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"directive",type:X.MatSelectTrigger,selector:"mat-select-trigger"},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:Ne.MatListItemTitle,selector:"[matListItemTitle]"},{kind:"directive",type:Ne.MatListItemMeta,selector:"[matListItemMeta]"},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Nn,selector:"tb-example-hint",inputs:["hintText","popupHelpLink","textAlign"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Er,decorators:[{type:n,args:[{selector:"tb-transformation-node-to-email-config",template:'
\n
\n
tb.rulenode.email-sender
\n
\n \n tb.rulenode.from-template\n \n \n {{ \'tb.rulenode.email-from-template-hint\' | translate }}\n \n \n
\n
\n
\n
\n \n {{ \'tb.rulenode.from-template-required\' | translate }}\n \n
\n
\n
\n
\n
\n
tb.rulenode.recipients
\n \n \n
\n
\n \n tb.rulenode.to-template\n \n \n {{ \'tb.rulenode.to-template-required\' | translate }}\n \n \n \n tb.rulenode.cc-template\n \n \n \n tb.rulenode.bcc-template\n \n \n
\n
\n
\n
tb.rulenode.message-subject-and-content
\n \n \n
\n \n tb.rulenode.subject-template\n \n \n {{ \'tb.rulenode.subject-template-required\' | translate }}\n \n \n \n tb.rulenode.mail-body-type\n \n \n \n {{ getBodyTypeName() | translate }}\n \n \n \n \n {{ type.name | translate }}\n \n
\n \n {{ type.description | translate }}\n \n
\n
\n
\n \n tb.rulenode.body-type-template\n \n tb.mail-body-type.after-template-evaluation-hint\n \n \n tb.rulenode.body-template\n \n \n {{ \'tb.rulenode.body-template-required\' | translate }}\n \n \n
\n
\n
\n',styles:[":host .input-bottom-double-hint{display:inline-flex}:host .input-bottom-double-hint .see-example{flex-shrink:0;padding-right:16px}:host textarea.tb-enable-vertical-resize{resize:vertical}\n"]}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder}]}});class Gr extends f{constructor(e,t,n){super(e),this.store=e,this.fb=t,this.translate=n,this.copyFrom=[],this.translation=tn;for(const e of this.translation.keys())this.copyFrom.push({value:e,name:this.translate.instant(this.translation.get(e))})}onConfigurationSet(e){this.copyKeysConfigForm=this.fb.group({copyFrom:[e.copyFrom,[O.required]],keys:[e?e.keys:null,[O.required]]})}configForm(){return this.copyKeysConfigForm}prepareInputConfig(e){let t;return t=ie(e?.fromMetadata)?e.copyFrom?en.METADATA:en.DATA:ie(e?.copyFrom)?e.copyFrom:en.DATA,{keys:ie(e?.keys)?e.keys:null,copyFrom:t}}}e("CopyKeysConfigComponent",Gr),Gr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Gr,deps:[{token:P.Store},{token:R.FormBuilder},{token:Z.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Gr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Gr,selector:"tb-transformation-node-copy-keys-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n help\n \n \n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"component",type:Ze.StringItemsListComponent,selector:"tb-string-items-list",inputs:["required","disabled","label","placeholder","hint","requiredText","floatLabel","appearance","editable","subscriptSizing","predefinedValues"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:Y.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:On,selector:"tb-msg-metadata-chip",inputs:["labelText","translation"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Gr,decorators:[{type:n,args:[{selector:"tb-transformation-node-copy-keys-config",template:'
\n \n \n \n \n help\n \n \n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder},{type:Z.TranslateService}]}});class Dr extends f{constructor(e,t,n){super(e),this.store=e,this.fb=t,this.translate=n,this.renameIn=[],this.translation=rn;for(const e of this.translation.keys())this.renameIn.push({value:e,name:this.translate.instant(this.translation.get(e))})}configForm(){return this.renameKeysConfigForm}onConfigurationSet(e){this.renameKeysConfigForm=this.fb.group({renameIn:[e?e.renameIn:null,[O.required]],renameKeysMapping:[e?e.renameKeysMapping:null,[O.required]]})}prepareInputConfig(e){let t;return t=ie(e?.fromMetadata)?e.fromMetadata?en.METADATA:en.DATA:ie(e?.renameIn)?e?.renameIn:en.DATA,{renameKeysMapping:ie(e?.renameKeysMapping)?e.renameKeysMapping:null,renameIn:t}}}e("RenameKeysConfigComponent",Dr),Dr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Dr,deps:[{token:P.Store},{token:R.FormBuilder},{token:Z.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Dr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Dr,selector:"tb-transformation-node-rename-keys-config",usesInheritance:!0,ngImport:t,template:'
\n
tb.rulenode.rename-keys-in
\n
\n
\n \n \n {{ data.name }}\n \n \n
\n
\n \n \n
\n',styles:[":host .fetch-to-data-toggle{max-width:420px;width:100%}:host .fx-centered{display:flex;width:100%;justify-content:space-around}\n"],dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"directive",type:Xe.ToggleOption,selector:"tb-toggle-option",inputs:["value"]},{kind:"component",type:et.ToggleSelectComponent,selector:"tb-toggle-select",inputs:["disabled","selectMediaBreakpoint","appearance","disablePagination"]},{kind:"component",type:Sn,selector:"tb-kv-map-config",inputs:["disabled","uniqueKeyValuePairValidator","labelText","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","popupHelpLink","required"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Dr,decorators:[{type:n,args:[{selector:"tb-transformation-node-rename-keys-config",template:'
\n
tb.rulenode.rename-keys-in
\n
\n
\n \n \n {{ data.name }}\n \n \n
\n
\n \n \n
\n',styles:[":host .fetch-to-data-toggle{max-width:420px;width:100%}:host .fx-centered{display:flex;width:100%;justify-content:space-around}\n"]}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder},{type:Z.TranslateService}]}});class wr extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.jsonPathConfigForm}onConfigurationSet(e){this.jsonPathConfigForm=this.fb.group({jsonPath:[e?e.jsonPath:null,[O.required]]})}}e("NodeJsonPathConfigComponent",wr),wr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:wr,deps:[{token:P.Store},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),wr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:wr,selector:"tb-transformation-node-json-path-config",usesInheritance:!0,ngImport:t,template:"
\n \n {{ 'tb.rulenode.json-path-expression' | translate }}\n \n {{ 'tb.rulenode.json-path-expression-hint' | translate }}\n {{ 'tb.rulenode.json-path-expression-required' | translate }}\n \n
\n",dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:wr,decorators:[{type:n,args:[{selector:"tb-transformation-node-json-path-config",template:"
\n \n {{ 'tb.rulenode.json-path-expression' | translate }}\n \n {{ 'tb.rulenode.json-path-expression-hint' | translate }}\n {{ 'tb.rulenode.json-path-expression-required' | translate }}\n \n
\n"}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder}]}});class Vr extends f{constructor(e,t,n){super(e),this.store=e,this.fb=t,this.translate=n,this.deleteFrom=[],this.translation=nn;for(const e of this.translation.keys())this.deleteFrom.push({value:e,name:this.translate.instant(this.translation.get(e))})}onConfigurationSet(e){this.deleteKeysConfigForm=this.fb.group({deleteFrom:[e.deleteFrom,[O.required]],keys:[e?e.keys:null,[O.required]]})}prepareInputConfig(e){let t;return t=ie(e?.fromMetadata)?e.fromMetadata?en.METADATA:en.DATA:ie(e?.deleteFrom)?e?.deleteFrom:en.DATA,{keys:ie(e?.keys)?e.keys:null,deleteFrom:t}}configForm(){return this.deleteKeysConfigForm}}e("DeleteKeysConfigComponent",Vr),Vr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Vr,deps:[{token:P.Store},{token:R.FormBuilder},{token:Z.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Vr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Vr,selector:"tb-transformation-node-delete-keys-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n help\n \n \n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"component",type:Ze.StringItemsListComponent,selector:"tb-string-items-list",inputs:["required","disabled","label","placeholder","hint","requiredText","floatLabel","appearance","editable","subscriptSizing","predefinedValues"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:Y.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:On,selector:"tb-msg-metadata-chip",inputs:["labelText","translation"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Vr,decorators:[{type:n,args:[{selector:"tb-transformation-node-delete-keys-config",template:'
\n \n \n \n \n help\n \n \n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder},{type:Z.TranslateService}]}});class Pr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.deduplicationStrategie=Gt,this.deduplicationStrategies=Object.keys(this.deduplicationStrategie),this.deduplicationStrategiesTranslations=Dt}configForm(){return this.deduplicationConfigForm}onConfigurationSet(e){this.deduplicationConfigForm=this.fb.group({interval:[ie(e?.interval)?e.interval:null,[O.required,O.min(1)]],strategy:[ie(e?.strategy)?e.strategy:null,[O.required]],outMsgType:[ie(e?.outMsgType)?e.outMsgType:null,[O.required]],maxPendingMsgs:[ie(e?.maxPendingMsgs)?e.maxPendingMsgs:null,[O.required,O.min(1),O.max(1e3)]],maxRetries:[ie(e?.maxRetries)?e.maxRetries:null,[O.required,O.min(0),O.max(100)]]})}prepareInputConfig(e){return e||(e={}),e.outMsgType||(e.outMsgType="POST_TELEMETRY_REQUEST"),super.prepareInputConfig(e)}updateValidators(e){this.deduplicationConfigForm.get("strategy").value===this.deduplicationStrategie.ALL?this.deduplicationConfigForm.get("outMsgType").enable({emitEvent:!1}):this.deduplicationConfigForm.get("outMsgType").disable({emitEvent:!1}),this.deduplicationConfigForm.get("outMsgType").updateValueAndValidity({emitEvent:e})}validatorTriggers(){return["strategy"]}}e("DeduplicationConfigComponent",Pr),Pr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Pr,deps:[{token:P.Store},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Pr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Pr,selector:"tb-action-node-msg-deduplication-config",usesInheritance:!0,ngImport:t,template:'
\n \n {{\'tb.rulenode.interval\' | translate}}\n \n \n {{\'tb.rulenode.interval-required\' | translate}}\n \n \n {{\'tb.rulenode.interval-min-error\' | translate}}\n \n help\n \n
\n
\n
tb.rulenode.strategy
\n \n \n {{ deduplicationStrategiesTranslations.get(strategy) | translate }}\n \n \n \n \n \n \n \n \n
\n \n \n
\n
\n
\n \n \n tb.rulenode.advanced-settings\n \n
\n \n {{\'tb.rulenode.max-pending-msgs\' | translate}}\n \n \n {{\'tb.rulenode.max-pending-msgs-required\' | translate}}\n \n \n {{\'tb.rulenode.max-pending-msgs-max-error\' | translate}}\n \n \n {{\'tb.rulenode.max-pending-msgs-min-error\' | translate}}\n \n help\n \n \n {{\'tb.rulenode.max-retries\' | translate}}\n \n \n {{\'tb.rulenode.max-retries-required\' | translate}}\n \n \n {{\'tb.rulenode.max-retries-max-error\' | translate}}\n \n \n {{\'tb.rulenode.max-retries-min-error\' | translate}}\n \n help\n \n
\n
\n
\n
\n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Y.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:Je.MatExpansionPanel,selector:"mat-expansion-panel",inputs:["disabled","expanded","hideToggle","togglePosition"],outputs:["opened","closed","expandedChange","afterExpand","afterCollapse"],exportAs:["matExpansionPanel"]},{kind:"component",type:Je.MatExpansionPanelHeader,selector:"mat-expansion-panel-header",inputs:["tabIndex","expandedHeight","collapsedHeight"]},{kind:"directive",type:Je.MatExpansionPanelTitle,selector:"mat-panel-title"},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"directive",type:Xe.ToggleOption,selector:"tb-toggle-option",inputs:["value"]},{kind:"component",type:et.ToggleSelectComponent,selector:"tb-toggle-select",inputs:["disabled","selectMediaBreakpoint","appearance","disablePagination"]},{kind:"component",type:Rn,selector:"tb-output-message-type-autocomplete",inputs:["subscriptSizing","disabled","required"]},{kind:"component",type:Nn,selector:"tb-example-hint",inputs:["hintText","popupHelpLink","textAlign"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Pr,decorators:[{type:n,args:[{selector:"tb-action-node-msg-deduplication-config",template:'
\n \n {{\'tb.rulenode.interval\' | translate}}\n \n \n {{\'tb.rulenode.interval-required\' | translate}}\n \n \n {{\'tb.rulenode.interval-min-error\' | translate}}\n \n help\n \n
\n
\n
tb.rulenode.strategy
\n \n \n {{ deduplicationStrategiesTranslations.get(strategy) | translate }}\n \n \n \n \n \n \n \n \n
\n \n \n
\n
\n
\n \n \n tb.rulenode.advanced-settings\n \n
\n \n {{\'tb.rulenode.max-pending-msgs\' | translate}}\n \n \n {{\'tb.rulenode.max-pending-msgs-required\' | translate}}\n \n \n {{\'tb.rulenode.max-pending-msgs-max-error\' | translate}}\n \n \n {{\'tb.rulenode.max-pending-msgs-min-error\' | translate}}\n \n help\n \n \n {{\'tb.rulenode.max-retries\' | translate}}\n \n \n {{\'tb.rulenode.max-retries-required\' | translate}}\n \n \n {{\'tb.rulenode.max-retries-max-error\' | translate}}\n \n \n {{\'tb.rulenode.max-retries-min-error\' | translate}}\n \n help\n \n
\n
\n
\n
\n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder}]}});class Rr{}e("RulenodeCoreConfigTransformModule",Rr),Rr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Rr,deps:[],target:t.ɵɵFactoryTarget.NgModule}),Rr.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.10",ngImport:t,type:Rr,declarations:[Tr,Ir,Er,Gr,Dr,wr,Vr,Pr],imports:[$,M,Un],exports:[Tr,Ir,Er,Gr,Dr,wr,Vr,Pr]}),Rr.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Rr,imports:[$,M,Un]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Rr,decorators:[{type:c,args:[{declarations:[Tr,Ir,Er,Gr,Dr,wr,Vr,Pr],imports:[$,M,Un],exports:[Tr,Ir,Er,Gr,Dr,wr,Vr,Pr]}]}]});class Or extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.entityType=F}configForm(){return this.ruleChainInputConfigForm}onConfigurationSet(e){this.ruleChainInputConfigForm=this.fb.group({ruleChainId:[e?e.ruleChainId:null,[O.required]]})}}e("RuleChainInputComponent",Or),Or.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Or,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Or.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Or,selector:"tb-flow-node-rule-chain-input-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n
\n',dependencies:[{kind:"component",type:lt.EntityAutocompleteComponent,selector:"tb-entity-autocomplete",inputs:["entityType","entitySubtype","excludeEntityIds","labelText","requiredText","useFullEntityId","appearance","required","disabled"],outputs:["entityChanged"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Or,decorators:[{type:n,args:[{selector:"tb-flow-node-rule-chain-input-config",template:'
\n \n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class _r extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.ruleChainOutputConfigForm}onConfigurationSet(e){this.ruleChainOutputConfigForm=this.fb.group({})}}e("RuleChainOutputComponent",_r),_r.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:_r,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),_r.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:_r,selector:"tb-flow-node-rule-chain-output-config",usesInheritance:!0,ngImport:t,template:'
\n
\n
\n',dependencies:[{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:_r,decorators:[{type:n,args:[{selector:"tb-flow-node-rule-chain-output-config",template:'
\n
\n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class Br{}e("RuleNodeCoreConfigFlowModule",Br),Br.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Br,deps:[],target:t.ɵɵFactoryTarget.NgModule}),Br.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.10",ngImport:t,type:Br,declarations:[Or,_r],imports:[$,M,Un],exports:[Or,_r]}),Br.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Br,imports:[$,M,Un]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Br,decorators:[{type:c,args:[{declarations:[Or,_r],imports:[$,M,Un],exports:[Or,_r]}]}]});class Kr{constructor(e){!function(e){e.setTranslation("en_US",{tb:{rulenode:{id:"Id","additional-info":"Additional Info","advanced-settings":"Advanced settings","create-entity-if-not-exists":"Create new entity if not exists","create-entity-if-not-exists-hint":"Create a new entity set above if it does not exist.","entity-name-pattern":"Name pattern","entity-name-pattern-required":"Name pattern is required","entity-name-pattern-hint":"Name pattern field support templatization. Use $[messageKey] to extract value from the message and ${metadataKey} to extract value from the metadata.","copy-message-type":"Copy message type","entity-type-pattern":"Type pattern","entity-type-pattern-required":"Type pattern is required","message-type-value":"Message type value","message-type-value-required":"Message type value is required","message-type-value-max-length":"Message type value should be less than 256","output-message-type":"Output message type","entity-cache-expiration":"Entities cache expiration time (sec)","entity-cache-expiration-hint":"Specifies maximum time interval allowed to store found entity records. 0 value means that records will never expire.","entity-cache-expiration-required":"Entities cache expiration time is required.","entity-cache-expiration-range":"Entities cache expiration time should be greater than or equal to 0.","customer-name-pattern":"Customer name pattern","customer-name-pattern-required":"Customer name pattern is required","create-customer-if-not-exists":"Create new customer if not exists","customer-cache-expiration":"Customers cache expiration time (sec)","customer-cache-expiration-hint":"Specifies maximum time interval allowed to store found customer records. 0 value means that records will never expire.","customer-cache-expiration-required":"Customers cache expiration time is required.","customer-cache-expiration-range":"Customers cache expiration time should be greater than or equal to 0.","interval-start":"Interval start","interval-end":"Interval end","time-unit":"Time unit","fetch-mode":"Fetch mode","order-by-timestamp":"Order by timestamp",limit:"Limit","limit-hint":"Min limit value is 2, max - 1000. If you want to fetch a single entry, select fetch mode 'First' or 'Last'.","limit-required":"Limit is required.","limit-range":"Limit should be in a range from 2 to 1000.","time-unit-milliseconds":"Milliseconds","time-unit-seconds":"Seconds","time-unit-minutes":"Minutes","time-unit-hours":"Hours","time-unit-days":"Days","time-value-range":"Allowing range from 1 to 2147483647.","start-interval-value-required":"Interval start is required.","end-interval-value-required":"Interval end is required.",filter:"Filter",switch:"Switch","math-templatization-tooltip":"This field support templatization. Use $[messageKey] to extract value from the message and ${metadataKey} to extract value from the metadata.","add-message-type":"Add message type","select-message-types-required":"At least one message type should be selected.","select-message-types":"Select message types","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","attributes-keys":"Attributes keys","attributes-keys-required":"Attributes keys are required","notify-device":"Force notification to the device","send-attributes-updated-notification":"Send attributes updated notification","send-attributes-updated-notification-hint":"Send notification about updated attributes as a separate message to the rule engine queue.","send-attributes-deleted-notification":"Send attributes deleted notification","send-attributes-deleted-notification-hint":"Send notification about deleted attributes as a separate message to the rule engine queue.","update-attributes-only-on-value-change":"Save attributes only if the value changes","update-attributes-only-on-value-change-hint":"Updates the attributes on every incoming message disregarding if their value has changed. Increases API usage and reduces performance.","update-attributes-only-on-value-change-hint-enabled":"Updates the attributes only if their value has changed. If the value is not changed, no update to the attribute timestamp nor attribute change notification will be sent.","fetch-credentials-to-metadata":"Fetch credentials to metadata","notify-device-on-update-hint":"If enabled, force notification to the device about shared attributes update. If disabled, the notification behavior is controlled by the 'notifyDevice' parameter from the incoming message metadata. To turn off the notification, the message metadata must contain the 'notifyDevice' parameter set to 'false'. Any other case will trigger the notification to the device.","notify-device-on-delete-hint":"If enabled, force notification to the device about shared attributes removal. If disabled, the notification behavior is controlled by the 'notifyDevice' parameter from the incoming message metadata. To turn on the notification, the message metadata must contain the 'notifyDevice' parameter set to 'true'. In any other case, the notification will not be triggered to the device.","latest-timeseries":"Latest time-series data keys","timeseries-keys":"Timeseries keys","timeseries-keys-required":"At least one timeseries key should be selected.","add-timeseries-key":"Add timeseries key","add-message-field":"Add message field","relation-search-parameters":"Relation search parameters","add-metadata-field":"Add metadata field","data-keys":"Message field names","copy-from":"Copy from","data-to-metadata":"Data to metadata","metadata-to-data":"Metadata to data","use-regular-expression-hint":"Use regular expression to copy keys by pattern.\n\nTips & tricks:\nPress 'Enter' to complete field name input.\nPress 'Backspace' to delete field name. Multiple field names supported.",interval:"Interval","interval-required":"Interval is required","interval-hint":"Deduplication interval in seconds.","interval-min-error":"Min allowed value is 1","max-pending-msgs":"Max pending messages","max-pending-msgs-hint":"Maximum number of messages that are stored in memory for each unique deduplication id.","max-pending-msgs-required":"Max pending messages is required","max-pending-msgs-max-error":"Max allowed value is 1000","max-pending-msgs-min-error":"Min allowed value is 1","max-retries":"Max retries","max-retries-required":"Max retries is required","max-retries-hint":"Maximum number of retries to push the deduplicated messages into the queue. 10 seconds delay is used between retries","max-retries-max-error":"Max allowed value is 100","max-retries-min-error":"Min allowed value is 0",strategy:"Strategy","strategy-required":"Strategy is required","strategy-all-hint":"Return all messages that arrived during deduplication period as a single JSON array message. Where each element represents object with msg and metadata inner properties.","strategy-first-hint":"Return first message that arrived during deduplication period.","strategy-last-hint":"Return last message that arrived during deduplication period.",first:"First",last:"Last",all:"All","output-msg-type-hint":"The message type of the deduplication result.","queue-name-hint":"The queue name where the deduplication result will be published.",keys:"Keys","keys-required":"Keys are required","rename-keys-in":"Rename keys in",data:"Data",message:"Message",metadata:"Metadata","current-key-name":"Current key name","key-name-required":"Key name is required","new-key-name":"New key name","new-key-name-required":"New key name is required","metadata-keys":"Metadata field names","json-path-expression":"JSON path expression","json-path-expression-required":"JSON path expression is required","json-path-expression-hint":"JSONPath specifies a path to an element or a set of elements in a JSON structure. '$' represents the root object or array.","relations-query":"Relations query","device-relations-query":"Device relations query","max-relation-level":"Max relation level","max-relation-level-error":"Value should be greater than 0 or unspecified.","relation-type":"Relation type","relation-type-pattern":"Relation type pattern","relation-type-pattern-required":"Relation type pattern is required","relation-types-list":"Relation types to propagate","relation-types-list-hint":"If Propagate relation types are not selected, alarms will be propagated without filtering by relation type.","unlimited-level":"Unlimited level","latest-telemetry":"Latest telemetry","add-telemetry-key":"Add telemetry key","delete-from":"Delete from","use-regular-expression-delete-hint":"Use regular expression to delete keys by pattern.\n\nTips & tricks:\nPress 'Enter' to complete field name input.\nPress 'Backspace' to delete field name.\nMultiple field names supported.","fetch-into":"Fetch into","attr-mapping":"Attributes mapping:","source-attribute":"Source attribute key","source-attribute-required":"Source attribute key is required.","source-telemetry":"Source telemetry key","source-telemetry-required":"Source telemetry key is required.","target-key":"Target key","target-key-required":"Target key is required.","attr-mapping-required":"At least one mapping entry should be specified.","fields-mapping":"Fields mapping","relations-query-config-direction-suffix":"originator","profile-name":"Profile name","fetch-circle-parameter-info-from-metadata-hint":'Metadata field \'{{perimeterKeyName}}\' should be defined in next format: {"latitude":48.196, "longitude":24.6532, "radius":100.0, "radiusUnit":"METER"}',"fetch-poligon-parameter-info-from-metadata-hint":"Metadata field '{{perimeterKeyName}}' should be defined in next format: [[48.19736,24.65235],[48.19800,24.65060],...,[48.19849,24.65420]]","short-templatization-tooltip":"Use $[messageKey] to extract value from the message and ${metadataKey} to extract value from the metadata.","fields-mapping-required":"At least one field mapping should be specified.","at-least-one-field-required":"At least one input field must have a value(s) provided.","originator-fields-sv-map-hint":"Target key fields support templatization. Use $[messageKey] to extract value from the message and ${metadataKey} to extract value from the metadata.","sv-map-hint":"Only target key fields support templatization. Use $[messageKey] to extract value from the message and ${metadataKey} to extract value from the metadata.","source-field":"Source field","source-field-required":"Source field is required.","originator-source":"Originator source","new-originator":"New originator","originator-customer":"Customer","originator-tenant":"Tenant","originator-related":"Related entity","originator-alarm-originator":"Alarm Originator","originator-entity":"Entity by name pattern","clone-message":"Clone message",transform:"Transform","default-ttl":"Default TTL in seconds","default-ttl-required":"Default TTL is required.","min-default-ttl-message":"Only 0 minimum TTL is allowed.","message-count":"Message count (0 - unlimited)","message-count-required":"Message count is required.","min-message-count-message":"Only 0 minimum message count is allowed.","period-seconds":"Period in seconds","period-seconds-required":"Period is required.","use-metadata-period-in-seconds-patterns":"Use period in seconds pattern","use-metadata-period-in-seconds-patterns-hint":"If selected, rule node use period in seconds interval pattern from message metadata or data assuming that intervals are in the seconds.","period-in-seconds-pattern":"Period in seconds pattern","period-in-seconds-pattern-required":"Period in seconds pattern is required","min-period-seconds-message":"Only 1 second minimum period is allowed.",originator:"Originator","message-body":"Message body","message-metadata":"Message metadata",generate:"Generate","test-generator-function":"Test generator function",generator:"Generator","test-filter-function":"Test filter function","test-switch-function":"Test switch function","test-transformer-function":"Test transformer function",transformer:"Transformer","alarm-create-condition":"Alarm create condition","test-condition-function":"Test condition function","alarm-clear-condition":"Alarm clear condition","alarm-details-builder":"Alarm details builder","test-details-function":"Test details function","alarm-type":"Alarm type","select-entity-types":"Select entity types","alarm-type-required":"Alarm type is required.","alarm-severity":"Alarm severity","alarm-severity-required":"Alarm severity is required","alarm-severity-pattern":"Alarm severity pattern","alarm-status-filter":"Alarm status filter","alarm-status-list-empty":"Alarm status list is empty","no-alarm-status-matching":"No alarm status matching were found.",propagate:"Propagate alarm to related entities","propagate-to-owner":"Propagate alarm to entity owner (Customer or Tenant)","propagate-to-tenant":"Propagate alarm to Tenant",condition:"Condition",details:"Details","to-string":"To string","test-to-string-function":"Test to string function","from-template":"From","from-template-required":"From is required","message-to-metadata":"Message to metadata","metadata-to-message":"Metadata to message","from-message":"From message","from-metadata":"From metadata","to-template":"To","to-template-required":"To Template is required","mail-address-list-template-hint":'Comma separated address list, use ${metadataKey} for value from metadata, $[messageKey] for value from message body',"cc-template":"Cc","bcc-template":"Bcc","subject-template":"Subject","subject-template-required":"Subject Template is required","body-template":"Body","body-template-required":"Body Template is required","dynamic-mail-body-type":"Dynamic mail body type","mail-body-type":"Mail body type","body-type-template":"Body type template","request-id-metadata-attribute":"Request Id Metadata attribute name","timeout-sec":"Timeout in seconds","timeout-required":"Timeout is required","min-timeout-message":"Only 0 minimum timeout value is allowed.","endpoint-url-pattern":"Endpoint URL pattern","endpoint-url-pattern-required":"Endpoint URL pattern is required","request-method":"Request method","use-simple-client-http-factory":"Use simple client HTTP factory","ignore-request-body":"Without request body","parse-to-plain-text":"Parse to plain text","parse-to-plain-text-hint":'If selected, request body message payload will be transformed from JSON string to plain text, e.g. msg = "Hello,\\t\\"world\\"" will be parsed to Hello, "world"',"read-timeout":"Read timeout in millis","read-timeout-hint":"The value of 0 means an infinite timeout","max-parallel-requests-count":"Max number of parallel requests","max-parallel-requests-count-hint":"The value of 0 specifies no limit in parallel processing",headers:"Headers","headers-hint":'Use ${metadataKey} for value from metadata, $[messageKey] for value from message body in header/value fields',header:"Header","header-required":"Header is required",value:"Value","value-required":"Value is required","topic-pattern":"Topic pattern","key-pattern":"Key pattern","key-pattern-hint":"Optional. If a valid partition number is specified, it will be used when sending the record. If no partition is specified, the key will be used instead. If neither is specified, a partition will be assigned in a round-robin fashion.","topic-pattern-required":"Topic pattern is required",topic:"Topic","topic-required":"Topic is required","bootstrap-servers":"Bootstrap servers","bootstrap-servers-required":"Bootstrap servers value is required","other-properties":"Other properties",key:"Key","key-required":"Key is required",retries:"Automatically retry times if fails","min-retries-message":"Only 0 minimum retries is allowed.","batch-size-bytes":"Produces batch size in bytes","min-batch-size-bytes-message":"Only 0 minimum batch size is allowed.","linger-ms":"Time to buffer locally (ms)","min-linger-ms-message":"Only 0 ms minimum value is allowed.","buffer-memory-bytes":"Client buffer max size in bytes","min-buffer-memory-message":"Only 0 minimum buffer size is allowed.",acks:"Number of acknowledgments","key-serializer":"Key serializer","key-serializer-required":"Key serializer is required","value-serializer":"Value serializer","value-serializer-required":"Value serializer is required","topic-arn-pattern":"Topic ARN pattern","topic-arn-pattern-required":"Topic ARN pattern is required","aws-access-key-id":"AWS Access Key ID","aws-access-key-id-required":"AWS Access Key ID is required","aws-secret-access-key":"AWS Secret Access Key","aws-secret-access-key-required":"AWS Secret Access Key is required","aws-region":"AWS Region","aws-region-required":"AWS Region is required","exchange-name-pattern":"Exchange name pattern","routing-key-pattern":"Routing key pattern","message-properties":"Message properties",host:"Host","host-required":"Host is required",port:"Port","port-required":"Port is required","port-range":"Port should be in a range from 1 to 65535.","virtual-host":"Virtual host",username:"Username",password:"Password","automatic-recovery":"Automatic recovery","connection-timeout-ms":"Connection timeout (ms)","min-connection-timeout-ms-message":"Only 0 ms minimum value is allowed.","handshake-timeout-ms":"Handshake timeout (ms)","min-handshake-timeout-ms-message":"Only 0 ms minimum value is allowed.","client-properties":"Client properties","queue-url-pattern":"Queue URL pattern","queue-url-pattern-required":"Queue URL pattern is required","delay-seconds":"Delay (seconds)","min-delay-seconds-message":"Only 0 seconds minimum value is allowed.","max-delay-seconds-message":"Only 900 seconds maximum value is allowed.",name:"Name","name-required":"Name is required","queue-type":"Queue type","sqs-queue-standard":"Standard","sqs-queue-fifo":"FIFO","gcp-project-id":"GCP project ID","gcp-project-id-required":"GCP project ID is required","gcp-service-account-key":"GCP service account key file","gcp-service-account-key-required":"GCP service account key file is required","pubsub-topic-name":"Topic name","pubsub-topic-name-required":"Topic name is required","message-attributes":"Message attributes","message-attributes-hint":'Use ${metadataKey} for value from metadata, $[messageKey] for value from message body in name/value fields',"connect-timeout":"Connection timeout (sec)","connect-timeout-required":"Connection timeout is required.","connect-timeout-range":"Connection timeout should be in a range from 1 to 200.","client-id":"Client ID","client-id-hint":'Optional. Leave empty for auto-generated Client ID. Be careful when specifying the Client ID. Majority of the MQTT brokers will not allow multiple connections with the same Client ID. To connect to such brokers, your mqtt Client ID must be unique. When platform is running in a micro-services mode, the copy of rule node is launched in each micro-service. This will automatically lead to multiple mqtt clients with the same ID and may cause failures of the rule node. To avoid such failures enable "Add Service ID as suffix to Client ID" option below.',"append-client-id-suffix":"Add Service ID as suffix to Client ID","client-id-suffix-hint":'Optional. Applied when "Client ID" specified explicitly. If selected then Service ID will be added to Client ID as a suffix. Helps to avoid failures when platform is running in a micro-services mode.',"device-id":"Device ID","device-id-required":"Device ID is required.","clean-session":"Clean session","enable-ssl":"Enable SSL",credentials:"Credentials","credentials-type":"Credentials type","credentials-type-required":"Credentials type is required.","credentials-anonymous":"Anonymous","credentials-basic":"Basic","credentials-pem":"PEM","credentials-pem-hint":"At least Server CA certificate file or a pair of Client certificate and Client private key files are required","credentials-sas":"Shared Access Signature","sas-key":"SAS Key","sas-key-required":"SAS Key is required.",hostname:"Hostname","hostname-required":"Hostname is required.","azure-ca-cert":"CA certificate file","username-required":"Username is required.","password-required":"Password is required.","ca-cert":"Server CA certificate file","private-key":"Client private key file",cert:"Client certificate file","no-file":"No file selected.","drop-file":"Drop a file or click to select a file to upload.","private-key-password":"Private key password","use-system-smtp-settings":"Use system SMTP settings","use-metadata-dynamic-interval":"Use dynamic interval","metadata-dynamic-interval-hint":"Interval start and end input fields support templatization. Note that the substituted template value should be set in milliseconds. Use $[messageKey] to extract value from the message and ${metadataKey} to extract value from the metadata.","use-metadata-interval-patterns-hint":"If selected, rule node use start and end interval patterns from message metadata or data assuming that intervals are in the milliseconds.","use-message-alarm-data":"Use message alarm data","overwrite-alarm-details":"Overwrite alarm details","use-alarm-severity-pattern":"Use alarm severity pattern","check-all-keys":"Check that all specified fields are present","check-all-keys-hint":"If selected, checks that all specified keys are present in the message data and metadata.","check-relation-to-specific-entity":"Check relation to specific entity","check-relation-to-specific-entity-tooltip":"If enabled, checks the presence of relation with a specific entity otherwise, checks the presence of relation with any entity. In both cases, relation lookup is based on configured direction and type.","check-relation-hint":"Checks existence of relation to specific entity or to any entity based on direction and relation type.","delete-relation-to-specific-entity":"Delete relation to specific entity","delete-relation-hint":"Deletes relation from the originator of the incoming message to the specified entity or list of entities based on direction and type.","remove-current-relations":"Remove current relations","remove-current-relations-hint":"Removes current relations from the originator of the incoming message based on direction and type.","change-originator-to-related-entity":"Change originator to related entity","change-originator-to-related-entity-hint":"Used to process submitted message as a message from another entity.","start-interval":"Interval start","end-interval":"Interval end","start-interval-required":"Interval start is required.","end-interval-required":"Interval end is required.","smtp-protocol":"Protocol","smtp-host":"SMTP host","smtp-host-required":"SMTP host is required.","smtp-port":"SMTP port","smtp-port-required":"You must supply a smtp port.","smtp-port-range":"SMTP port should be in a range from 1 to 65535.","timeout-msec":"Timeout ms","min-timeout-msec-message":"Only 0 ms minimum value is allowed.","enter-username":"Enter username","enter-password":"Enter password","enable-tls":"Enable TLS","tls-version":"TLS version","enable-proxy":"Enable proxy","use-system-proxy-properties":"Use system proxy properties","proxy-host":"Proxy host","proxy-host-required":"Proxy host is required.","proxy-port":"Proxy port","proxy-port-required":"Proxy port is required.","proxy-port-range":"Proxy port should be in a range from 1 to 65535.","proxy-user":"Proxy user","proxy-password":"Proxy password","proxy-scheme":"Proxy scheme","numbers-to-template":"Phone Numbers To Template","numbers-to-template-required":"Phone Numbers To Template is required","numbers-to-template-hint":'Comma separated Phone Numbers, use ${metadataKey} for value from metadata, $[messageKey] for value from message body',"sms-message-template":"SMS message Template","sms-message-template-required":"SMS message Template is required","use-system-sms-settings":"Use system SMS provider settings","min-period-0-seconds-message":"Only 0 second minimum period is allowed.","max-pending-messages":"Maximum pending messages","max-pending-messages-required":"Maximum pending messages is required.","max-pending-messages-range":"Maximum pending messages should be in a range from 1 to 100000.","originator-types-filter":"Originator types filter","interval-seconds":"Interval in seconds","interval-seconds-required":"Interval is required.","min-interval-seconds-message":"Only 1 second minimum interval is allowed.","output-timeseries-key-prefix":"Output timeseries key prefix","output-timeseries-key-prefix-required":"Output timeseries key prefix required.","separator-hint":'Press "Enter" to complete field input.',"select-details":"Select details","entity-details-id":"Id","entity-details-title":"Title","entity-details-country":"Country","entity-details-state":"State","entity-details-city":"City","entity-details-zip":"Zip","entity-details-address":"Address","entity-details-address2":"Address2","entity-details-additional_info":"Additional Info","entity-details-phone":"Phone","entity-details-email":"Email","email-sender":"Email sender","fields-to-check":"Fields to check","add-detail":"Add detail","check-all-keys-tooltip":"If enabled, checks the presence of all fields listed in the message and metadata field names within the incoming message and its metadata.","fields-to-check-hint":'Press "Enter" to complete field name input. Multiple field names supported.',"entity-details-list-empty":"At least one detail should be selected.","alarm-status":"Alarm status","alarm-required":"At least one alarm status should be selected.","no-entity-details-matching":"No entity details matching were found.","custom-table-name":"Custom table name","custom-table-name-required":"Table Name is required","custom-table-hint":"Enter the table name without prefix 'cs_tb_'.","message-field":"Message field","message-field-required":"Message field is required.","table-col":"Table column","table-col-required":"Table column is required.","latitude-field-name":"Latitude field name","longitude-field-name":"Longitude field name","latitude-field-name-required":"Latitude field name is required.","longitude-field-name-required":"Longitude field name is required.","fetch-perimeter-info-from-metadata":"Fetch perimeter information from metadata","fetch-perimeter-info-from-metadata-tooltip":"If perimeter type is set to 'Polygon' the value of metadata field '{{perimeterKeyName}}' will be set as perimeter definition without additional parsing of the value. Otherwise, if perimeter type is set to 'Circle' the value of '{{perimeterKeyName}}' metadata field will be parsed to extract 'latitude', 'longitude', 'radius', 'radiusUnit' fields that uses for circle perimeter definition.","perimeter-key-name":"Perimeter key name","perimeter-key-name-hint":"Metadata field name that includes perimeter information.","perimeter-key-name-required":"Perimeter key name is required.","perimeter-circle":"Circle","perimeter-polygon":"Polygon","perimeter-type":"Perimeter type","circle-center-latitude":"Center latitude","circle-center-latitude-required":"Center latitude is required.","circle-center-longitude":"Center longitude","circle-center-longitude-required":"Center longitude is required.","range-unit-meter":"Meter","range-unit-kilometer":"Kilometer","range-unit-foot":"Foot","range-unit-mile":"Mile","range-unit-nautical-mile":"Nautical mile","range-units":"Range units","range-units-required":"Range units is required.",range:"Range","range-required":"Range is required.","polygon-definition":"Polygon definition","polygon-definition-required":"Polygon definition is required.","polygon-definition-hint":"Use the following format for manual definition of polygon: [[lat1,lon1],[lat2,lon2], ... ,[latN,lonN]].","min-inside-duration":"Minimal inside duration","min-inside-duration-value-required":"Minimal inside duration is required","min-inside-duration-time-unit":"Minimal inside duration time unit","min-outside-duration":"Minimal outside duration","min-outside-duration-value-required":"Minimal outside duration is required","min-outside-duration-time-unit":"Minimal outside duration time unit","tell-failure-if-absent":"Tell Failure","tell-failure-if-absent-hint":'If at least one selected key doesn\'t exist the outbound message will report "Failure".',"get-latest-value-with-ts":"Fetch timestamp for the latest telemetry values","get-latest-value-with-ts-hint":'If selected, the latest telemetry values will also include timestamp, e.g: "temp": "{"ts":1574329385897, "value":42}"',"use-redis-queue":"Use redis queue for message persistence","ignore-null-strings":"Ignore null strings","ignore-null-strings-hint":"If selected rule node will ignore entity fields with empty value.","trim-redis-queue":"Trim redis queue","redis-queue-max-size":"Redis queue max size","add-metadata-key-values-as-kafka-headers":"Add Message metadata key-value pairs to Kafka record headers","add-metadata-key-values-as-kafka-headers-hint":"If selected, key-value pairs from message metadata will be added to the outgoing records headers as byte arrays with predefined charset encoding.","charset-encoding":"Charset encoding","charset-encoding-required":"Charset encoding is required.","charset-us-ascii":"US-ASCII","charset-iso-8859-1":"ISO-8859-1","charset-utf-8":"UTF-8","charset-utf-16be":"UTF-16BE","charset-utf-16le":"UTF-16LE","charset-utf-16":"UTF-16","select-queue-hint":"The queue name can be selected from a drop-down list or add a custom name.","persist-alarm-rules":"Persist state of alarm rules","fetch-alarm-rules":"Fetch state of alarm rules","input-value-key":"Input value key","input-value-key-required":"Input value key is required.","output-value-key":"Output value key","output-value-key-required":"Output value key is required.","number-of-digits-after-floating-point":"Number of digits after floating point","number-of-digits-after-floating-point-range":"Number of digits after floating point should be in a range from 0 to 15.","failure-if-delta-negative":"Tell Failure if delta is negative","failure-if-delta-negative-tooltip":"Rule node forces failure of message processing if delta value is negative.","use-caching":"Use caching","use-caching-tooltip":'Rule node will cache the value of "{{inputValueKey}}" that arrives from the incoming message to improve performance. Note that the cache will not be updated if you modify the "{{inputValueKey}}" value elsewhere.',"add-time-difference-between-readings":'Add the time difference between "{{inputValueKey}}" readings',"add-time-difference-between-readings-tooltip":'If enabled, the rule node will add the "{{periodValueKey}}" to the outbound message.',"period-value-key":"Period value key","period-value-key-required":"Period value key is required.","general-pattern-hint":"Use ${metadataKey} for value from metadata, $[messageKey] for value from message body.","alarm-severity-pattern-hint":'Use ${metadataKey} for value from metadata, $[messageKey] for value from message body. Alarm severity should be system (CRITICAL, MAJOR etc.)',"output-node-name-hint":"The rule node name corresponds to the relation type of the output message, and it is used to forward messages to other rule nodes in the caller rule chain.","skip-latest-persistence":"Skip latest persistence","use-server-ts":"Use server ts","use-server-ts-hint":"Enable this setting to use the timestamp of the message processing instead of the timestamp from the message. Useful for all sorts of sequential processing if you merge messages from multiple sources (devices, assets, etc).","kv-map-pattern-hint":"All input fields support templatization. Use $[messageKey] to extract value from the message and ${metadataKey} to extract value from the metadata.","shared-scope":"Shared scope","server-scope":"Server scope","client-scope":"Client scope","attribute-type":"Attribute","constant-type":"Constant","time-series-type":"Time-series","message-body-type":"Message","message-metadata-type":"Metadata","argument-tile":"Arguments","no-arguments-prompt":"No arguments configured","result-title":"Result","functions-field-input":"Functions","no-option-found":"No option found","argument-source-field-input":"Source","argument-source-field-input-required":"Argument source is required.","argument-key-field-input":"Key","argument-key-field-input-required":"Argument key is required.","constant-value-field-input":"Constant value","constant-value-field-input-required":"Constant value is required.","attribute-scope-field-input":"Attribute scope","attribute-scope-field-input-required":"Attribute scope os required.","default-value-field-input":"Default value","type-field-input":"Type","type-field-input-required":"Type is required.","key-field-input":"Key","add-entity-type":"Add entity type","add-device-profile":"Add device profile","key-field-input-required":"Key is required.","number-floating-point-field-input":"Number of digits after floating point","number-floating-point-field-input-hint":"Use 0 to convert result to integer","add-to-message-field-input":"Add to message","add-to-metadata-field-input":"Add to metadata","custom-expression-field-input":"Mathematical Expression","custom-expression-field-input-required":"Mathematical expression is required","custom-expression-field-input-hint":"Specify a mathematical expression to evaluate. Default expression demonstrates how to transform Fahrenheit to Celsius","retained-message":"Retained","attributes-mapping":"Attributes mapping","latest-telemetry-mapping":"Latest telemetry mapping","add-mapped-attribute-to":"Add mapped attributes to","add-mapped-latest-telemetry-to":"Add mapped latest telemetry to","add-mapped-fields-to":"Add mapped fields to","add-selected-details-to":"Add selected details to","clear-selected-types":"Clear selected types","clear-selected-details":"Clear selected details","clear-selected-fields":"Clear selected fields","clear-selected-keys":"Clear selected keys","geofence-configuration":"Geofence configuration","coordinate-field-names":"Coordinate field names","coordinate-field-hint":"Rule node tries to retrieve the specified fields from the message. If they are not present, it will look them up in the metadata.","fetch-credentials-to":"Fetch credentials to","add-originator-attributes-to":"Add originator attributes to","originator-attributes":"Originator attributes","fetch-latest-telemetry-with-timestamp":"Fetch latest telemetry with timestamp","fetch-latest-telemetry-with-timestamp-tooltip":'If selected, latest telemetry values will be added to the outbound metadata with timestamp, e.g: "{{latestTsKeyName}}": "{"ts":1574329385897, "value":42}"',"tell-failure":"Tell failure if any of the attributes are missing","tell-failure-tooltip":'If at least one selected key doesn\'t exist the outbound message will report "Failure".',"created-time":"Created time","chip-help":"Press 'Enter' to complete {{inputName}} input. \nPress 'Backspace' to delete {{inputName}}. \nMultiple values supported.",detail:"detail","field-name":"field name","device-profile":"device profile","entity-type":"entity type","message-type":"message type","timeseries-key":"timeseries key",type:"Type","first-name":"First name","last-name":"Last name",label:"Label","originator-fields-mapping":"Originator fields mapping","add-mapped-originator-fields-to":"Add mapped originator fields to",fields:"Fields","skip-empty-fields":"Skip empty fields","skip-empty-fields-tooltip":"Fields with empty values will not be added to the output message/output metadata.","fetch-interval":"Fetch interval","fetch-strategy":"Fetch strategy","fetch-timeseries-from-to":"Fetch timeseries from {{startInterval}} {{startIntervalTimeUnit}} ago to {{endInterval}} {{endIntervalTimeUnit}} ago.","fetch-timeseries-from-to-invalid":'Fetch timeseries invalid ("Interval start" should be less than "Interval end").',"use-metadata-dynamic-interval-tooltip":"If selected, the rule node will use dynamic interval start and end based on the message and metadata patterns.","all-mode-hint":'If selected fetch mode "All" rule node will retrieve telemetry from the fetch interval with configurable query parameters.',"first-mode-hint":'If selected fetch mode "First" rule node will retrieve the closest telemetry to the fetch interval\'s start.',"last-mode-hint":'If selected fetch mode "Last" rule node will retrieve the closest telemetry to the fetch interval\'s end.',ascending:"Ascending",descending:"Descending",min:"Min",max:"Max",average:"Average",sum:"Sum",count:"Count",none:"None","last-level-relation-tooltip":"If selected, the rule node will search related entities only on the level set in the max relation level.","last-level-device-relation-tooltip":"If selected, the rule node will search related devices only on the level set in the max relation level.","data-to-fetch":"Data to fetch","mapping-of-customers":"Mapping of customer's","map-fields-required":"All mapping fields are required.",attributes:"Attributes","related-device-attributes":"Related device attributes","add-selected-attributes-to":"Add selected attributes to","device-profiles":"Device profiles","mapping-of-tenant":"Mapping of tenant's","add-attribute-key":"Add attribute key","message-template":"Message template","message-template-required":"Message template is required","use-system-slack-settings":"Use system slack settings","slack-api-token":"Slack API token","slack-api-token-required":"Slack API token is required","keys-mapping":"keys mapping","add-key":"Add key",recipients:"Recipients","message-subject-and-content":"Message subject and content","template-rules-hint":"Both input fields support templatization. Use $[messageKey] to extract value from the message and ${metadataKey} to extract value from the metadata.","originator-customer-desc":"Use customer of incoming message originator as new originator.","originator-tenant-desc":"Use current tenant as new originator.","originator-related-entity-desc":"Use related entity as new originator. Lookup based on configured relation type and direction.","originator-alarm-originator-desc":"Use alarm originator as new originator. Only if incoming message originator is alarm entity.","originator-entity-by-name-pattern-desc":"Use entity fetched from DB as new originator. Lookup based on entity type and specified name pattern.","email-from-template-hint":"Use $[messageKey] to extract value from the message and ${metadataKey} to extract value from the metadata.","recipients-block-main-hint":"Comma-separated address list. All input fields support templatization. Use $[messageKey] to extract value from the message and ${metadataKey} to extract value from the metadata."},"key-val":{key:"Key",value:"Value","see-examples":"See examples.","remove-entry":"Remove entry","remove-mapping-entry":"Remove mapping entry","add-mapping-entry":"Add mapping","add-entry":"Add entry","copy-key-values-from":"Copy key-values from","delete-key-values":"Delete key-values","delete-key-values-from":"Delete key-values from","at-least-one-key-error":"At least one key should be selected.","unique-key-value-pair-error":"'{{keyText}}' must be different from the '{{valText}}'!"},"mail-body-type":{"plain-text":"Plain text",html:"HTML",dynamic:"Dynamic","use-body-type-template":"Use body type template","plain-text-description":"Simple, unformatted text with no special styling or formating.","html-text-description":"Allows you to use HTML tags for formatting, links and images in your mai body.","dynamic-text-description":"Allows to use Plain Text or HTML body type dynamically based on templatization feature.","after-template-evaluation-hint":"After template evaluation value should be true for HTML, and false for Plain text."}}},!0)}(e)}}e("RuleNodeCoreConfigModule",Kr),Kr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Kr,deps:[{token:Z.TranslateService}],target:t.ɵɵFactoryTarget.NgModule}),Kr.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.10",ngImport:t,type:Kr,declarations:[dt],imports:[$,M],exports:[Hn,Lr,nr,gr,Rr,Br,dt]}),Kr.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Kr,imports:[$,M,Hn,Lr,nr,gr,Rr,Br]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Kr,decorators:[{type:c,args:[{declarations:[dt],imports:[$,M],exports:[Hn,Lr,nr,gr,Rr,Br,dt]}]}],ctorParameters:function(){return[{type:Z.TranslateService}]}})}}}));//# sourceMappingURL=rulenode-core-config.js.map From 83815dce301766165ca0700d7a7683fa5ce34b78 Mon Sep 17 00:00:00 2001 From: YevhenBondarenko Date: Mon, 8 Jan 2024 16:50:47 +0100 Subject: [PATCH 053/179] set default device conncectivity params from yml for install --- .../DefaultSystemDataLoaderService.java | 48 ++----------------- .../DeviceConnectivityConfiguration.java | 3 +- 2 files changed, 7 insertions(+), 44 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/service/install/DefaultSystemDataLoaderService.java b/application/src/main/java/org/thingsboard/server/service/install/DefaultSystemDataLoaderService.java index 63771f8165..7fea98e7dc 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/DefaultSystemDataLoaderService.java +++ b/application/src/main/java/org/thingsboard/server/service/install/DefaultSystemDataLoaderService.java @@ -85,6 +85,7 @@ import org.thingsboard.server.common.data.tenant.profile.TenantProfileData; import org.thingsboard.server.common.data.tenant.profile.TenantProfileQueueConfiguration; import org.thingsboard.server.dao.attributes.AttributesService; import org.thingsboard.server.dao.customer.CustomerService; +import org.thingsboard.server.dao.device.DeviceConnectivityConfiguration; import org.thingsboard.server.dao.device.DeviceCredentialsService; import org.thingsboard.server.dao.device.DeviceProfileService; import org.thingsboard.server.dao.device.DeviceService; @@ -169,6 +170,9 @@ public class DefaultSystemDataLoaderService implements SystemDataLoaderService { @Autowired private TimeseriesService tsService; + @Autowired + private DeviceConnectivityConfiguration connectivityConfiguration; + @Value("${state.persistToTelemetry:false}") @Getter private boolean persistActivityToTelemetry; @@ -260,7 +264,6 @@ public class DefaultSystemDataLoaderService implements SystemDataLoaderService { ObjectNode node = JacksonUtil.newObjectNode(); node.put("baseUrl", "http://localhost:8080"); node.put("prohibitDifferentUrl", false); - node.set("connectivity", createDeviceConnectivityConfiguration()); generalSettings.setJsonValue(node); adminSettingsService.saveAdminSettings(TenantId.SYS_TENANT_ID, generalSettings); @@ -285,51 +288,10 @@ public class DefaultSystemDataLoaderService implements SystemDataLoaderService { AdminSettings connectivitySettings = new AdminSettings(); connectivitySettings.setTenantId(TenantId.SYS_TENANT_ID); connectivitySettings.setKey("connectivity"); - connectivitySettings.setJsonValue(createDeviceConnectivityConfiguration()); + connectivitySettings.setJsonValue(JacksonUtil.valueToTree(connectivityConfiguration.getConnectivity())); adminSettingsService.saveAdminSettings(TenantId.SYS_TENANT_ID, connectivitySettings); } - private ObjectNode createDeviceConnectivityConfiguration() { - ObjectNode config = JacksonUtil.newObjectNode(); - - ObjectNode http = JacksonUtil.newObjectNode(); - http.put("enabled", true); - http.put("host", ""); - http.put("port", 8080); - config.set("http", http); - - ObjectNode https = JacksonUtil.newObjectNode(); - https.put("enabled", false); - https.put("host", ""); - https.put("port", 443); - config.set("https", https); - - ObjectNode mqtt = JacksonUtil.newObjectNode(); - mqtt.put("enabled", true); - mqtt.put("host", ""); - mqtt.put("port", 1883); - config.set("mqtt", mqtt); - - ObjectNode mqtts = JacksonUtil.newObjectNode(); - mqtts.put("enabled", false); - mqtts.put("host", ""); - mqtts.put("port", 8883); - config.set("mqtts", mqtts); - - ObjectNode coap = JacksonUtil.newObjectNode(); - coap.put("enabled", true); - coap.put("host", ""); - coap.put("port", 5683); - config.set("coap", coap); - - ObjectNode coaps = JacksonUtil.newObjectNode(); - coaps.put("enabled", false); - coaps.put("host", ""); - coaps.put("port", 5684); - config.set("coaps", coaps); - return config; - } - @Override public void createRandomJwtSettings() throws Exception { jwtSettingsService.createRandomJwtSettings(); diff --git a/dao/src/main/java/org/thingsboard/server/dao/device/DeviceConnectivityConfiguration.java b/dao/src/main/java/org/thingsboard/server/dao/device/DeviceConnectivityConfiguration.java index df55eee2e4..3e40450035 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/device/DeviceConnectivityConfiguration.java +++ b/dao/src/main/java/org/thingsboard/server/dao/device/DeviceConnectivityConfiguration.java @@ -18,14 +18,15 @@ package org.thingsboard.server.dao.device; import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Profile; import java.util.HashMap; import java.util.Map; +@Profile("install") @Configuration @ConfigurationProperties(prefix = "device") @Data -@Deprecated(since = "3.6.1") public class DeviceConnectivityConfiguration { private Map connectivity = new HashMap<>(); From f7fc127e3662501cd048e710926180391dd7b22e Mon Sep 17 00:00:00 2001 From: Igor Kulikov Date: Mon, 8 Jan 2024 19:34:07 +0200 Subject: [PATCH 054/179] UI: Implement bar chart with labels widget. Improve echarts initialization. Improve timewindow component to set preferred aggregation interval for selected timewindow. Fix data aggregator to schedule interval with maximum allowed setTimeout delay. --- .../json/system/widget_bundles/charts.json | 2 +- .../widget_types/bar_chart_with_labels.json | 20 +- ui-ngx/src/app/core/api/data-aggregator.ts | 6 +- .../basic/basic-widget-config.module.ts | 12 +- ...rt-with-labels-basic-config.component.html | 248 ++++++++++++++ ...hart-with-labels-basic-config.component.ts | 323 ++++++++++++++++++ .../doughnut-basic-config.component.html | 16 +- .../chart/doughnut-basic-config.component.ts | 8 +- .../range-chart-basic-config.component.html | 14 +- ...ignal-strength-basic-config.component.html | 10 +- .../bar-chart-with-labels-widget.component.ts | 309 +++++++---------- .../bar-chart-with-labels-widget.models.ts | 19 +- .../lib/chart/doughnut-widget.component.ts | 22 +- .../lib/chart/doughnut-widget.models.ts | 23 +- .../widget/lib/chart/echarts-widget.models.ts | 214 ++++++++++++ .../lib/chart/range-chart-widget.component.ts | 127 +------ .../lib/chart/range-chart-widget.models.ts | 16 +- ...with-labels-widget-settings.component.html | 150 ++++++++ ...t-with-labels-widget-settings.component.ts | 170 +++++++++ .../doughnut-widget-settings.component.html | 16 +- .../doughnut-widget-settings.component.ts | 13 +- ...range-chart-widget-settings.component.html | 12 +- .../common/font-settings-panel.component.ts | 13 +- .../common/font-settings.component.ts | 8 +- ...al-strength-widget-settings.component.html | 10 +- .../lib/settings/widget-settings.module.ts | 12 +- .../components/time/timeinterval.component.ts | 12 +- .../assets/locale/locale.constant-en_US.json | 35 +- .../assets/locale/locale.constant-zh_CN.json | 29 +- 29 files changed, 1390 insertions(+), 479 deletions(-) create mode 100644 ui-ngx/src/app/modules/home/components/widget/config/basic/chart/bar-chart-with-labels-basic-config.component.html create mode 100644 ui-ngx/src/app/modules/home/components/widget/config/basic/chart/bar-chart-with-labels-basic-config.component.ts create mode 100644 ui-ngx/src/app/modules/home/components/widget/lib/chart/echarts-widget.models.ts create mode 100644 ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/bar-chart-with-labels-widget-settings.component.html create mode 100644 ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/bar-chart-with-labels-widget-settings.component.ts diff --git a/application/src/main/data/json/system/widget_bundles/charts.json b/application/src/main/data/json/system/widget_bundles/charts.json index 4a3240fdd2..07929028ff 100644 --- a/application/src/main/data/json/system/widget_bundles/charts.json +++ b/application/src/main/data/json/system/widget_bundles/charts.json @@ -11,8 +11,8 @@ "charts.basic_timeseries", "charts.state_chart", "range_chart", - "charts.timeseries_bars_flot", "bar_chart_with_labels", + "charts.timeseries_bars_flot", "cards.aggregated_value_card", "charts.bars", "charts.pie", diff --git a/application/src/main/data/json/system/widget_types/bar_chart_with_labels.json b/application/src/main/data/json/system/widget_types/bar_chart_with_labels.json index 6120c4f1c5..06ee881c0a 100644 --- a/application/src/main/data/json/system/widget_types/bar_chart_with_labels.json +++ b/application/src/main/data/json/system/widget_types/bar_chart_with_labels.json @@ -2,8 +2,8 @@ "fqn": "bar_chart_with_labels", "name": "Bar chart with labels", "deprecated": false, - "image": "tb-image:cmFuZ2VfY2hhcnRfc3lzdGVtX3dpZGdldF9pbWFnZS5wbmc=:IlJhbmdlIGNoYXJ0IiBzeXN0ZW0gd2lkZ2V0IGltYWdl;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAACgCAMAAAB+IdObAAAC/VBMVEX////////8/PwAAAD///////+bsfP+wEzu7u73lkzz8/P1eWTT09PN1emRpeOcsvSxsbGQpeLc3NyXl5epqanjXHPLy8tti+OgoKD/wU26urr29vbts0fnkUf39/fIrYP4l02oqKjJroPl5eWUrPPDw8PCwsLJroSQqfKLpfKDn/HU1NSnu/X/tzD/pwNyku//vD//sB3m5ub2jj98mfB2lfD2hTD/rRPu8v3/3qD1fCD3+f7K1vnnjEf1eh30awSWrvOBnfFkhOLld1n1dRX0cxH/9N/1cVvld1jmjEf2izn/qQry9f2Yr/P/+u/+9u+RpuP82r//yGDdM1D3kEPzWD32gSixwfBWeN//2JDzY0v+vkf/siT+5+RBaNr7x6DbYWXxTC96mPD+7N+VqN35tID2emX3oWD3k0fm6/zc5PvV3vq2xveWrfL+8/Hd3d09ZNr/6b/6vZCPj4/2h3TfQl3bKkjaIUD/ujnxQCL0bwrC0PiWqN5Kbt3/79D6zMqGhob/0n/iUWn0aVH+vUPZGjr/tSuwwvZpiOLR0dH+2I97e3v1dWDkcV3fPVnxSCr/qw+Jo/F/m/GLoum3xOj64uZef+H41NoyW9hdfNbJycnxqLT7x5/4no/nb4P/zXDiVm3hS2TlcV3zXEPyUzj+uTTwRCbkbRB+mOaareN5k+FyjuBHbNw4YNn7xr3/47D70LD5t6zumqjngJH/2I+Ojo7lYnf4oWC+mF7utEj2iDTmfSrxRyrunw/kZwLL1vWWrfS/zPORqfP98fKjt/GGofHv7+/+7erK0umHnuKDm+Lf39/t5d7829bm2dT949Dzt8HqwLFse6r4raDsjJz3lIPopHzGpnT4q3DZVmXSNkvnj0LnjD7mgjbjWzHiSzHwRyrunQXv8/3+9POquOWot+Tu4s3u3b3rzrfUxrHu166boa6coK76uKzTvJvoppv6vpDuyYfdboDmkXH1fGffR2H3oV/kbVnnjkHtrTbOIDTiUiLhUCD/rhTuoROM0RHwAAAABXRSTlMg77MAvxFwlo8AAA5CSURBVHja1JtJaBNRGMfj8scXk8MwSYZxoiFhaC9FEQoRA7YHE6K9iMZ4KIoWcTkpqK3oRVH05HISwX1Db66guF48eHHFBfcFQUUQ933BL6PxZZyZRE2+of4aMhPyWvKb73vzf3nQQL9A/z743+lLGoE+Qlea0JLShVA0mFHFwP9Hn0CgL7QwdERgKnGlmY7QBYgNGwY2lleHBjLSNwAIpdlAFPRIQERBsIjcvDGQEUEimqLq0FFysUR4WLKiG5yQiKGiJGIqIJYCKQEGDhV6wAmJCD3VBDWqCxCmrjeBg+7tK06DkQD8Yd3C2ML1YMM/kY2FWM9GsOGfyLLuWOEg2PBPZMW22JotYMM3kYs9sdjbw2DDN5Eta2KxbQWw4ZtIYRmJrAAbfomsXxgjFq4DF36JXCmQB2eQ+CWybHuMKPAFiU8i61bESqy5Ai58EtnYY4l08wWJTyKHuy2R7d3gwieRnmWkwRok/ogsoc6y4FzI84tYsU4wBwm/iBXrP+i5CC74RcqxTnAu5C0RMypgppQ4lCaIlN6CxnKwUBZZcwhsWN/ZE4CeUA3TiCIiEImjoVCs/6T7MNggkXAk1YIo4lGoCaEDiQQIRRGN4fynaWVu3BRskIjRBJ0sbPtaDRR5fm/1jtWrV+/YsXrH+3uCDRJpDpNI5Me+VlwnMYFG8qYz9IvdZ8AFicQjioKmlC4A0JFeNJSuvBRZuxdcBEAIlGcGkUBDWdIVkuy6DCb4c+TqzpmhED0sipvBBL9IMU8WZToXgAd+kSknQhUs7wQP/CKXd1WK5E88BAv8IvnllSKruO6/7CJzFq0KVbJ2ClhgF9nbFbLRdQ4ssIss6LSLFJ+BBXaRYinWZ9LPT3YyBQmviIx19iCpS2QOanK1GCJ4g6R+kQVLUIvO5SE7+SLqgkWkmEcNptwP/c4i1AeDyIGu3VNqDSn+DyL5zp3VZ66M9Zm9WeTcfVpwVJvvtliXInNQBwwiFHU1UkHGOvcaRYqYKoSiAc0mEs2KwB8wZRFF3apdVa8vuRIzfRRZaiAiVMPUDOiq+KN9rQO7an/jo1h3cIJTxCgJIB5FWMR1wBSoTdGax/ku75LIWJ/pU0WEoRr4y32tS1/GjB4zevSYu9eEJ6/vjh5DY8pPNJ6ePl8SPARIIBqZr0ZKFQHiEUATtUXGHh87dtSosaPu7DkrvDh+ZxQNGVt6EHQsne15IngIgKCKGIaigaCDjppMXxz8SW6G55j2oAu58eDBEkGCZExYmCZqc6Qt+JOOHDzYRGOcZPeDgX/OkczEYLJ8iafCnWQ6SNA4G21T8Y9wiGzKyk/WkYE77bN/OPRmkcyx2s2yn2R7u8h4muqybTpa4casScEKkr1SZFbaPn/Hw4VMa9CNzAz8Exwi09sn2q71MbeSXKCquTGpF4lMbfutXxa7lORFeZAcm+xtInTvtZN2KUlrR4VE76zI1Jw9G4h2R0lkrCftKpNmwZ2qic8i0pp2XOtJrQ7brDSoHJ5MH/H6s+NQBQYRucySzHaUJFlhaxPyFMnMgycsIu9ss9irYXJyHtmF0h6tNa69FZ5wiIyjj+hWkun2hs86FX5WJAlXxufavXuLQ2Rqm3s8XIdExrq9raqsAzAvk/XuLQ6RTIcVCcnfS5IdB4kj1muLJI+lPXuLQ4SWWbUTm2I9+bci6dbZXr3FIkLLLHdm58ZV9Elb0FMk7T71KHfq6i1LZG6LQEJrAehovZA4cm62vffleZssiYx15xJlYsZjrlsLhDoo/9dbSjU0s8mAoqlV9rWut5UFHCoTqSQy1r1wisgaUm/VJ6LGof/Y12pW4zoQ9hJxLLNsRtlfJdmU/WsRus3V2VsBEIZm29fyZFMu6E0HlUTG+l+KpDvKi896RDQDKO9r6YDqua91+/iQKuwpb9btue096NYp4capD9Z7Z+va1zJ1VY0rYSoLoWtzI/AQefRgsIOj8vTjSWHx9KRzkDx7IFx4/ONXvr2sT0TTNBEPt8AirCXgwYSVA4hBA0rIM8mIkSixdfKAKgyDC/u+Wu8NHQ4XGp4j32kvYxWFgSiKVsOkVlnyVrARbJYJM1XID6QJWKQT/Qm7VAFBLLbKH1hZ2/iBq6s4WW/MDle8oCHeIeT47ry85MlW96pKyvy8zlntWcNA9rtfb5nMwXoDSOZ0W4Ik211hs7zoxhS5guQKZatbTRdgvQHEVfp/mSZp8yJ60QXSLC82kS0GZF30Acj9u7K9pF0gdaE1kS0SRIyWW0AQA+Mm8OtzkGOqNZEtDgSiT6qoFWhz63OQrXeAlM5v2HBh1dK1AtmDENkiQdwWk0SoE6SxmsgWB5KlQAAnLMg80ZrIFgdiDlw9EOSI/TD1NpmtOg8EqQstDAaudhlcfLHytnDZsqdAkNIE3St6ISBy8Gu5bM2TDEBCxiwuZfIMxNiz+VK21imAhIxZLBOAwF5n+9Z+FQiysp0DCfMkWW169jqbLVN9B4FkTeBtC5yBjyAL11oqTLbyRIeBWMO2KRSClDv9YrYy1wKZDM6f6HKcdIxZ0Hx7qiD35Pn/ua8iprpafLZK40GieBaf39PH0fBjOIUxC6YsXrtSPShZepfrW27rQT4HaqhmIxVHavoF67oKIFz/NY8gdeNn/tBs4evM6Q4SqdHlOAzovcKOKQACl6eytXB/QeLLMR7/kGoFK27DQDQXixzKTgVljxswKo6NwVBsCDgH5wMM/QbfNt18QU495Zz8RdkfyLEsLXT30OveSy+99Bs6ltWVlfHKMnoklhTNyPM0T5ITEtx8uNh7tYbt841vJyL0h4ep2qLfAj7/J/Lm7Y1Mxnv869a18bvWz3O4CBFRtJCIojAKQyyxjkVb7fqlTYTG2IVX7A/bZgc0wzq2n6O5icVza412yhvvc/4zn4Izuv+dBQrX7+aqlDw0kS9PV/xK4yO+OOftZ5xjo6tiwVWdKztdtl0vHY98buK+HUXZ8M7h6XEKjx/36PZ79BxZZRWTAEZBesaxFIGB24KOU2dlYMHWbB4SdLkbJXK3kfewRu1D5NNpYNR8H1ggSrO5dCKSVO7Bu1iK5GKivjOKWFg1su43y4y5EFnn03IBY927JCDzSbzq3KKtQ3YwUtpGCKNEkmU/CphIhHrAJZFGSDtpqCv52hJSbAyRHhkinY0mhAJ8clKZRH5lQwOARVvbhmWrPi/hQiSJjbmSF2dIB5KRJiDC0IBxbaUxO/XytSqYA5FtQe7hvXtlZO8kQ5naosfBMe1pZuNCRMSvSgd0050hECLVctiRaEsHbsoTYkLEkhAfgNG4JHISxMGureSBsf4iaXZAiVA5GsGAKvxOeOPUvs3IGFRbdG43697SH8/IqvCJWGvQbBcC8VVd4vw131hY5lYvkn3SOXybWRNCFzjVip0INVkqPMjrbsAEtLbo3NZyD2/656nEzJaQyvvJBEhiRmHVVir3KL1IyqymRKgTjdV/HwbHzwe1VSa7rnOzV0skZ5QI3bAnhEfU502tLsrBvRcky1QdQ0dKxJ4Qd4CfF32Wp09+epH8q+56WqSG4Wj98yCHlQ1JiCGBQhk6KONpQBD04pxH8DZ7moN4WfbgwF5d8Kh4c0XWb+Dfo2cRVARvfgdP+iH8pdlprKGtioudRztN8vq68zYv/ZPD9OKF1Ej+S4dUvbj9j68jsd4zqmhNs7V3uT7C5SshNVSMRgouHTOqBOe05ZKFB6qOR0KiThDbjWylNxpxkFx7VGeZjLAJrFjPaxUMogwPVPGovbeNrcZI8IeR206ylV7XfHdtN67Y62hJKAZZleKw+pP4n8BASrN16UPkbtwK/+1ohCuAjxpG8nCX34u/vW1Mm1IyZqvlNHp5dz1xEXvEiurXwiRCeaxpe/3LlzA/4xcqERqzNjdpJaZiq6Jv99TxZ2B9MWkKCgJRtTBUaLlZ0YF/+Zj9hMcviKlnmF48Di3rb+DHiFRqyykuQHBcWRD2vn8799/x/Ond27dp8bh79+mnJkctX2M9w4AxP7h/vsbOrMkdnT9/NI/1QRvBbCcaWS2a3MGTJ9Ha0I0slrWPJwdo4nDn4LCuDN3IfFln69UCTbxbrt7WlaEbidmarXZ/NXm0ipXBG6mz9epZwv08+gdvpM7W692EO3wfy4M3ss7WzrOUercXy8M3sliFDnmbUnNEDN8IZSs996YYvpGQreUC3dgAIz5bs94O2QAjPluvDtGDDTBC2Zod7aIHm2BksaJzbx82wch8+XoPfdgEI5jN0IuNMLJYoB/BCJNghpcYG+RGFQ6Dwhz9ODZSSIwFJLh1xTTMa93Z+m1o3cWWJyR98KBZ90a0Xs9r5fTxx/j4uYt9cELSq3mznnHFbDJBlx5y8MgAYe29CUXLgMAFhE72yjF4ZPBQcMcvdGSqMHmgcm/ojqAPR5RgDV1OznNrJlTUI6BEA3csMOGFI6kvpVJq1O1SoZRulzI+SqRdp1/B3wC2sN7dwwmsQM6Q534hWK6hRZVEte/8dsowBVglHVN9jK3SS8tKGtRuLUUuVYdUAO1SmSORdhkJ40VURsy+s4IZWzizfqWo1utdlOa0LTTXtI+K0ikXJFWGWTEqtGxKuVDtUlsY1ioV+7xMpL9rRAluBZ+CT41TiEYs84dkXPi/5YzjWkTpFh95KTPHUh6lYJapdinLmWmVagvjEunvGgGXgjNYIZSORuwEBMWclE6CGZgiSicY8Upa3hNcoJgKE6Vjy/dHHVLIVqkoyVkqzU6hFYrW0dgb4XBvxMgKRVtWH3LrnlJUo1VIioNkGPP4bbhvAFNUEUxyYh66WloRrdKy4JN2qeEGqTQ7i3+EPGnoZLvJvItlSMnTWbb57wJH9RLtM9lpbDpOnc3O/ACb/i1NA1ABvwAAAABJRU5ErkJggg==", - "description": "Displays changes to time-series data over time visualized with color ranges — for example, temperature or humidity readings.", + "image": "tb-image:QmFyLWNoYXJ0LXdpdGgtbGFiZWxzLnN2Zw==:IkJhciBjaGFydCB3aXRoIGxhYmVscyIgc3lzdGVtIHdpZGdldCBpbWFnZQ==;data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMDEiIGhlaWdodD0iMTYwIiBmaWxsPSJub25lIj48cGF0aCBmaWxsPSIjMDAwIiBmaWxsLW9wYWNpdHk9Ii41IiBkPSJNMi44IDQuM1YxMGgtLjdWNS4ybC0xLjQuNXYtLjZsMi0uOGguMVptNS45IDIuNHYuOWwtLjEgMS4yLS40LjdjLS4yLjItLjMuNC0uNi40YTIgMiAwIDAgMS0uNy4ybC0uNi0uMWMtLjIgMC0uNC0uMS0uNS0uMy0uMiAwLS4zLS4yLS40LS40bC0uMi0uOC0uMS0xdi0uOGwuMS0xLjIuNC0uN2MuMS0uMi4zLS40LjUtLjRsLjgtLjIuNi4xYTEuNCAxLjQgMCAwIDEgLjkuN2wuMi43djFabS0uNyAxVjUuOWwtLjItLjVhMSAxIDAgMCAwLS4yLS4zbC0uMy0uMmExIDEgMCAwIDAtLjQgMCAxIDEgMCAwIDAtLjUgMGwtLjMuMy0uMi42djIuNmwuMS41LjIuMy4zLjJoLjlsLjMtLjMuMi0uNnYtLjhabTUuMy0xdjIuMWwtLjUuN2MtLjEuMi0uMy40LS41LjRhMiAyIDAgMCAxLS44LjJMMTEgMTBjLS4yIDAtLjMtLjEtLjUtLjNsLS4zLS40LS4zLS44di0zbC40LS43Yy4yLS4yLjQtLjQuNi0uNGwuNy0uMi42LjFhMS40IDEuNCAwIDAgMSAxIC43bC4xLjcuMSAxWm0tLjcgMVY1LjlsLS4yLS41YTEgMSAwIDAgMC0uMi0uM2wtLjMtLjJhMSAxIDAgMCAwLS40IDAgMSAxIDAgMCAwLS40IDBjLS4yIDAtLjMuMi0uNC4zbC0uMi42djIuNmwuMS41LjMuM2MwIC4xLjEuMi4zLjJoLjhsLjMtLjMuMi0uNi4xLS44Wm0xLjctMnYtLjNjMC0uMiAwLS40LjItLjYgMC0uMi4yLS4zLjQtLjRsLjYtLjJjLjMgMCAuNSAwIC42LjJsLjQuNC4yLjZ2LjNjMCAuMiAwIC40LS4yLjYgMCAuMi0uMi4zLS40LjRsLS42LjJjLS4yIDAtLjQgMC0uNi0uMmExIDEgMCAwIDEtLjQtLjRsLS4yLS42Wm0uNi0uM1Y2bC4zLjMuMy4xaC40TDE2IDZWNS4xYS42LjYgMCAwIDAtLjYtLjQuNi42IDAgMCAwLS41LjRsLS4xLjNaTTE3IDl2LS4zYzAtLjIgMC0uNC4yLS42IDAtLjIuMi0uMy40LS40bC42LS4yYy4yIDAgLjQgMCAuNi4ybC40LjQuMS42VjlsLS4xLjZjMCAuMi0uMi4zLS40LjRsLS42LjJjLS4zIDAtLjUgMC0uNi0uMi0uMiAwLS4zLS4yLS40LS40bC0uMi0uNlptLjYtLjN2LjdsLjIuMi40LjFoLjNsLjItLjMuMS0uNHYtLjZhLjYuNiAwIDAgMC0uNi0uNC42LjYgMCAwIDAtLjYuNHYuM1ptLjgtMy41LTIuOCA0LjUtLjQtLjNMMTggNWwuNC4yWk02IDM2YzAgLjQgMCAuNy0uMiAxbC0uNi41LTEgLjJjLS4zIDAtLjYgMC0uOS0uMi0uMi0uMS0uNS0uMy0uNi0uNi0uMi0uMi0uMy0uNS0uMy0uOGExLjUgMS41IDAgMCAxIDEuMS0xLjVsLjctLjFjLjQgMCAuNyAwIDEgLjIuMi4xLjUuMy42LjYuMi4yLjMuNS4zLjhabS0uNyAwLS4xLS41YTEgMSAwIDAgMC0uNC0uNGwtLjYtLjEtLjUuMWExIDEgMCAwIDAtLjQuNGwtLjEuNXYuNmwuNS40aDEuMWwuNC0uNC4xLS42Wm0uNi0yLjZjMCAuMyAwIC41LS4yLjctLjEuMy0uMy40LS42LjZsLS44LjJhMiAyIDAgMCAxLTEtLjJjLS4yLS4yLS40LS4zLS41LS42LS4yLS4yLS4yLS40LS4yLS43IDAtLjMgMC0uNi4yLS45LjEtLjIuMy0uNC42LS41bC44LS4yIDEgLjIuNS41Yy4yLjMuMi42LjIuOVptLS43IDAtLjEtLjVjLS4xLS4xLS4yLS4zLS40LS4zYTEgMSAwIDAgMC0uNS0uMiAxIDEgMCAwIDAtLjUuMWwtLjMuNC0uMS41LjEuNWMwIC4yLjIuMy40LjRoLjlsLjQtLjQuMS0uNVptNS41Ljl2LjlsLS4xIDEuMS0uNC44Yy0uMi4yLS4zLjQtLjYuNGEyIDIgMCAwIDEtLjcuMmwtLjYtLjFjLS4yIDAtLjQtLjEtLjUtLjMtLjIgMC0uMy0uMi0uNC0uNGwtLjItLjgtLjEtMXYtLjhsLjEtMS4yLjQtLjdjLjEtLjIuMy0uNC41LS40bC44LS4yLjYuMWExLjQgMS40IDAgMCAxIC45LjdsLjIuN3YxWm0tLjcgMXYtMS44bC0uMi0uNWExIDEgMCAwIDAtLjItLjNsLS4zLS4yYTEgMSAwIDAgMC0uNCAwIDEgMSAwIDAgMC0uNSAwbC0uMy4zLS4yLjZWMzZsLjEuNS4yLjMuMy4yaC45bC4zLS4zLjItLjZ2LS44Wm0xLjctMlYzM2wuMS0uNi40LS40LjctLjJjLjIgMCAuNCAwIC42LjJsLjQuNC4xLjZ2LjNsLS4xLjYtLjQuNC0uNi4yYy0uMyAwLS41IDAtLjctLjJhMSAxIDAgMCAxLS40LS40bC0uMS0uNlptLjUtLjN2LjNsLjEuM2MwIC4yLjEuMi4yLjNsLjQuMWguM2wuMi0uNFYzMi43YS42LjYgMCAwIDAtLjUtLjQuNi42IDAgMCAwLS42LjR2LjNabTIuMyAzLjV2LS4zbC4xLS42LjQtLjQuNi0uMmMuMyAwIC41IDAgLjcuMmwuNC40LjEuNnYuM2wtLjEuNi0uNC40LS43LjJjLS4yIDAtLjQgMC0uNi0uMi0uMiAwLS4zLS4yLS40LS40bC0uMS0uNlptLjUtLjN2LjdsLjMuMi4zLjFoLjRjMC0uMi4yLS4yLjItLjN2LTFhLjYuNiAwIDAgMC0uNi0uNC42LjYgMCAwIDAtLjUuNHYuM1ptLjgtMy41TDEzIDM3LjJsLS40LS4zIDIuOC00LjQuNC4yWk01LjIgNTkuNWguMXYuNmMtLjQgMC0uOCAwLTEgLjItLjMuMS0uNS4zLS42LjVhMiAyIDAgMCAwLS40Ljd2Mi4zbC4zLjUuMy4zaC45bC4zLS4zLjItLjRhMS44IDEuOCAwIDAgMCAwLTFjMC0uMiAwLS4zLS4yLS40YTEgMSAwIDAgMC0uNy0uNGwtLjYuMS0uNC40YTEgMSAwIDAgMC0uMi41aC0uNGwuMi0uNy40LS41Yy4xLS4yLjMtLjMuNS0uM2ExLjkgMS45IDAgMCAxIDEuMyAwbC41LjVjLjIuMS4zLjMuMy42QTIuNCAyLjQgMCAwIDEgNiA2NGwtLjMuNi0uNi40LS44LjJjLS4zIDAtLjUgMC0uOC0uMmwtLjUtLjUtLjQtLjd2LTIuM2wuNS0xYy4yLS40LjQtLjYuOC0uOGEzIDMgMCAwIDEgMS4zLS4zWm01LjUgMi40di45bC0uMSAxLjItLjQuN2MtLjIuMi0uMy40LS42LjRhMiAyIDAgMCAxLS43LjJsLS42LS4xYy0uMiAwLS40LS4xLS41LS4zLS4yIDAtLjMtLjItLjQtLjRsLS4yLS44LS4xLTFWNjJsLjEtMS4yLjQtLjdjLjEtLjIuMy0uNC41LS40bC44LS4yLjYuMWExLjQgMS40IDAgMCAxIC45LjdsLjIuN3YxWm0tLjcgMVY2MWwtLjItLjVhMSAxIDAgMCAwLS4yLS4zbC0uMy0uMmExIDEgMCAwIDAtLjQgMCAxIDEgMCAwIDAtLjUgMGwtLjMuMy0uMi42djIuNmwuMS41LjIuMy4zLjJoLjlsLjMtLjMuMi0uNlY2M1ptMS43LTJ2LS4zbC4xLS42LjQtLjQuNy0uMmMuMiAwIC40IDAgLjYuMmwuNC40LjEuNnYuM2wtLjEuNi0uNC40LS42LjJjLS4zIDAtLjUgMC0uNy0uMmExIDEgMCAwIDEtLjQtLjRsLS4xLS42Wm0uNS0uM3YuM2wuMS4zYzAgLjIuMS4yLjIuM2wuNC4xaC4zbC4yLS40VjYwLjNhLjYuNiAwIDAgMC0uNS0uNGwtLjQuMS0uMi4zdi4zWm0yLjMgMy41di0uM2wuMS0uNi40LS40LjYtLjJjLjMgMCAuNSAwIC43LjJsLjQuNC4xLjZ2LjNsLS4xLjYtLjQuNC0uNy4yYy0uMiAwLS40IDAtLjYtLjItLjIgMC0uMy0uMi0uNC0uNGwtLjEtLjZabS41LS4zdi43bC4zLjIuMy4xaC40YzAtLjIuMi0uMi4yLS4zdi0xYS42LjYgMCAwIDAtLjYtLjQuNi42IDAgMCAwLS41LjR2LjNabS44LTMuNUwxMyA2NC44bC0uNC0uMyAyLjgtNC40LjQuMlpNNi4zIDkwLjl2LjZoLTRWOTFsMi41LTRoLjVsLS42IDEuMkwzIDkwLjloMy4zWk01LjUgODd2NS43aC0uN3YtNS43aC43Wm01LjIgMi40di45bC0uMSAxLjEtLjQuOGMtLjIuMi0uMy40LS42LjRhMiAyIDAgMCAxLS43LjJsLS42LS4xYy0uMiAwLS40LS4xLS41LS4zLS4yIDAtLjMtLjItLjQtLjRsLS4yLS44LS4xLTF2LS44bC4xLTEuMi40LS43Yy4xLS4yLjMtLjQuNS0uNEw5IDg3bC42LjFhMS40IDEuNCAwIDAgMSAuOS43bC4yLjd2MVptLS43IDF2LTEuOGwtLjItLjVhMSAxIDAgMCAwLS4yLS4zbC0uMy0uMmExIDEgMCAwIDAtLjQgMCAxIDEgMCAwIDAtLjUgMGwtLjMuMy0uMi42djIuNmwuMS41LjIuMy4zLjJoLjlsLjMtLjMuMi0uNnYtLjhabTEuNy0ydi0uM2wuMS0uNi40LS40LjctLjJjLjIgMCAuNCAwIC42LjJsLjQuNC4xLjZ2LjNsLS4xLjYtLjQuNC0uNi4yYy0uMyAwLS41IDAtLjctLjJhMSAxIDAgMCAxLS40LS40bC0uMS0uNlptLjUtLjN2LjNsLjEuM2MwIC4yLjEuMi4yLjNsLjQuMWguM2wuMi0uNFY4OGEuNi42IDAgMCAwLS41LS40bC0uNC4xLS4yLjN2LjNabTIuMyAzLjV2LS4zbC4xLS42LjQtLjQuNi0uMmMuMyAwIC41IDAgLjcuMmwuNC40LjEuNnYuM2wtLjEuNi0uNC40LS43LjJjLS4yIDAtLjQgMC0uNi0uMi0uMiAwLS4zLS4yLS40LS40bC0uMS0uNlptLjUtLjN2LjdsLjMuMi4zLjFoLjRjMC0uMi4yLS4yLjItLjN2LTFhLjYuNiAwIDAgMC0uNi0uNC42LjYgMCAwIDAtLjUuNHYuM1ptLjgtMy41TDEzIDkyLjRsLS40LS4zIDIuOC00LjQuNC4yWk02LjIgMTE5Ljh2LjZIMi41di0uNWwxLjgtMiAuNi0uNy4yLS41LjEtLjUtLjEtLjUtLjMtLjNhMSAxIDAgMCAwLS42LS4yYy0uMiAwLS40IDAtLjYuMmExIDEgMCAwIDAtLjQuNGwtLjEuNmgtLjdjMC0uMyAwLS42LjItLjkuMS0uMy4zLS41LjYtLjZhMiAyIDAgMCAxIDEtLjNsMSAuMmMuMi4yLjQuMy41LjYuMi4yLjIuNC4yLjh2LjVsLS4zLjVhNy44IDcuOCAwIDAgMS0uOCAxbC0xLjUgMS42aDIuOVptNC41LTIuN3YuOWwtLjEgMS4yLS40LjdjLS4yLjItLjMuNC0uNi40YTIgMiAwIDAgMS0uNy4ybC0uNi0uMWMtLjIgMC0uNC0uMS0uNS0uMy0uMiAwLS4zLS4yLS40LS40bC0uMi0uOC0uMS0xdi0uOGwuMS0xLjIuNC0uN2MuMS0uMi4zLS40LjUtLjRsLjgtLjIuNi4xYTEuNCAxLjQgMCAwIDEgLjkuN2wuMi43djFabS0uNyAxdi0xLjhsLS4yLS41YTEgMSAwIDAgMC0uMi0uM2wtLjMtLjJhMSAxIDAgMCAwLS40IDAgMSAxIDAgMCAwLS41IDBsLS4zLjMtLjIuNnYyLjZsLjEuNS4yLjMuMy4yaC45bC4zLS4zLjItLjZ2LS44Wm0xLjctMnYtLjNsLjEtLjYuNC0uNC43LS4yYy4yIDAgLjQgMCAuNi4ybC40LjQuMS42di4zbC0uMS42LS40LjQtLjYuMmMtLjMgMC0uNSAwLS43LS4yYTEgMSAwIDAgMS0uNC0uNGwtLjEtLjZabS41LS4zdi4zbC4xLjNjMCAuMi4xLjIuMi4zbC40LjFoLjNsLjItLjRWMTE1LjVhLjYuNiAwIDAgMC0uNS0uNC42LjYgMCAwIDAtLjYuNHYuM1ptMi4zIDMuNXYtLjNsLjEtLjYuNC0uNC42LS4yYy4zIDAgLjUgMCAuNy4ybC40LjQuMS42di4zbC0uMS42LS40LjQtLjcuMmMtLjIgMC0uNCAwLS42LS4yLS4yIDAtLjMtLjItLjQtLjRsLS4xLS42Wm0uNS0uM3YuN2wuMy4yLjMuMWguNGMwLS4yLjItLjIuMi0uM3YtMWEuNi42IDAgMCAwLS42LS40LjYuNiAwIDAgMC0uNS40di4zWm0uOC0zLjVMMTMgMTIwbC0uNC0uMyAyLjgtNC40LjQuMlpNOC41IDE0NC43djIuMWwtLjQuN2MtLjIuMi0uNC40LS42LjRhMiAyIDAgMCAxLS44LjJsLS42LS4xLS41LS4zLS4zLS40LS4zLS44di0zbC40LS43Yy4yLS4yLjQtLjQuNi0uNGwuNy0uMi43LjFhMS40IDEuNCAwIDAgMSAuOC43bC4zLjd2MVptLS43IDF2LTEuOGwtLjItLjVhMSAxIDAgMCAwLS4yLS4zbC0uMy0uMmExIDEgMCAwIDAtLjQgMCAxIDEgMCAwIDAtLjQgMGwtLjQuMy0uMi42djIuNmwuMi41YzAgLjEgMCAuMi4yLjNsLjMuMmguOGwuMy0uMy4zLS42di0uOFptMS44LTJ2LS4zbC4xLS42YzAtLjIuMi0uMy40LS40bC42LS4yYy4zIDAgLjUgMCAuNi4yLjIuMS40LjIuNC40bC4yLjZ2LjNjMCAuMiAwIC40LS4yLjYgMCAuMi0uMi4zLS40LjRsLS42LjJjLS4yIDAtLjQgMC0uNi0uMmExIDEgMCAwIDEtLjQtLjRsLS4xLS42Wm0uNS0uM3YuNmwuMy4zLjMuMWguNGwuMi0uNFYxNDMuMWEuNi42IDAgMCAwLS42LS40LjYuNiAwIDAgMC0uNS40bC0uMS4zWm0yLjIgMy41di0uM2MwLS4yIDAtLjQuMi0uNiAwLS4yLjItLjMuNC0uNGwuNi0uMmMuMiAwIC40IDAgLjYuMmwuNC40LjIuNnYuM2MwIC4yIDAgLjQtLjIuNiAwIC4yLS4yLjMtLjQuNGwtLjYuMmMtLjIgMC0uNSAwLS42LS4yLS4yIDAtLjMtLjItLjQtLjRsLS4yLS42Wm0uNi0uM3YuN2wuMi4yLjQuMWguM2wuMy0uM3YtMWEuNi42IDAgMCAwLS42LS40LjYuNiAwIDAgMC0uNi40di4zWm0uOC0zLjUtMi44IDQuNS0uNC0uMyAyLjgtNC40LjQuMloiLz48cGF0aCBzdHJva2U9IiMwMDAiIHN0cm9rZS1saW5lY2FwPSJzcXVhcmUiIHN0cm9rZS1vcGFjaXR5PSIuMSIgc3Ryb2tlLXdpZHRoPSIuNCIgZD0iTTI0LjIgNi44aDE3NS42TTI0LjIgMzQuNmgxNzUuNk0yNC4yIDYyLjRoMTc1LjZNMjQuMiA5MC4yaDE3NS42TTI0LjIgMTE4aDE3NS42Ii8+PHBhdGggc3Ryb2tlPSIjMDAwIiBzdHJva2UtbGluZWNhcD0ic3F1YXJlIiBzdHJva2Utb3BhY2l0eT0iLjUiIHN0cm9rZS13aWR0aD0iLjQiIGQ9Ik0yNC4yIDE0NS44aDE3NS42Ii8+PHBhdGggZmlsbD0iIzdEOEVGRiIgZD0iTTMwIDI1LjVoMTh2MTIwSDMweiIvPjxwYXRoIGZpbGw9IiMwMDAiIGZpbGwtb3BhY2l0eT0iLjkiIGQ9Ik00MC40IDEzNS40Yy40IDAgLjcgMCAxIC4ybC41LjcuMiAxYzAgLjMgMCAuNi0uMi45LS4xLjMtLjMuNS0uNi43bC0uOS4yYTEuNSAxLjUgMCAwIDEtMS0uNWwtLjQtLjYtLjEtLjhjMC0uMyAwLS43LjItMWwuNS0uNmMuMy0uMi41LS4yLjgtLjJabTAgLjlhMSAxIDAgMCAwLS41LjFsLS4zLjMtLjEuNXYuNWMuMS4yLjMuMy40LjNsLjUuMmMuMiAwIC40IDAgLjUtLjJsLjMtLjMuMS0uNXYtLjVsLS40LS4zYTEgMSAwIDAgMC0uNS0uMVptLTIuNi0uOGMuMyAwIC41IDAgLjguMmwuNS42LjIgMWMwIC4zIDAgLjYtLjIuOGwtLjUuNy0uOC4yYy0uMyAwLS42LS4xLS44LS4zLS4zLS4xLS41LS4zLS42LS42bC0uMi0uOS4yLS45LjYtLjYuOC0uMlptMCAxYTEgMSAwIDAgMC0uNCAwIC43LjcgMCAwIDAtLjQuN3YuNWwuNC4yLjQuMWguNWwuMy0uMy4xLS41LS4xLS40LS4zLS4zYTEgMSAwIDAgMC0uNSAwWm0xLjYtMy0uMi43LTIuOS0uM3YtM2guOHYyLjJsMS40LjJhMS44IDEuOCAwIDAgMS0uMi0xbC4xLS43YzAtLjIuMi0uNC40LS41LjEtLjIuMy0uMy42LS4zYTIuNSAyLjUgMCAwIDEgMS41IDBsLjYuMy40LjYuMi44LS4xLjctLjMuNmExLjYgMS42IDAgMCAxLTEuMi42di0xbC40LS4xYy4yIDAgLjMtLjIuMy0uM2wuMS0uNXYtLjRsLS4zLS4zYTEgMSAwIDAgMC0uNC0uMiAxLjggMS44IDAgMCAwLS45IDAgMSAxIDAgMCAwLS40LjJsLS4yLjR2LjlsLjMuM1oiLz48cGF0aCBmaWxsPSIjMDAwIiBmaWxsLW9wYWNpdHk9Ii41IiBkPSJNMzguOCAxMjMuOGguNnYzaC0uNnYtM1ptLTIuNSAzSDQydi43aC01Ljd2LS43Wm0wLTMuNkg0MnYuN2gtNS43di0uN1ptNC43LTRoLTMuMnYtLjdINDJ2LjdoLTFabS0uOSAwdi0uNGwuOC4xLjYuMy40LjUuMi44LS4xLjVhMS4xIDEuMSAwIDAgMS0uOC44SDM3Ljh2LS43SDQxbC4zLS4yLjEtLjN2LS4ybC0uMS0uOGExIDEgMCAwIDAtLjUtLjRoLS43Wm0tMS41LTIuNkg0MnYuN2gtNC4ydi0uNmguOFptMS4xLjJ2LjNsLS44LS4xYTIgMiAwIDAgMS0uNi0uM2wtLjUtLjYtLjEtLjd2LS42YTEuMSAxLjEgMCAwIDEgLjgtLjdINDJ2LjZoLTIuOGExIDEgMCAwIDAtLjUuMWwtLjMuNC0uMS40LjEuNi4zLjMuNS4yaC41Wm0tLjQtMi44LjIuNS0uNy0uMS0uNi0uMy0uNC0uNi0uMS0uN3YtLjZsLjQtLjQuNC0uM0g0MnYuNmgtMi44bC0uNS4xYy0uMi4xLS4zLjItLjMuNGExLjMgMS4zIDAgMCAwIDAgLjlsLjIuMy4zLjJoLjRabS0xLjUtNC42SDQydi44aC00LjJ2LS44Wm0tMS4xLjhoLS4zbC0uMi0uNGMwLS4xIDAtLjIuMi0uM2wuMy0uMWguMmwuMi40YzAgLjEgMCAuMi0uMi4zbC0uMi4xWm00LjUtNC43SDM2di0uN2g2di43aC0uOFptLTEuMyAyLjlhMyAzIDAgMCAxLTEtLjFsLS42LS40LS40LS41Yy0uMi0uMi0uMi0uNS0uMi0uN2wuMS0uNy40LS41Yy4yLS4xLjQtLjMuNy0uM2wuOC0uMmguNGMuMyAwIC42IDAgLjguMi4zIDAgLjUuMi42LjNsLjQuNWExLjcgMS43IDAgMCAxIDAgMS40YzAgLjItLjIuNC0uNC41bC0uNy40YTMgMyAwIDAgMS0uOSAwWm0wLS44aC42bC41LS4yYy4yLS4xLjMtLjIuMy0uNGwuMi0uNWMwLS4yIDAtLjQtLjItLjZsLS40LS4zLS41LS4zaC0xbC0uNC4yLS4zLjJhMSAxIDAgMCAwLS4zLjNsLS4xLjUuMS41LjQuNC41LjJoLjZabS0yLjEtNC44SDQydi43aC00LjJ2LS43Wm0tMS4xLjgtLjMtLjEtLjItLjNjMC0uMiAwLS4zLjItLjRoLjVsLjIuNHMwIC4yLS4yLjNoLS4yWm0xLTMuOGguNnYyLjNoLS41di0yLjNabS0xIDEuNXYtLjdINDFsLjMtLjEuMS0uMnYtLjJhMS4yIDEuMiAwIDAgMCAwLS4zaC42djFsLS40LjRoLTQuOVptNC45LTMuNi0zLjgtMS4ydi0uOGw0LjkgMS43YTIuNyAyLjcgMCAwIDEgLjYuNCAxLjIgMS4yIDAgMCAxIC40Ljl2LjRINDNhMS43IDEuNyAwIDAgMCAwLS43bC0uMy0uMi0uNC0uMi0uOC0uM1ptLTMuOC44IDMuMy0xIC43LS4zLjMuNi00LjMgMS41di0uOFoiLz48cGF0aCBmaWxsPSIjRjk2RkZGIiBkPSJNNDggNDguNWgxOHY5N0g0OHoiLz48cGF0aCBmaWxsPSIjMDAwIiBmaWxsLW9wYWNpdHk9Ii45IiBkPSJNNTQuMyAxMzUuM2guNWw1LjIgMi4zdjFsLTUtMi4zdjNoLS43di00Wm0yLjQtNC42aDFjLjQgMCAuNyAwIDEgLjIuNCAwIC42LjIuOC4zLjIuMi40LjQuNC42bC4yLjgtLjEuNmExLjUgMS41IDAgMCAxLS44IDFsLS42LjJoLTNhMiAyIDAgMCAxLS44LS41bC0uNC0uNS0uMi0uOC4xLS42YTEuNSAxLjUgMCAwIDEgLjgtMWwuNi0uMmgxWm0xIDFoLTEuMmE0IDQgMCAwIDAtLjYgMGwtLjQuMS0uMy4yLS4yLjN2LjdsLjMuMy41LjJoMi41bC41LS4xLjMtLjIuMi0uM3YtLjdsLS4zLS4zLS41LS4yYTQgNCAwIDAgMC0uOCAwWiIvPjxwYXRoIGZpbGw9IiMwMDAiIGZpbGwtb3BhY2l0eT0iLjUiIGQ9Ik01OC42IDEyNC41YTEgMSAwIDAgMC0uNCAwbC0uMy4zLS4yLjQtLjIuNi0uMy44LS40LjYtLjQuNGgtLjZhMS40IDEuNCAwIDAgMS0xLjEtLjRjLS4yLS4yLS4zLS40LS4zLS43bC0uMi0uN2MwLS41LjEtLjguMy0xLjEuMS0uMy40LS42LjYtLjcuMy0uMi42LS4yLjktLjJ2LjdsLS42LjFhMSAxIDAgMCAwLS40LjVsLS4xLjd2LjZsLjQuNC41LjFoLjNsLjMtLjMuMi0uNC4yLS42LjMtLjhjLjEtLjMuMi0uNS40LS42LjEtLjIuMy0uMy41LS4zbC42LS4yYy4yIDAgLjQgMCAuNi4yLjIgMCAuMy4yLjUuNGwuMy42YTMgMyAwIDAgMSAwIDEuNmwtLjQuNy0uNS41LS43LjJ2LS44aC41YzAtLjIuMi0uMy4zLS40bC4yLS41YTIuMiAyLjIgMCAwIDAgMC0xLjFsLS40LS41YS44LjggMCAwIDAtLjQtLjFabS0uNy0xLjUtLjktLjFhMiAyIDAgMCAxLS43LS40bC0uNC0uNi0uMi0uOGMwLS4zIDAtLjYuMi0uOCAwLS4yLjItLjQuNC0uNmwuNy0uNC44LS4xaC4xbC45LjEuNy40YTEuOCAxLjggMCAwIDEgLjYgMS40YzAgLjMgMCAuNi0uMi44YTEuOCAxLjggMCAwIDEtMS4xIDFsLS45LjFabTAtLjdoLjZsLjUtLjMuNC0uNHYtMWExIDEgMCAwIDAtLjQtLjRsLS41LS4yLS42LS4xaC0uNmwtLjUuM2ExIDEgMCAwIDAtLjUuOWwuMS41LjQuNC41LjIuNS4xWm0tMi4xLTQuOUg2MHYuOGgtNC4ydi0uOFptLTEuMS44aC0uM2wtLjItLjRjMC0uMiAwLS4zLjItLjNsLjMtLjFoLjJsLjIuNGMwIC4xIDAgLjItLjIuM2wtLjIuMVptLS43LTIuOGg2di44aC02di0uOFptMi42LTRINjB2LjhoLTQuMnYtLjdoLjhabTEuMS4ydi4zSDU3YTIgMiAwIDAgMS0uNi0uNGwtLjUtLjUtLjEtLjh2LS41YTEuMSAxLjEgMCAwIDEgLjgtLjdsLjctLjFINjB2LjdoLTIuOGExIDEgMCAwIDAtLjUuMWwtLjMuMy0uMS41LjEuNWMwIC4yLjIuMy4zLjRsLjUuMmguNVptLS40LTIuNy4yLjVjLS4zIDAtLjUgMC0uNy0uMmwtLjYtLjMtLjQtLjUtLjEtLjd2LS42bC40LS41LjQtLjNINjB2LjdoLTIuOGwtLjUuMWMtLjIgMC0uMy4yLS4zLjNhMS4zIDEuMyAwIDAgMCAwIDFsLjIuMi4zLjJoLjRabS42LTMuNi0uOS0uMWEyIDIgMCAwIDEtLjctLjRsLS40LS42LS4yLS44YzAtLjMgMC0uNi4yLS44IDAtLjMuMi0uNS40LS42bC43LS40LjgtLjFoMWwuNy41YTEuOCAxLjggMCAwIDEgLjYgMS40YzAgLjMgMCAuNS0uMi44YTEuOCAxLjggMCAwIDEtMS4xIDFsLS45LjFabTAtLjcuNi0uMS41LS4yLjQtLjR2LTFhMSAxIDAgMCAwLS40LS40bC0uNS0uMi0uNi0uMWgtLjZsLS41LjNhMSAxIDAgMCAwLS41LjlsLjEuNS40LjQuNS4yaC41Wm0tMi4xLTQuOUg2MHYuN2gtNC4ydi0uN1ptLTEuMS44LS4zLS4xLS4yLS4zYzAtLjIgMC0uMy4yLS40aC41bC4yLjRjMCAuMSAwIC4yLS4yLjNoLS4yWm00LjItNC41LS4zLjEtLjMuMy0uMi42LS4xLjYtLjMuNWExIDEgMCAwIDEtLjguNCAxIDEgMCAwIDEtLjQgMEw1NiA5OGMtLjItLjEtLjItLjMtLjMtLjVhMiAyIDAgMCAxLS4xLS42YzAtLjQgMC0uNy4yLTFsLjUtLjUuNi0uMXYuN2gtLjNsLS4zLjQtLjEuNXYuNGwuMy4zYS42LjYgMCAwIDAgLjUgMGguMmwuMS0uNC4yLS41LjItLjguNC0uNS42LS4yYTEuMSAxLjEgMCAwIDEgMSAuNWwuMi41di42bC0uMSAxLS41LjYtLjcuMnYtLjhsLjUtLjEuMi0uNGExLjUgMS41IDAgMCAwIDAtMWwtLjItLjNoLS4zWm0tMy4xLTMuNWguNXYyLjNoLS41di0yLjNabS0xIDEuNXYtLjdoNC41bC4xLS4ydi0uMmExLjIgMS4yIDAgMCAwIDAtLjRoLjZ2MS4xbC0uNC4zLS43LjFoLTQuMlptNC4yLTVoLTMuMnYtLjdINjB2LjdoLTFabS0uOSAwdi0uNGwuOC4xLjYuMy40LjUuMi44LS4xLjVhMS4xIDEuMSAwIDAgMS0uOC44SDU1LjhWOTFINTlsLjMtLjIuMS0uM3YtLjNsLS4xLS43YTEgMSAwIDAgMC0uNS0uNGgtLjdabS0xLjctMi42SDYwdi44aC00LjJ2LS43aC42Wm0tLjYtMS4zaC42di44bC4zLjMuMy4zaC40bC4yLjMtLjgtLjFhMiAyIDAgMCAxLS41LS4zYy0uMiAwLS40LS4yLS41LS40YTEuMSAxLjEgMCAwIDEgMC0uOVptNC4zLTIuNGMwIC4zIDAgLjYtLjIuOGExLjggMS44IDAgMCAxLTEgMWwtLjkuMkg1OGMtLjQgMC0uNyAwLTEtLjJhMiAyIDAgMCAxLS42LS40IDEuOCAxLjggMCAwIDEtLjQtMmMwLS4zLjItLjUuNC0uNmwuNi0uMy45LS4xaC4zdjMuMWgtLjZ2LTIuNGwtLjYuMWExIDEgMCAwIDAtLjQuMyAxIDEgMCAwIDAtLjIuNiAxIDEgMCAwIDAgLjQuOGwuNS4zaDEuNGwuNS0uMy4zLS40VjgybC0uNS0uNC40LS41LjQuNC4zLjV2LjdaIi8+PHBhdGggZmlsbD0iI0ZGQTM4OSIgZD0iTTY2IDM0LjVoMTh2MTExSDY2eiIvPjxwYXRoIGZpbGw9IiMwMDAiIGZpbGwtb3BhY2l0eT0iLjkiIGQ9Ik03Ni40IDEzNS40Yy40IDAgLjcgMCAxIC4ybC41LjcuMiAxYzAgLjMgMCAuNi0uMi45LS4xLjMtLjMuNS0uNi43bC0uOS4yYTEuNSAxLjUgMCAwIDEtMS0uNWwtLjQtLjYtLjEtLjhjMC0uMyAwLS43LjItMWwuNS0uNmMuMy0uMi41LS4yLjgtLjJabTAgLjlhMSAxIDAgMCAwLS41LjFsLS4zLjMtLjEuNXYuNWMuMS4yLjMuMy40LjNsLjUuMmMuMiAwIC40IDAgLjUtLjJsLjMtLjMuMS0uNXYtLjVsLS40LS4zYTEgMSAwIDAgMC0uNS0uMVptLTIuNi0uOGMuMyAwIC41IDAgLjguMmwuNS42LjIgMWMwIC4zIDAgLjYtLjIuOGwtLjUuNy0uOC4yYy0uMyAwLS42LS4xLS44LS4zLS4zLS4xLS41LS4zLS42LS42bC0uMi0uOS4yLS45LjYtLjYuOC0uMlptMCAxYTEgMSAwIDAgMC0uNCAwIC43LjcgMCAwIDAtLjQuN3YuNWwuNC4yLjQuMWguNWwuMy0uMy4xLS41LS4xLS40LS4zLS4zYTEgMSAwIDAgMC0uNSAwWm0uOS01LjhoMWMuNCAwIC43IDAgMSAuMi40IDAgLjYuMi44LjMuMi4yLjQuNC40LjZsLjIuOC0uMS42YTEuNSAxLjUgMCAwIDEtLjggMWwtLjYuMmgtM2EyIDIgMCAwIDEtLjgtLjVsLS40LS41LS4yLS44LjEtLjZhMS41IDEuNSAwIDAgMSAuOC0xbC42LS4yaDFabTEgMWgtMS4yYTQgNCAwIDAgMC0uNiAwbC0uNC4xLS4zLjItLjIuM3YuN2wuMy4zLjUuMmgyLjVsLjUtLjEuMy0uMi4yLS4zdi0uN2wtLjMtLjMtLjUtLjJhNCA0IDAgMCAwLS44IDBaIi8+PHBhdGggZmlsbD0iIzAwMCIgZmlsbC1vcGFjaXR5PSIuNSIgZD0iTTc3LjQgMTI0aC42djNoLS42di0zWm0tNSAyLjhINzh2LjdoLTUuN3YtLjdabTUuNy01LjNjMCAuMyAwIC42LS4yLjhhMS44IDEuOCAwIDAgMS0xIDFsLS45LjJINzZjLS40IDAtLjcgMC0xLS4yYTIgMiAwIDAgMS0uNi0uNCAxLjggMS44IDAgMCAxLS40LTJjMC0uMy4yLS41LjQtLjZsLjYtLjMuOS0uMWguM3YzLjFoLS42di0yLjRsLS42LjFhMSAxIDAgMCAwLS40LjMgMSAxIDAgMCAwLS4yLjYgMSAxIDAgMCAwIC40LjhsLjUuMi43LjFoLjdsLjUtLjNhMS4yIDEuMiAwIDAgMCAuNC0xYzAtLjIgMC0uNC0uMi0uNmwtLjQtLjQuNC0uNS40LjQuMy41di43Wm0tLjgtNWgtMi42Yy0uMi4xLS4zLjItLjMuNGwtLjEuNXYuNWwuMy4zaC4zdi44YTEgMSAwIDAgMS0uNC0uMWMtLjIgMC0uMy0uMi0uNC0uM2wtLjMtLjZhMiAyIDAgMCAxLS4xLS43YzAtLjMgMC0uNS4yLS44IDAtLjIuMi0uNC40LS41LjItLjIuNS0uMi44LS4yaDIuNGwuNC0uMmguMXYuOGgtLjdabS0xLjktLjFoLjV2LjdsLjEuNS4xLjQuMy4zaC43bC4zLS4zdi0uNGExLjIgMS4yIDAgMCAwLS40LTEgLjcuNyAwIDAgMC0uNC0uMmwuMy0uMy40LjJhMS43IDEuNyAwIDAgMSAuOCAxLjRjMCAuMyAwIC41LS4yLjdsLS40LjUtLjcuMi0uNi0uMS0uNC0uNC0uMy0uNnYtMS42Wm0yLjYtM3YuOGgtNC43Yy0uMyAwLS41IDAtLjctLjItLjMgMC0uNC0uMi0uNS0uNGwtLjItLjhhMiAyIDAgMCAxIDAtLjVoLjd2LjlsLjMuMkg3OFptLTQuMi0uOGguNXYyLjNoLS41di0yLjNabTMuNS00LTMuNS0xdi0uNWguN2wzLjUgMS4ydi40aC0uOFptLTMuNS44IDMuNS0xaC43di40bC00LjIgMS4zdi0uN1ptMy41LTMuNC0zLjUtLjl2LS43bDQuMiAxLjJ2LjVoLS43Wm0tMy41IDEgMy40LTEuMS44LS4xdi40bC0zLjUgMS4yaC0uN3YtLjRabTQuMy01LjFjMCAuMyAwIC41LS4yLjhhMS44IDEuOCAwIDAgMS0xIDFsLS45LjFINzZsLTEtLjFhMiAyIDAgMCAxLS42LS41IDEuOCAxLjggMCAwIDEtLjQtMmMwLS4yLjItLjQuNC0uNmwuNi0uM2gxLjJ2M2gtLjZWMTAxbC0uNi4yYTEgMSAwIDAgMC0uNC4zIDEgMSAwIDAgMC0uMi42IDEgMSAwIDAgMCAuNC44bC41LjJoMS40bC41LS4yLjMtLjR2LTEuMmwtLjUtLjUuNC0uNC40LjNjMCAuMi4yLjMuMy41di44Wm0tNC4zLTQuM2guNXYyLjJoLS41di0yLjJabS0xIDEuNXYtLjhoNC41bC4xLS4yVjk4YTEuMiAxLjIgMCAwIDAgMC0uNGguNnYxLjFjLS4xLjEtLjIuMy0uNC4zbC0uNy4yaC00LjJabTEuOS0zLjJINzh2LjhoLTQuMlY5NmguOVptMSAuMnYuM2wtLjgtLjFhMiAyIDAgMCAxLS42LS40IDEuNiAxLjYgMCAwIDEtLjYtMS4yVjk0bC4zLS40LjUtLjNINzh2LjdoLTMuM2wtLjMuMy0uMS41YTEgMSAwIDAgMCAuNC45IDEuNiAxLjYgMCAwIDAgMSAuM1ptMi40LTUuN2MwIC4zIDAgLjYtLjIuOGExLjggMS44IDAgMCAxLTEgMWwtLjkuMkg3NmMtLjQgMC0uNyAwLTEtLjJhMiAyIDAgMCAxLS42LS40IDEuOCAxLjggMCAwIDEtLjQtMmMwLS4zLjItLjUuNC0uNmwuNi0uMy45LS4xaC4zdjMuMWgtLjZ2LTIuNGwtLjYuMWExIDEgMCAwIDAtLjQuMyAxIDEgMCAwIDAtLjIuNiAxIDEgMCAwIDAgLjQuOGwuNS4zaDEuNGwuNS0uMy4zLS40di0xLjJsLS41LS40LjQtLjUuNC40LjMuNXYuN1ptLTEuMi01aC0uM2wtLjMuNC0uMi42LS4xLjYtLjMuNWExIDEgMCAwIDEtLjguNCAxIDEgMCAwIDEtLjQgMGwtLjQtLjRjLS4yLS4xLS4yLS4zLS4zLS41YTIgMiAwIDAgMS0uMS0uNmMwLS40IDAtLjcuMi0xIDAtLjIuMy0uMy41LS41bC42LS4ydi44aC0uM2wtLjMuNC0uMS41di40bC4zLjNhLjYuNiAwIDAgMCAuNSAwbC4yLS4xLjEtLjMuMi0uNS4yLS44LjQtLjUuNi0uMmExLjEgMS4xIDAgMCAxIDEgLjRsLjIuNnYuNmwtLjEgMS0uNS42LS43LjJ2LS44bC41LS4xLjItLjRhMS41IDEuNSAwIDAgMCAwLTFsLS4yLS4zaC0uM1ptMC00LjItLjMuMS0uMy4zLS4yLjYtLjEuNi0uMy41YTEgMSAwIDAgMS0uOC40IDEgMSAwIDAgMS0uNCAwbC0uNC0uNGMtLjItLjEtLjItLjMtLjMtLjVhMiAyIDAgMCAxLS4xLS42YzAtLjQgMC0uNy4yLS45IDAtLjIuMy0uNC41LS42bC42LS4xdi43aC0uM2wtLjMuNC0uMS41di41bC4zLjJhLjYuNiAwIDAgMCAuNSAwaC4ybC4xLS40LjItLjUuMi0uOC40LS41LjYtLjJhMS4xIDEuMSAwIDAgMSAxIC41bC4yLjV2LjZsLS4xIDEtLjUuNi0uNy4yVjgzbC41LS4xLjItLjRhMS41IDEuNSAwIDAgMCAwLTFsLS4yLS4zaC0uM1oiLz48cGF0aCBmaWxsPSIjRkZFRDUzIiBkPSJNODQgNTYuNWgxOHY4OUg4NHoiLz48cGF0aCBmaWxsPSIjMDAwIiBmaWxsLW9wYWNpdHk9Ii45IiBkPSJNOTAuMyAxMzYuMmguN2wuMi44YTEuNiAxLjYgMCAwIDAgMSAxbC44LjFoMS41bC41LS4zLjItLjMuMS0uNHYtLjNsLS4zLS4zLS40LS4yYTEuNyAxLjcgMCAwIDAtLjkgMGMtLjEgMC0uMyAwLS40LjJsLS4yLjItLjEuNC4xLjYuNC4zLjQuMi0uMS4zYTIgMiAwIDAgMS0uNy0uMWwtLjUtLjQtLjMtLjVWMTM2LjJsLjUtLjUuNi0uM2EyLjUgMi41IDAgMCAxIDEuNSAwYy4yIDAgLjQuMi42LjQuMi4xLjMuMy40LjZsLjIuN2MwIC4zIDAgLjYtLjIuOC0uMS4zLS4zLjUtLjUuNmwtLjcuNC0uOC4yaC0uNGwtMS4zLS4yYTMgMyAwIDAgMS0xLS41Yy0uMy0uMi0uNS0uNS0uNy0uOWEzIDMgMCAwIDEtLjItMS4zWm01LTUuNmguN3YzLjhoLS42bC0yLTEuOC0uNy0uNWEyIDIgMCAwIDAtLjQtLjIgMS4yIDEuMiAwIDAgMC0uOSAwbC0uMy4zLS4xLjQuMS42LjQuMy41LjF2MWwtLjktLjMtLjYtLjZhMiAyIDAgMCAxLS4zLTFsLjItMWMuMi0uMy4zLS41LjYtLjYuMi0uMi41LS4zLjgtLjNsLjUuMS42LjMuNS4zLjUuNSAxLjMgMS4ydi0yLjZaIi8+PHBhdGggZmlsbD0iIzAwMCIgZmlsbC1vcGFjaXR5PSIuNSIgZD0iTTk0LjIgMTI0di0uN2MuNCAwIC43LjIgMSAuNC4yLjEuNS40LjYuNy4yLjMuMy42LjMgMS4xIDAgLjMgMCAuNi0uMiAxYTIgMiAwIDAgMS0uNS42Yy0uMy4yLS41LjQtLjkuNWwtMSAuMWgtLjZsLTEuMS0uMS0uOC0uNWEyIDIgMCAwIDEtLjYtLjdsLS4yLTFjMC0uNC4xLS44LjMtMSAuMS0uNC40LS42LjYtLjdsMS0uNHYuOGwtLjYuMmExIDEgMCAwIDAtLjUuNGwtLjEuNy4xLjdjMCAuMi4yLjQuNC41bC42LjNoMi4yYy4zIDAgLjUtLjIuNy0uM2wuNC0uNC4yLS43YzAtLjMgMC0uNi0uMi0uOGExIDEgMCAwIDAtLjQtLjRsLS43LS4yWm0tNC4yLTIuNGg2di43aC02di0uN1ptNC0xaC0uMmMtLjMgMC0uNSAwLS44LS4yYTIgMiAwIDAgMS0uNy0uNGMtLjItLjEtLjMtLjMtLjQtLjYtLjItLjItLjItLjUtLjItLjggMC0uMyAwLS41LjItLjggMC0uMi4yLS40LjQtLjZsLjctLjRoMS44bC43LjRhMS44IDEuOCAwIDAgMSAuNiAxLjRjMCAuMyAwIC42LS4yLjhhMS44IDEuOCAwIDAgMS0xLjEgMWwtLjkuMlptLS4yLS44aC43Yy4yIDAgLjQtLjIuNS0uMy4yIDAgLjMtLjIuNC0uM1YxMThhMSAxIDAgMCAwLS40LS40bC0uNS0uMmgtMS4ybC0uNS4yYTEgMSAwIDAgMC0uNS45bC4xLjYuNC4zLjUuM2guNVptMS4yLTYuNmgtMy4ydi0uOEg5NnYuN2gtMVptLS45LS4ydi0uM2wuOC4xLjYuMy40LjUuMi44LS4xLjVhMS4xIDEuMSAwIDAgMS0uOC44SDkxLjh2LS43SDk1bC4zLS4yLjEtLjJ2LS4zbC0uMS0uOGExIDEgMCAwIDAtLjUtLjNsLS43LS4yWm0xLTQuNEg5MHYtLjdoNnYuN2gtLjhabS0xLjIgMi45YTMgMyAwIDAgMS0xLS4ybC0uNi0uMy0uNC0uNWMtLjItLjItLjItLjUtLjItLjdsLjEtLjcuNC0uNWMuMi0uMS40LS4zLjctLjNsLjgtLjJoLjRjLjMgMCAuNiAwIC44LjIuMyAwIC41LjIuNi4zbC40LjVhMS43IDEuNyAwIDAgMSAwIDEuNGMwIC4yLS4yLjQtLjQuNS0uMi4yLS41LjMtLjcuM2EzIDMgMCAwIDEtLjkuMlptMC0uOGguNmwuNS0uMmMuMi0uMS4zLS4yLjMtLjRsLjItLjVjMC0uMiAwLS40LS4yLS42bC0uNC0uMy0uNS0uM2gtMWEyIDIgMCAwIDAtLjQuMmwtLjMuMmExIDEgMCAwIDAtLjMuM2wtLjEuNS4xLjUuNC40LjUuMmguNlptMS42LTcuNy0uMS0uNWExIDEgMCAwIDAtLjMtLjMuOC44IDAgMCAwLS40LS4ydi0uN2wuNy4zYTEuNyAxLjcgMCAwIDEgLjcgMS40YzAgLjMgMCAuNi0uMi44LS4xLjMtLjMuNC0uNS42YTIgMiAwIDAgMS0uNi40SDkzYTIgMiAwIDAgMS0uNy0uNGwtLjQtLjZhMiAyIDAgMCAxLS4yLS44YzAtLjMgMC0uNi4yLS45bC41LS42LjgtLjJ2LjdhMSAxIDAgMCAwLS40LjEgMSAxIDAgMCAwLS41LjhsLjEuNi40LjQuNS4yaDEuMmwuNS0uMi40LS40di0uNVptLTEuNi0yLjQtLjktLjFhMiAyIDAgMCAxLS43LS40bC0uNC0uNmMtLjItLjItLjItLjUtLjItLjggMC0uMyAwLS42LjItLjggMC0uMi4yLS40LjQtLjZsLjctLjQuOC0uMWguMWwuOS4xLjcuNGExLjggMS44IDAgMCAxIC42IDEuNGMwIC4zIDAgLjYtLjIuOGExLjggMS44IDAgMCAxLTEuMSAxbC0uOS4xWm0wLS43aC42bC41LS4zYy4yIDAgLjMtLjIuNC0uNHYtMWExIDEgMCAwIDAtLjQtLjRsLS41LS4yaC0xLjJsLS41LjJhMSAxIDAgMCAwLS41LjlsLjEuNS40LjQuNS4yLjUuMVptMS40LTUuMy0zLjUtMS4ydi0uN2w0LjIgMS41di41bC0uNy0uMVptLTMuNSAxIDMuNi0xLjIuNi0uMXYuNWwtNC4yIDEuNXYtLjdabTQuMy01LjNjMCAuMiAwIC41LS4yLjhhMS44IDEuOCAwIDAgMS0xIDFsLS45LjFIOTRjLS40IDAtLjcgMC0xLS4yYTIgMiAwIDAgMS0uNi0uNCAxLjggMS44IDAgMCAxLS40LTJjMC0uMy4yLS40LjQtLjZsLjYtLjNoMS4ydjNoLS42di0yLjRsLS42LjFhMSAxIDAgMCAwLS40LjQgMSAxIDAgMCAwLS4yLjUgMSAxIDAgMCAwIC40LjlsLjUuMmgxLjRjLjIgMCAuMy0uMi41LS4zbC4zLS40di0xLjFsLS41LS41LjQtLjQuNC4zYzAgLjIuMi4zLjMuNXYuOFpNOTIuNCA4N0g5NnYuN2gtNC4yVjg3aC42Wm0tLjctMS4zaC43di44bC4zLjMuMy4yLjQuMS4yLjJoLS44YTIgMiAwIDAgMS0uNS0uM2wtLjUtLjRhMS4xIDEuMSAwIDAgMSAwLTFaIi8+PHBhdGggZmlsbD0iIzdEOEVGRiIgZD0iTTEyMyAzNi41aDE4djEwOWgtMTh6Ii8+PHBhdGggZmlsbD0iIzAwMCIgZmlsbC1vcGFjaXR5PSIuOSIgZD0iTTEyOS4zIDEzNS4zaC41bDUuMiAyLjN2MWwtNS0yLjN2M2gtLjd2LTRabTUtMS42di0uMWMwLS40IDAtLjctLjItLjlhMS40IDEuNCAwIDAgMC0xLS45aC0yLjNsLS41LjItLjIuMy0uMS40di4zbC4zLjMuNC4yYTEuOCAxLjggMCAwIDAgMSAwYy4xIDAgLjIgMCAuMy0uMmwuMy0uMi4xLS40YTEgMSAwIDAgMC0uMy0uOCAxLjEgMS4xIDAgMCAwLS43LS4zbC4xLS4zaC42YTEuOCAxLjggMCAwIDEgLjkgMWwuMS42LS4xLjctLjQuNS0uNy4zYTIuNSAyLjUgMCAwIDEtMS40IDAgMiAyIDAgMCAxLS43LS40Yy0uMi0uMS0uMy0uMy0uNC0uNmwtLjItLjdjMC0uNCAwLS42LjItLjlsLjUtLjUuNy0uNCAxLS4xaDEuM2wuOC40LjcuNS41LjguMSAxdi4yaC0uN1oiLz48cGF0aCBmaWxsPSIjMDAwIiBmaWxsLW9wYWNpdHk9Ii41IiBkPSJNMTMxLjggMTIzLjhoLjZ2M2gtLjZ2LTNabS0yLjUgM2g1Ljd2LjdoLTUuN3YtLjdabTAtMy42aDUuN3YuN2gtNS43di0uN1ptNC43LTRoLTMuMnYtLjdoNC4ydi43aC0xWm0tLjkgMHYtLjRsLjguMS42LjMuNC41LjIuOC0uMS41YTEuMSAxLjEgMCAwIDEtLjguOEgxMzAuOHYtLjdoMy4ybC4zLS4yLjEtLjN2LS4ybC0uMS0uOGExIDEgMCAwIDAtLjUtLjRoLS43Wm0tMS41LTIuNmgzLjR2LjdoLTQuMnYtLjZoLjhabTEuMS4ydi4zbC0uOC0uMS0uNi0uMy0uNS0uNi0uMS0uN3YtLjZhMS4xIDEuMSAwIDAgMSAuOC0uN2gzLjV2LjZoLTIuOGExIDEgMCAwIDAtLjUuMWwtLjMuNHYxbC4zLjMuNS4yaC41Wm0tLjQtMi44LjIuNS0uNy0uMS0uNi0uMy0uNC0uNi0uMS0uN3YtLjZsLjQtLjQuNC0uM2gzLjV2LjZoLTIuOGwtLjUuMWMtLjIuMS0uMy4yLS4zLjRhMS4yIDEuMiAwIDAgMCAwIC45bC4yLjNhMSAxIDAgMCAwIC43LjJabS0xLjUtNC42aDQuMnYuOGgtNC4ydi0uOFptLTEuMS44aC0uM2wtLjItLjRjMC0uMSAwLS4yLjItLjNsLjMtLjFoLjJsLjIuNGMwIC4xIDAgLjItLjIuM2wtLjIuMVptNC41LTQuN0gxMjl2LS43aDZ2LjdoLS44Wm0tMS4zIDIuOWEzIDMgMCAwIDEtMS0uMWwtLjYtLjRhMS41IDEuNSAwIDAgMS0uNi0xLjJsLjEtLjcuNC0uNWMuMi0uMS40LS4zLjctLjNsLjgtLjJoLjRjLjMgMCAuNiAwIC44LjIuMyAwIC41LjIuNi4zbC40LjVhMS43IDEuNyAwIDAgMSAwIDEuNGMwIC4yLS4yLjQtLjQuNWwtLjcuNGEzIDMgMCAwIDEtLjkgMFptMC0uOGguNmwuNS0uMmMuMi0uMS4zLS4yLjMtLjRsLjItLjVhMSAxIDAgMCAwLS42LTFsLS41LS4yaC0xbC0uNC4yLS4zLjJhMSAxIDAgMCAwLS4zLjN2MWwuNC40LjUuMmguNlptLTIuMS00LjhoNC4ydi43aC00LjJ2LS43Wm0tMS4xLjgtLjMtLjEtLjItLjNjMC0uMiAwLS4zLjItLjRoLjVsLjIuNHMwIC4yLS4yLjNoLS4yWm0xLTMuOGguNnYyLjNoLS41di0yLjNabS0xIDEuNXYtLjdoNC4zbC4zLS4xLjEtLjJ2LS41aC42YTEuOCAxLjggMCAwIDEgMCAuNXYuNWwtLjQuNGgtNC45Wm00LjktMy42LTMuOC0xLjJ2LS44bDQuOSAxLjdhMi43IDIuNyAwIDAgMSAuNi40bC4zLjRhMSAxIDAgMCAxIDAgLjd2LjJoLS41YTEuOSAxLjkgMCAwIDAgMC0uN2wtLjMtLjItLjQtLjItLjgtLjNabS0zLjguOCAzLjMtMSAuNy0uMy4zLjYtNC4zIDEuNXYtLjhaIi8+PHBhdGggZmlsbD0iI0Y5NkZGRiIgZD0iTTE0MSA3Ny41aDE4djY4aC0xOHoiLz48cGF0aCBmaWxsPSIjMDAwIiBmaWxsLW9wYWNpdHk9Ii45IiBkPSJtMTUwLjQgMTM4LS4yLjgtMi45LS4zdi0zaC44djIuMmwxLjQuMmExLjggMS44IDAgMCAxLS4yLS45bC4xLS43YzAtLjIuMi0uNC40LS42bC42LS4zYTIuNSAyLjUgMCAwIDEgMS41IDBsLjYuMy40LjYuMi44LS4xLjctLjMuNi0uNS40LS43LjJ2LTFoLjRsLjMtLjQuMS0uNXYtLjRsLS4zLS4yYTEgMSAwIDAgMC0uNC0uMiAxLjggMS44IDAgMCAwLTEgMCAxIDEgMCAwIDAtLjMuMmwtLjIuM3YxbC4zLjNabS0uNy03LjNoMWMuNCAwIC43IDAgMSAuMi40IDAgLjYuMi44LjNsLjQuNi4yLjgtLjEuNmExLjUgMS41IDAgMCAxLS44IDFsLS42LjJoLTNhMiAyIDAgMCAxLS44LS41bC0uNC0uNS0uMi0uOC4xLS42YTEuNSAxLjUgMCAwIDEgLjgtMWwuNi0uMmgxWm0xIDFoLTEuMmE0IDQgMCAwIDAtLjYgMGwtLjQuMS0uMy4yLS4yLjN2LjdsLjMuMy41LjJoMi41bC41LS4xLjMtLjIuMi0uM3YtLjdsLS4zLS4zLS41LS4yYTQgNCAwIDAgMC0uOCAwWiIvPjxwYXRoIGZpbGw9IiMwMDAiIGZpbGwtb3BhY2l0eT0iLjUiIGQ9Ik0xNTEuNiAxMjQuNWExIDEgMCAwIDAtLjQgMGwtLjMuMy0uMi40LS4yLjYtLjMuOC0uNC42LS40LjRoLS42YTEuNCAxLjQgMCAwIDEtMS4xLS40Yy0uMi0uMi0uMy0uNC0uMy0uN2wtLjItLjdjMC0uNS4xLS44LjMtMS4xLjEtLjMuNC0uNi42LS43LjMtLjIuNi0uMi45LS4ydi43bC0uNi4xYTEgMSAwIDAgMC0uNC41bC0uMS43di42bC40LjQuNS4xaC4zbC4zLS4zLjItLjQuMi0uNi4zLS44Yy4xLS4zLjItLjUuNC0uNi4xLS4yLjMtLjMuNS0uM2wuNi0uMmMuMiAwIC40IDAgLjYuMi4yIDAgLjMuMi41LjRsLjMuNmEzIDMgMCAwIDEgMCAxLjZsLS40LjctLjUuNS0uNy4ydi0uOGguNWMwLS4yLjItLjMuMy0uNGwuMi0uNWEyLjIgMi4yIDAgMCAwIDAtMS4xbC0uNC0uNWEuOC44IDAgMCAwLS40LS4xWm0tLjctMS41LS45LS4xYTIgMiAwIDAgMS0uNy0uNGwtLjQtLjZjLS4yLS4yLS4yLS41LS4yLS44IDAtLjMgMC0uNi4yLS44IDAtLjIuMi0uNC40LS42bC43LS40LjgtLjFoLjFsLjkuMS43LjRhMS44IDEuOCAwIDAgMSAuNiAxLjRjMCAuMyAwIC42LS4yLjhhMS44IDEuOCAwIDAgMS0xLjEgMWwtLjkuMVptMC0uN2guNmwuNS0uMy40LS40di0xYTEgMSAwIDAgMC0uNC0uNGwtLjUtLjItLjYtLjFoLS42bC0uNS4zYTEgMSAwIDAgMC0uNS45bC4xLjUuNC40LjUuMi41LjFabS0yLjEtNC45aDQuMnYuOGgtNC4ydi0uOFptLTEuMS44aC0uM2wtLjItLjRjMC0uMiAwLS4zLjItLjNsLjMtLjFoLjJsLjIuNGMwIC4xIDAgLjItLjIuM2wtLjIuMVptLS43LTIuOGg2di44aC02di0uOFptMi42LTRoMy40di44aC00LjJ2LS43aC44Wm0xLjEuMnYuM2gtLjhsLS42LS40LS41LS41LS4xLS44di0uNWExLjEgMS4xIDAgMCAxIC44LS43bC43LS4xaDIuOHYuN2gtMi44YTEgMSAwIDAgMC0uNS4xbC0uMy4zdjFjMCAuMi4yLjMuMy40bC41LjJoLjVabS0uNC0yLjcuMi41Yy0uMyAwLS41IDAtLjctLjJsLS42LS4zLS40LS41LS4xLS43di0uNmwuNC0uNS40LS4zaDMuNXYuN2gtMi44bC0uNS4xYy0uMiAwLS4zLjItLjMuM2ExLjIgMS4yIDAgMCAwIDAgMWwuMi4yLjMuMmguNFptLjYtMy42LS45LS4xYTIgMiAwIDAgMS0uNy0uNGwtLjQtLjZjLS4yLS4zLS4yLS41LS4yLS44IDAtLjMgMC0uNi4yLS44IDAtLjMuMi0uNS40LS42bC43LS40LjgtLjFoMWwuNy41YTEuOCAxLjggMCAwIDEgLjYgMS40YzAgLjMgMCAuNS0uMi44YTEuOCAxLjggMCAwIDEtMS4xIDFsLS45LjFabTAtLjcuNi0uMS41LS4yLjQtLjR2LTFhMSAxIDAgMCAwLS40LS40bC0uNS0uMi0uNi0uMWgtLjZsLS41LjNhMSAxIDAgMCAwLS41LjlsLjEuNS40LjQuNS4yaC41Wm0tMi4xLTQuOWg0LjJ2LjdoLTQuMnYtLjdabS0xLjEuOC0uMy0uMS0uMi0uM2MwLS4yIDAtLjMuMi0uNGguNWwuMi40YzAgLjEgMCAuMi0uMi4zaC0uMlptNC4yLTQuNS0uMy4xLS4zLjMtLjIuNi0uMS42YzAgLjItLjIuNC0uMy41YTEgMSAwIDAgMS0uOC40IDEgMSAwIDAgMS0uNCAwbC0uNC0uNGMtLjItLjEtLjItLjMtLjMtLjVhMiAyIDAgMCAxLS4xLS42YzAtLjQgMC0uNy4yLTFsLjUtLjUuNi0uMXYuN2gtLjNsLS4zLjQtLjEuNXYuNGwuMy4zYS42LjYgMCAwIDAgLjUgMGguMmwuMS0uNC4yLS41LjItLjguNC0uNS42LS4yYTEuMSAxLjEgMCAwIDEgMSAuNWwuMi41di42bC0uMSAxLS41LjYtLjcuMnYtLjhsLjUtLjEuMi0uNGExLjUgMS41IDAgMCAwIDAtMWwtLjItLjNoLS4zWm0tMy4xLTMuNWguNXYyLjNoLS41di0yLjNabS0xIDEuNXYtLjdoNC41bC4xLS4yVjkyLjVoLjZhMS44IDEuOCAwIDAgMSAwIC42di41bC0uNC4zLS43LjFoLTQuMlptNC4yLTVoLTMuMnYtLjdoNC4ydi43aC0xWm0tLjkgMHYtLjRsLjguMS42LjMuNC41LjIuOC0uMS41YTEuMSAxLjEgMCAwIDEtLjguOEgxNDguOFY5MWgzLjJsLjMtLjIuMS0uM3YtLjNsLS4xLS43YTEgMSAwIDAgMC0uNS0uNGgtLjdabS0xLjctMi42aDMuNnYuOGgtNC4ydi0uN2guNlptLS43LTEuM2guN3YuOGwuMy4zLjMuM2guNGwuMi4zLS44LS4xYTIgMiAwIDAgMS0uNi0uM2wtLjQtLjRhMS4xIDEuMSAwIDAgMSAwLS45Wm00LjQtMi40YzAgLjMgMCAuNi0uMi44YTEuOCAxLjggMCAwIDEtMSAxbC0uOS4yaC0uMWMtLjQgMC0uNyAwLTEtLjJhMiAyIDAgMCAxLS42LS40IDEuOCAxLjggMCAwIDEtLjYtMS4zYzAtLjMgMC0uNS4yLS44IDAtLjIuMi0uNC40LS41bC42LS4zLjktLjFoLjN2My4xaC0uNnYtMi40bC0uNi4xYTEgMSAwIDAgMC0uNC4zIDEgMSAwIDAgMC0uMi42IDEgMSAwIDAgMCAuNC44bC41LjNoMS40bC41LS4zLjMtLjRWODJsLS41LS40LjQtLjUuNC40LjMuNXYuN1oiLz48cGF0aCBmaWxsPSIjRkZBMzg5IiBkPSJNMTU5IDQ3LjVoMTh2OThoLTE4eiIvPjxwYXRoIGZpbGw9IiMwMDAiIGZpbGwtb3BhY2l0eT0iLjkiIGQ9Ik0xNjUuMyAxMzUuM2guNWw1LjIgMi4zdjFsLTUtMi4zdjNoLS43di00Wm0yLjQtNC42aDFjLjQgMCAuNyAwIDEgLjIuNCAwIC42LjIuOC4zbC40LjYuMi44LS4xLjZhMS41IDEuNSAwIDAgMS0uOCAxbC0uNi4yaC0zYTIgMiAwIDAgMS0uOC0uNWwtLjQtLjUtLjItLjguMS0uNmExLjUgMS41IDAgMCAxIC44LTFsLjYtLjJoMVptMSAxaC0xLjJhNCA0IDAgMCAwLS42IDBsLS40LjEtLjMuMi0uMi4zdi43bC4zLjMuNS4yaDIuNWwuNS0uMS4zLS4yLjItLjN2LS43bC0uMy0uMy0uNS0uMmE0IDQgMCAwIDAtLjggMFoiLz48cGF0aCBmaWxsPSIjMDAwIiBmaWxsLW9wYWNpdHk9Ii41IiBkPSJNMTcwLjQgMTI0aC42djNoLS42di0zWm0tNSAyLjhoNS42di43aC01Ljd2LS43Wm01LjctNS4zYzAgLjMgMCAuNi0uMi44YTEuOCAxLjggMCAwIDEtMSAxbC0uOS4yaC0uMWMtLjQgMC0uNyAwLTEtLjJhMiAyIDAgMCAxLS42LS40IDEuOCAxLjggMCAwIDEtLjQtMmMwLS4zLjItLjUuNC0uNmwuNi0uMy45LS4xaC4zdjMuMWgtLjZ2LTIuNGwtLjYuMWExIDEgMCAwIDAtLjQuMyAxIDEgMCAwIDAtLjIuNiAxIDEgMCAwIDAgLjQuOGwuNS4yLjcuMWguN2wuNS0uMy4zLS40di0xLjJsLS41LS40LjQtLjUuNC40LjMuNXYuN1ptLS44LTVoLTIuNmMtLjIuMS0uMy4yLS4zLjRsLS4xLjV2LjVsLjMuM2guM3YuOGExIDEgMCAwIDEtLjQtLjFjLS4yIDAtLjMtLjItLjQtLjNsLS4zLS42YTIgMiAwIDAgMS0uMS0uN2MwLS4zIDAtLjUuMi0uOCAwLS4yLjItLjQuNC0uNS4yLS4yLjUtLjIuOC0uMmgyLjRsLjQtLjJoLjF2LjhoLS43Wm0tMS45LS4xaC41di43bC4xLjUuMS40LjMuM2guN2wuMy0uM3YtLjRhMS4yIDEuMiAwIDAgMC0uNC0xIC43LjcgMCAwIDAtLjQtLjJsLjMtLjMuNC4yYTEuNyAxLjcgMCAwIDEgLjYgMi4xbC0uNC41LS43LjItLjYtLjEtLjQtLjQtLjMtLjZ2LTEuNlptMi42LTN2LjhoLTQuN2MtLjMgMC0uNSAwLS43LS4yLS4zIDAtLjQtLjItLjUtLjRsLS4yLS44YTIgMiAwIDAgMSAwLS41aC43di45bC4zLjJIMTcxWm0tNC4yLS44aC41djIuM2gtLjV2LTIuM1ptMy40LTQtMy40LTF2LS41aC43bDMuNSAxLjJ2LjRoLS44Wm0tMy40LjggMy41LTFoLjd2LjRsLTQuMiAxLjN2LS43Wm0zLjUtMy40LTMuNS0uOXYtLjdsNC4yIDEuMnYuNWgtLjdabS0zLjUgMSAzLjQtMS4xLjgtLjF2LjRsLTMuNSAxLjJoLS43di0uNFptNC4zLTUuMWMwIC4zIDAgLjUtLjIuOGExLjggMS44IDAgMCAxLTEgMWwtLjkuMWgtLjFsLTEtLjFhMiAyIDAgMCAxLS42LS41IDEuOCAxLjggMCAwIDEtLjQtMmMwLS4yLjItLjQuNC0uNmwuNi0uM2gxLjJ2M2gtLjZWMTAxbC0uNi4yYTEgMSAwIDAgMC0uNC4zIDEgMSAwIDAgMC0uMi42IDEgMSAwIDAgMCAuNC44bC41LjJoMS40bC41LS4yYzAtLjIuMi0uMy4zLS40di0xLjJsLS41LS41LjQtLjQuNC4zYzAgLjIuMi4zLjMuNXYuOFptLTQuMy00LjNoLjV2Mi4yaC0uNXYtMi4yWm0tMSAxLjV2LS44aDQuNWwuMS0uMlY5Ny41aC42YTEuOCAxLjggMCAwIDEgMCAuNnYuNWMtLjEuMS0uMi4zLS40LjNsLS43LjJoLTQuMlptMS45LTMuMmgzLjN2LjhoLTQuMlY5NmguOVptMSAuMnYuM2wtLjgtLjFhMiAyIDAgMCAxLS42LS40IDEuNiAxLjYgMCAwIDEtLjYtMS4yVjk0bC4zLS40LjUtLjNoMy41di43aC0zLjNsLS4zLjN2LjVhMSAxIDAgMCAwIC4zLjkgMS42IDEuNiAwIDAgMCAxIC4zWm0yLjQtNS43YzAgLjMgMCAuNi0uMi44YTEuOCAxLjggMCAwIDEtMSAxbC0uOS4yaC0uMWMtLjQgMC0uNyAwLTEtLjJhMiAyIDAgMCAxLS42LS40IDEuOCAxLjggMCAwIDEtLjYtMS4zYzAtLjMgMC0uNS4yLS44IDAtLjIuMi0uNC40LS41bC42LS4zLjktLjFoLjN2My4xaC0uNnYtMi40bC0uNi4xYTEgMSAwIDAgMC0uNC4zIDEgMSAwIDAgMC0uMi42IDEgMSAwIDAgMCAuNC44bC41LjNoMS40bC41LS4zLjMtLjR2LTEuMmwtLjUtLjQuNC0uNS40LjQuMy41di43Wm0tMS4yLTVoLS4zbC0uMy40LS4yLjYtLjEuNmMwIC4yLS4yLjQtLjMuNWExIDEgMCAwIDEtLjguNCAxIDEgMCAwIDEtLjQgMGwtLjQtLjRjLS4yLS4xLS4yLS4zLS4zLS41YTIgMiAwIDAgMS0uMS0uNmMwLS40IDAtLjcuMi0xIDAtLjIuMy0uMy41LS41bC42LS4ydi44aC0uM2wtLjMuNC0uMS41di40bC4zLjNhLjYuNiAwIDAgMCAuNSAwbC4yLS4xLjEtLjMuMi0uNS4yLS44LjQtLjUuNi0uMmExLjEgMS4xIDAgMCAxIDEgLjRsLjIuNnYuNmwtLjEgMS0uNS42LS43LjJ2LS44bC41LS4xLjItLjRhMS41IDEuNSAwIDAgMCAwLTFsLS4yLS4zaC0uM1ptMC00LjItLjMuMS0uMy4zLS4yLjYtLjEuNmMwIC4yLS4yLjQtLjMuNWExIDEgMCAwIDEtLjguNCAxIDEgMCAwIDEtLjQgMGwtLjQtLjRjLS4yLS4xLS4yLS4zLS4zLS41YTIgMiAwIDAgMS0uMS0uNmMwLS40IDAtLjcuMi0uOSAwLS4yLjMtLjQuNS0uNmwuNi0uMXYuN2gtLjNsLS4zLjQtLjEuNXYuNWwuMy4yYS42LjYgMCAwIDAgLjUgMGguMmwuMS0uNC4yLS41LjItLjguNC0uNS42LS4yYTEuMSAxLjEgMCAwIDEgMSAuNWwuMi41di42bC0uMSAxLS41LjYtLjcuMlY4M2wuNS0uMS4yLS40YTEuNSAxLjUgMCAwIDAgMC0xbC0uMi0uM2gtLjNaIi8+PHBhdGggZmlsbD0iI0ZGRUQ1MyIgZD0iTTE3NyA2Mi41aDE4djgzaC0xOHoiLz48cGF0aCBmaWxsPSIjMDAwIiBmaWxsLW9wYWNpdHk9Ii45IiBkPSJNMTgzLjMgMTM2LjJoLjdsLjIuOGExLjYgMS42IDAgMCAwIDEgMWwuOC4xaDEuNWwuNS0uMy4yLS4zLjEtLjR2LS4zbC0uMy0uMy0uNC0uMmExLjcgMS43IDAgMCAwLS45IDBjLS4xIDAtLjMgMC0uNC4ybC0uMi4yLS4xLjQuMS42LjQuMy40LjItLjEuM2EyIDIgMCAwIDEtLjctLjFsLS41LS40LS4zLS41VjEzNi4ybC41LS41LjYtLjNhMi41IDIuNSAwIDAgMSAxLjUgMGMuMiAwIC40LjIuNi40LjIuMS4zLjMuNC42bC4yLjdjMCAuMyAwIC42LS4yLjgtLjEuMy0uMy41LS41LjZsLS43LjQtLjguMmgtLjRsLTEuMy0uMmEzIDMgMCAwIDEtMS0uNWMtLjMtLjItLjUtLjUtLjctLjlhMyAzIDAgMCAxLS4yLTEuM1ptMi40LTUuNWgxYy40IDAgLjcgMCAxIC4yLjQgMCAuNi4yLjguM2wuNC42LjIuOC0uMS42YTEuNSAxLjUgMCAwIDEtLjggMWwtLjYuMmgtM2EyIDIgMCAwIDEtLjgtLjVsLS40LS41LS4yLS44LjEtLjZhMS41IDEuNSAwIDAgMSAuOC0xbC42LS4yaDFabTEgMWgtMS4yYTQgNCAwIDAgMC0uNiAwbC0uNC4xLS4zLjItLjIuM3YuN2wuMy4zLjUuMmgyLjVsLjUtLjEuMy0uMi4yLS4zdi0uN2wtLjMtLjMtLjUtLjJhNCA0IDAgMCAwLS44IDBaIi8+PHBhdGggZmlsbD0iIzAwMCIgZmlsbC1vcGFjaXR5PSIuNSIgZD0iTTE4Ny4yIDEyNHYtLjdjLjQgMCAuNy4yIDEgLjQuMi4xLjUuNC42LjcuMi4zLjMuNi4zIDEuMSAwIC4zIDAgLjYtLjIgMWEyIDIgMCAwIDEtLjUuNmwtLjkuNS0xIC4xaC0uNmwtMS4xLS4xLS44LS41YTIgMiAwIDAgMS0uNi0uN2wtLjItMWMwLS40LjEtLjguMy0xIC4xLS40LjQtLjYuNi0uN2wxLS40di44bC0uNi4yYTEgMSAwIDAgMC0uNS40bC0uMS43LjEuN2MwIC4yLjIuNC40LjVsLjYuM2gyLjJjLjMgMCAuNS0uMi43LS4zbC40LS40LjItLjdjMC0uMyAwLS42LS4yLS44YTEgMSAwIDAgMC0uNC0uNGwtLjctLjJabS00LjItMi40aDZ2LjdoLTZ2LS43Wm00LTFoLS4yYy0uMyAwLS41IDAtLjgtLjJhMiAyIDAgMCAxLS43LS40Yy0uMi0uMS0uMy0uMy0uNC0uNi0uMi0uMi0uMi0uNS0uMi0uOCAwLS4zIDAtLjUuMi0uOCAwLS4yLjItLjQuNC0uNmwuNy0uNGgxLjhsLjcuNGExLjggMS44IDAgMCAxIC42IDEuNGMwIC4zIDAgLjYtLjIuOGExLjggMS44IDAgMCAxLTEuMSAxbC0uOS4yWm0tLjItLjhoLjdjLjIgMCAuNC0uMi41LS4zLjIgMCAuMy0uMi40LS4zVjExOGExIDEgMCAwIDAtLjQtLjRsLS41LS4yaC0xLjJsLS41LjJhMSAxIDAgMCAwLS41LjlsLjEuNi40LjMuNS4zaC41Wm0xLjItNi42aC0zLjJ2LS44aDQuMnYuN2gtMVptLS45LS4ydi0uM2wuOC4xLjYuMy40LjUuMi44LS4xLjVhMS4xIDEuMSAwIDAgMS0uOC44SDE4NC44di0uN2gzLjJsLjMtLjIuMS0uMnYtLjNsLS4xLS44YTEgMSAwIDAgMC0uNS0uM2wtLjctLjJabTEtNC40SDE4M3YtLjdoNnYuN2gtLjhabS0xLjIgMi45YTMgMyAwIDAgMS0xLS4ybC0uNi0uM2ExLjUgMS41IDAgMCAxLS42LTEuMmwuMS0uNy40LS41Yy4yLS4xLjQtLjMuNy0uM2wuOC0uMmguNGMuMyAwIC42IDAgLjguMi4zIDAgLjUuMi42LjNsLjQuNWExLjcgMS43IDAgMCAxIDAgMS40YzAgLjItLjIuNC0uNC41LS4yLjItLjUuMy0uNy4zYTMgMyAwIDAgMS0uOS4yWm0wLS44aC42bC41LS4yYy4yLS4xLjMtLjIuMy0uNGwuMi0uNWExIDEgMCAwIDAtLjYtMWwtLjUtLjJoLTFhMiAyIDAgMCAwLS40LjJsLS4zLjJhMSAxIDAgMCAwLS40LjhsLjEuNS40LjQuNS4yaC42Wm0xLjYtNy43LS4xLS41YTEgMSAwIDAgMC0uMy0uMy44LjggMCAwIDAtLjQtLjJ2LS43bC43LjNhMS43IDEuNyAwIDAgMSAuNyAxLjRjMCAuMyAwIC42LS4yLjgtLjEuMy0uMy40LS41LjZhMiAyIDAgMCAxLS42LjRIMTg2YTIgMiAwIDAgMS0uNy0uNGwtLjQtLjZhMiAyIDAgMCAxLS4yLS44YzAtLjMgMC0uNi4yLS45bC41LS42LjgtLjJ2LjdhMSAxIDAgMCAwLS40LjEgMSAxIDAgMCAwLS41LjhsLjEuNi40LjQuNS4yaDEuMmwuNS0uMmMuMiAwIC4zLS4yLjQtLjR2LS41Wm0tMS42LTIuNC0uOS0uMWEyIDIgMCAwIDEtLjctLjRsLS40LS42Yy0uMi0uMi0uMi0uNS0uMi0uOCAwLS4zIDAtLjYuMi0uOCAwLS4yLjItLjQuNC0uNmwuNy0uNC44LS4xaC4xbC45LjEuNy40YTEuOCAxLjggMCAwIDEgLjYgMS40YzAgLjMgMCAuNi0uMi44IDAgLjItLjIuNC0uNC42YTIgMiAwIDAgMS0uNy40bC0uOS4xWm0wLS43aC42bC41LS4zYy4yIDAgLjMtLjIuNC0uNHYtMWExIDEgMCAwIDAtLjQtLjRsLS41LS4yaC0xLjJsLS41LjJhMSAxIDAgMCAwLS41LjlsLjEuNS40LjQuNS4yLjUuMVptMS40LTUuMy0zLjUtMS4ydi0uN2w0LjIgMS41di41bC0uNy0uMVptLTMuNSAxIDMuNi0xLjIuNi0uMXYuNWwtNC4yIDEuNXYtLjdabTQuMy01LjNjMCAuMiAwIC41LS4yLjhhMS44IDEuOCAwIDAgMS0xIDFsLS45LjFoLS4xYy0uNCAwLS43IDAtMS0uMmEyIDIgMCAwIDEtLjYtLjQgMS44IDEuOCAwIDAgMS0uNi0xLjNjMC0uMyAwLS41LjItLjcgMC0uMy4yLS40LjQtLjZsLjYtLjNoMS4ydjNoLS42di0yLjRsLS42LjFhMSAxIDAgMCAwLS40LjQgMSAxIDAgMCAwLS4yLjUgMSAxIDAgMCAwIC40LjlsLjUuMmgxLjRjLjIgMCAuMy0uMi41LS4zbC4zLS40di0xLjFsLS41LS41LjQtLjQuNC4zYzAgLjIuMi4zLjMuNXYuOFptLTMuNy0zLjNoMy42di43aC00LjJWODdoLjZabS0uNy0xLjNoLjd2LjhsLjMuMy4zLjIuNC4xLjIuMmgtLjhhMiAyIDAgMCAxLS42LS4zbC0uNC0uNGExLjEgMS4xIDAgMCAxIDAtMVpNNjEuNSAxNTQuM3YtNGguOHY0YzAgLjQgMCAuNy0uMiAxbC0uNy42YTIgMiAwIDAgMS0uOS4yYy0uMyAwLS43IDAtMS0uMmwtLjYtLjUtLjItMWguOHYuNmwuNS40YTEuMyAxLjMgMCAwIDAgMSAwbC40LS40LjEtLjdabTQuNiAxVjE1M2wtLjEtLjRjMC0uMi0uMi0uMy0uMy0uM2ExIDEgMCAwIDAtLjUtLjFoLS41bC0uMy4zLS4xLjNoLS43di0uNGwuNC0uNC42LS4zLjctLjFjLjMgMCAuNSAwIC44LjIuMiAwIC40LjIuNS40LjIuMi4yLjUuMi44djIuNGwuMi40di4xaC0uOHYtLjNsLS4xLS40Wm0uMS0xLjl2LjVoLS43bC0uNS4xLS41LjEtLjIuM3YuN2wuMy4zaC40YTEuMiAxLjIgMCAwIDAgMS0uNGwuMi0uNC4zLjMtLjIuNGExLjcgMS43IDAgMCAxLS44LjdINjQuMmwtLjUtLjVjLS4yLS4yLS4yLS40LS4yLS43bC4xLS42LjQtLjQuNi0uM2gxLjZabTIuNi0uN3YzLjNoLS43di00LjJoLjd2LjlabS0uMSAxaC0uM3YtLjhsLjQtLjZhMS42IDEuNiAwIDAgMSAxLjMtLjZoLjVsLjUuMy4yLjUuMS43djIuOGgtLjd2LTMuM2wtLjQtLjNhMSAxIDAgMCAwLS40IDAgMSAxIDAgMCAwLTEgLjMgMS42IDEuNiAwIDAgMC0uMiAxWk0xNTQgMTUwLjN2NS43aC0uOHYtNS43aC43Wm0yLjMgMi42di42aC0yLjZ2LS42aDIuNlptLjQtMi42di42aC0zdi0uNmgzWm0yLjYgNS44YTEuOCAxLjggMCAwIDEtMS44LTEuMmwtLjItLjl2LS4xYzAtLjQgMC0uNy4yLTFsLjQtLjZhMS44IDEuOCAwIDAgMSAyLS40Yy4zIDAgLjUuMi42LjRsLjMuNi4xLjl2LjNoLTMuMXYtLjZoMi40bC0uMS0uNmExIDEgMCAwIDAtLjMtLjQgMSAxIDAgMCAwLS42LS4yIDEgMSAwIDAgMC0uOC40bC0uMi41LS4xLjd2LjdsLjMuNS40LjNoMS4ybC40LS41LjUuNC0uNC40LS41LjNhMiAyIDAgMCAxLS43IDBabTIuNi02LjFoLjd2NmgtLjd2LTZabTMuNiAzLjktLjEuOS0uMy43LS41LjQtLjcuMmMtLjMgMC0uNiAwLS44LS4yLS4yIDAtLjMtLjItLjUtLjRhMiAyIDAgMCAxLS4zLS42IDQgNCAwIDAgMS0uMi0uOHYtLjRsLjItLjhjMC0uMy4yLS41LjMtLjdsLjUtLjQuNy0uMWMuMyAwIC41IDAgLjguMi4yIDAgLjMuMi41LjRsLjMuNy4xLjlabS0uNyAwdi0uNmwtLjMtLjVhMSAxIDAgMCAwLS44LS41bC0uNS4xYTEgMSAwIDAgMC0uNC4zbC0uMi4zLS4xLjR2MWwuMi41YzAgLjIuMi4zLjQuNGwuNi4yYy4yIDAgLjMgMCAuNS0uMmwuMy0uMy4yLS41di0uNloiLz48L3N2Zz4=", + "description": "Displays changes to time-series data over time visualized with value bars and labels — for example, daily water consumption for the last month.", "descriptor": { "type": "timeseries", "sizeX": 8, @@ -11,20 +11,20 @@ "resources": [], "templateHtml": "\n", "templateCss": ".legend {\n font-size: 13px;\n line-height: 10px;\n}\n\n.legend table { \n border-spacing: 0px;\n border-collapse: separate;\n}\n\n.mouse-events .flot-overlay {\n cursor: crosshair; \n}\n\n", - "controllerScript": "self.onInit = function() {\n self.ctx.$scope.barChartWidget.onInit();\n};\n\nself.onDataUpdated = function() {\n self.ctx.$scope.barChartWidget.onDataUpdated();\n}\n\nself.typeParameters = function() {\n return {\n previewWidth: '80%',\n embedTitlePanel: true,\n hasAdditionalLatestDataKeys: false,\n defaultDataKeysFunction: function() {\n return [{ name: 'temperature', label: 'Temperature', type: 'timeseries' }];\n }\n };\n}\n", + "controllerScript": "self.onInit = function() {\n self.ctx.$scope.barChartWidget.onInit();\n};\n\nself.onDataUpdated = function() {\n self.ctx.$scope.barChartWidget.onDataUpdated();\n}\n\nself.typeParameters = function() {\n return {\n previewWidth: '80%',\n embedTitlePanel: true,\n hasAdditionalLatestDataKeys: false,\n defaultDataKeysFunction: function() {\n return [{ name: 'humidity', label: 'Humidity', type: 'timeseries' }];\n }\n };\n}\n", "settingsSchema": "{}", "dataKeySettingsSchema": "{}", "latestDataKeySettingsSchema": "{}", - "settingsDirective": "", + "settingsDirective": "tb-bar-chart-with-labels-widget-settings", "dataKeySettingsDirective": "", "latestDataKeySettingsDirective": "", - "hasBasicMode": false, - "basicModeDirective": "", - "defaultConfig": "{\"datasources\":[{\"type\":\"function\",\"name\":\"function\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Humidity\",\"color\":\"rgb(125, 142, 255)\",\"settings\":{},\"_hash\":0.8587686344902596,\"funcBody\":\"var value = prevValue + Math.random() * 40 - 20;\\nif (value < 50) {\\n\\tvalue = 50;\\n} else if (value > 80) {\\n\\tvalue = 80;\\n}\\nreturn value;\",\"aggregationType\":null,\"units\":null,\"decimals\":null,\"usePostProcessing\":null,\"postFuncBody\":null},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Soil moisture\",\"color\":\"rgb(249, 111, 255)\",\"settings\":{},\"_hash\":0.9111685461089025,\"funcBody\":\"var value = prevValue + Math.random() * 40 - 20;\\nif (value < 30) {\\n\\tvalue = 30;\\n} else if (value > 90) {\\n\\tvalue = 90;\\n}\\nreturn value;\",\"aggregationType\":null,\"units\":null,\"decimals\":null,\"usePostProcessing\":null,\"postFuncBody\":null},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Leaf wetness\",\"color\":\"rgb(255, 163, 137)\",\"settings\":{},\"_hash\":0.8487533373085416,\"funcBody\":\"var value = prevValue + Math.random() * 40 - 20;\\nif (value < 40) {\\n\\tvalue = 40;\\n} else if (value > 70) {\\n\\tvalue = 70;\\n}\\nreturn value;\",\"aggregationType\":null,\"units\":null,\"decimals\":null,\"usePostProcessing\":null,\"postFuncBody\":null},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Cloud cover\",\"color\":\"#FFED53\",\"settings\":{},\"_hash\":0.7690144858984289,\"funcBody\":\"var value = prevValue + Math.random() * 40 - 20;\\nif (value < 20) {\\n\\tvalue = 20;\\n} else if (value > 60) {\\n\\tvalue = 60;\\n}\\nreturn value;\",\"aggregationType\":null,\"units\":null,\"decimals\":null,\"usePostProcessing\":null,\"postFuncBody\":null}],\"alarmFilterConfig\":{\"statusList\":[\"ACTIVE\"]}}],\"timewindow\":{\"hideInterval\":false,\"hideLastInterval\":false,\"hideQuickInterval\":false,\"hideAggregation\":false,\"hideAggInterval\":false,\"hideTimezone\":false,\"selectedTab\":1,\"history\":{\"historyType\":2,\"timewindowMs\":60000,\"interval\":2221714000,\"fixedTimewindow\":{\"startTimeMs\":1703599035699,\"endTimeMs\":1703685435699},\"quickInterval\":\"CURRENT_HALF_YEAR\"},\"aggregation\":{\"type\":\"AVG\",\"limit\":25000},\"timezone\":null},\"showTitle\":true,\"backgroundColor\":\"rgba(0, 0, 0, 0)\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"0px\",\"settings\":{},\"title\":\"Bar chart with labels\",\"dropShadow\":true,\"enableFullscreen\":true,\"titleStyle\":null,\"mobileHeight\":null,\"configMode\":\"basic\",\"actions\":{},\"showTitleIcon\":false,\"titleIcon\":\"thermostat\",\"iconColor\":\"#1F6BDD\",\"useDashboardTimewindow\":false,\"displayTimewindow\":true,\"titleFont\":{\"size\":16,\"sizeUnit\":\"px\",\"family\":\"Roboto\",\"weight\":\"500\",\"style\":\"normal\",\"lineHeight\":\"24px\"},\"titleColor\":\"rgba(0, 0, 0, 0.87)\",\"titleTooltip\":\"\",\"widgetStyle\":{},\"widgetCss\":\"\",\"pageSize\":1024,\"units\":\"%\",\"decimals\":0,\"noDataDisplayMessage\":\"\",\"timewindowStyle\":{\"showIcon\":false,\"iconSize\":\"24px\",\"icon\":null,\"iconPosition\":\"left\",\"font\":{\"size\":12,\"sizeUnit\":\"px\",\"family\":\"Roboto\",\"weight\":\"400\",\"style\":\"normal\",\"lineHeight\":\"16px\"},\"color\":\"rgba(0, 0, 0, 0.38)\",\"displayTypePrefix\":true},\"margin\":\"0px\",\"borderRadius\":\"0px\",\"iconSize\":\"0px\"}" + "hasBasicMode": true, + "basicModeDirective": "tb-bar-chart-with-labels-basic-config", + "defaultConfig": "{\"datasources\":[{\"type\":\"function\",\"name\":\"function\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Humidity\",\"color\":\"rgb(125, 142, 255)\",\"settings\":{},\"_hash\":0.8587686344902596,\"funcBody\":\"var value = prevValue + Math.random() * 40 - 20;\\nif (value < 50) {\\n\\tvalue = 50;\\n} else if (value > 80) {\\n\\tvalue = 80;\\n}\\nreturn value;\",\"aggregationType\":null,\"units\":null,\"decimals\":null,\"usePostProcessing\":null,\"postFuncBody\":null},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Soil moisture\",\"color\":\"rgb(249, 111, 255)\",\"settings\":{},\"_hash\":0.9111685461089025,\"funcBody\":\"var value = prevValue + Math.random() * 40 - 20;\\nif (value < 30) {\\n\\tvalue = 30;\\n} else if (value > 90) {\\n\\tvalue = 90;\\n}\\nreturn value;\",\"aggregationType\":null,\"units\":null,\"decimals\":null,\"usePostProcessing\":null,\"postFuncBody\":null},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Leaf wetness\",\"color\":\"rgb(255, 163, 137)\",\"settings\":{},\"_hash\":0.8487533373085416,\"funcBody\":\"var value = prevValue + Math.random() * 40 - 20;\\nif (value < 40) {\\n\\tvalue = 40;\\n} else if (value > 70) {\\n\\tvalue = 70;\\n}\\nreturn value;\",\"aggregationType\":null,\"units\":null,\"decimals\":null,\"usePostProcessing\":null,\"postFuncBody\":null},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Cloud cover\",\"color\":\"#FFED53\",\"settings\":{},\"_hash\":0.7690144858984289,\"funcBody\":\"var value = prevValue + Math.random() * 40 - 20;\\nif (value < 20) {\\n\\tvalue = 20;\\n} else if (value > 60) {\\n\\tvalue = 60;\\n}\\nreturn value;\",\"aggregationType\":null,\"units\":null,\"decimals\":null,\"usePostProcessing\":null,\"postFuncBody\":null}],\"alarmFilterConfig\":{\"statusList\":[\"ACTIVE\"]}}],\"timewindow\":{\"hideInterval\":false,\"hideLastInterval\":false,\"hideQuickInterval\":false,\"hideAggregation\":false,\"hideAggInterval\":false,\"hideTimezone\":false,\"selectedTab\":1,\"history\":{\"historyType\":2,\"timewindowMs\":60000,\"interval\":2592000000,\"fixedTimewindow\":{\"startTimeMs\":1704293713163,\"endTimeMs\":1704380113163},\"quickInterval\":\"CURRENT_HALF_YEAR\"},\"aggregation\":{\"type\":\"AVG\",\"limit\":25000},\"timezone\":null},\"showTitle\":true,\"backgroundColor\":\"rgba(0, 0, 0, 0)\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"0px\",\"settings\":{\"showBarLabel\":true,\"barLabelFont\":{\"family\":\"Roboto\",\"size\":12,\"sizeUnit\":\"px\",\"style\":\"normal\",\"weight\":\"400\",\"lineHeight\":\"12px\"},\"barLabelColor\":\"rgba(0, 0, 0, 0.54)\",\"showBarValue\":true,\"barValueFont\":{\"family\":\"Roboto\",\"size\":12,\"sizeUnit\":\"px\",\"style\":\"normal\",\"weight\":\"700\",\"lineHeight\":\"12px\"},\"barValueColor\":\"rgba(0, 0, 0, 0.76)\",\"showLegend\":true,\"legendPosition\":\"top\",\"legendLabelFont\":{\"family\":\"Roboto\",\"size\":12,\"sizeUnit\":\"px\",\"style\":\"normal\",\"weight\":\"400\",\"lineHeight\":\"16px\"},\"legendLabelColor\":\"rgba(0, 0, 0, 0.76)\",\"showTooltip\":true,\"tooltipValueFont\":{\"family\":\"Roboto\",\"size\":12,\"sizeUnit\":\"px\",\"style\":\"normal\",\"weight\":\"500\",\"lineHeight\":\"16px\"},\"tooltipValueColor\":\"rgba(0, 0, 0, 0.76)\",\"tooltipShowDate\":true,\"tooltipDateFormat\":{\"format\":\"MMMM y\",\"lastUpdateAgo\":false,\"custom\":true},\"tooltipDateFont\":{\"family\":\"Roboto\",\"size\":11,\"sizeUnit\":\"px\",\"style\":\"normal\",\"weight\":\"400\",\"lineHeight\":\"16px\"},\"tooltipDateColor\":\"rgba(0, 0, 0, 0.76)\",\"tooltipBackgroundColor\":\"rgba(255, 255, 255, 0.76)\",\"tooltipBackgroundBlur\":4,\"background\":{\"type\":\"color\",\"color\":\"#fff\",\"overlay\":{\"enabled\":false,\"color\":\"rgba(255,255,255,0.72)\",\"blur\":3}}},\"title\":\"Bar chart with labels\",\"dropShadow\":true,\"enableFullscreen\":true,\"titleStyle\":null,\"mobileHeight\":null,\"configMode\":\"basic\",\"actions\":{},\"showTitleIcon\":false,\"titleIcon\":\"public\",\"iconColor\":\"#1F6BDD\",\"useDashboardTimewindow\":false,\"displayTimewindow\":true,\"titleFont\":{\"size\":16,\"sizeUnit\":\"px\",\"family\":\"Roboto\",\"weight\":\"500\",\"style\":\"normal\",\"lineHeight\":\"24px\"},\"titleColor\":\"rgba(0, 0, 0, 0.87)\",\"titleTooltip\":\"\",\"widgetStyle\":{},\"widgetCss\":\"\",\"pageSize\":1024,\"units\":\"%\",\"decimals\":0,\"noDataDisplayMessage\":\"\",\"timewindowStyle\":{\"showIcon\":false,\"iconSize\":\"24px\",\"icon\":null,\"iconPosition\":\"left\",\"font\":{\"size\":12,\"sizeUnit\":\"px\",\"family\":\"Roboto\",\"weight\":\"400\",\"style\":\"normal\",\"lineHeight\":\"16px\"},\"color\":\"rgba(0, 0, 0, 0.38)\",\"displayTypePrefix\":true},\"margin\":\"0px\",\"borderRadius\":\"0px\",\"iconSize\":\"24px\"}" }, "tags": [ - "range", - "color range", - "line chart" + "bar chart", + "bar", + "bars" ] } \ No newline at end of file diff --git a/ui-ngx/src/app/core/api/data-aggregator.ts b/ui-ngx/src/app/core/api/data-aggregator.ts index 72a500e084..9351e410a8 100644 --- a/ui-ngx/src/app/core/api/data-aggregator.ts +++ b/ui-ngx/src/app/core/api/data-aggregator.ts @@ -136,6 +136,8 @@ const none: AggFunction = (aggData: AggData, value?: any) => { aggData.aggValue = value; }; +const MAX_INTERVAL_TIMEOUT = Math.pow(2,31)-1; + export class DataAggregator { constructor(private onDataCb: onAggregatedData, @@ -217,7 +219,7 @@ export class DataAggregator { this.aggregationTimeout = this.isLatestDataAgg ? 1000 : Math.max(this.subsTw.aggregation.interval, 1000); this.resetPending = true; this.updatedData = false; - this.intervalTimeoutHandle = setTimeout(this.onInterval.bind(this), this.aggregationTimeout); + this.intervalTimeoutHandle = setTimeout(this.onInterval.bind(this), Math.min(this.aggregationTimeout, MAX_INTERVAL_TIMEOUT)); } public destroy() { @@ -313,7 +315,7 @@ export class DataAggregator { this.updatedData = false; } if (!history) { - this.intervalTimeoutHandle = setTimeout(this.onInterval.bind(this), intervalTimeout); + this.intervalTimeoutHandle = setTimeout(this.onInterval.bind(this), Math.min(intervalTimeout, MAX_INTERVAL_TIMEOUT)); } } diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/basic-widget-config.module.ts b/ui-ngx/src/app/modules/home/components/widget/config/basic/basic-widget-config.module.ts index 5e95d162cd..95ce945259 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/basic/basic-widget-config.module.ts +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/basic-widget-config.module.ts @@ -88,6 +88,9 @@ import { import { RangeChartBasicConfigComponent } from '@home/components/widget/config/basic/chart/range-chart-basic-config.component'; +import { + BarChartWithLabelsBasicConfigComponent +} from '@home/components/widget/config/basic/chart/bar-chart-with-labels-basic-config.component'; @NgModule({ declarations: [ @@ -115,7 +118,8 @@ import { CompassGaugeBasicConfigComponent, LiquidLevelCardBasicConfigComponent, DoughnutBasicConfigComponent, - RangeChartBasicConfigComponent + RangeChartBasicConfigComponent, + BarChartWithLabelsBasicConfigComponent ], imports: [ CommonModule, @@ -147,7 +151,8 @@ import { CompassGaugeBasicConfigComponent, LiquidLevelCardBasicConfigComponent, DoughnutBasicConfigComponent, - RangeChartBasicConfigComponent + RangeChartBasicConfigComponent, + BarChartWithLabelsBasicConfigComponent ] }) export class BasicWidgetConfigModule { @@ -173,5 +178,6 @@ export const basicWidgetConfigComponentsMap: {[key: string]: Type + + + + + + + +
+
widget-config.appearance
+
+ + {{ 'widget-config.title' | translate }} + +
+ + + + + + + +
+
+
+ + {{ 'widget-config.card-icon' | translate }} + +
+ + + + + + + + +
+
+
+
+
widgets.bar-chart.bar-appearance
+
+ + {{ 'widgets.bar-chart.label-on-bar' | translate }} + +
+ + + + +
+
+
+ + {{ 'widgets.bar-chart.value-on-bar' | translate }} + +
+ + + + +
+
+
+
widget-config.units-short
+ + +
+
+
widget-config.decimals-short
+ + + +
+
+
+ + + + + {{ 'widget-config.legend' | translate }} + + + + +
+
{{ 'legend.position' | translate }}
+ + + + {{ legendPositionTranslationMap.get(pos) | translate }} + + + +
+
+
{{ 'legend.label' | translate }}
+
+ + + + +
+
+
+
+
+
+ + + + + {{ 'widget-config.tooltip' | translate }} + + + + +
+
{{ 'tooltip.value' | translate }}
+
+ + + + +
+
+
+ + {{ 'tooltip.date' | translate }} + +
+ + + + + +
+
+
+
{{ 'tooltip.background-color' | translate }}
+ + +
+
+
{{ 'tooltip.background-blur' | translate }}
+ + +
px
+
+
+
+
+
+
+
widget-config.card-appearance
+
+
{{ 'widgets.background.background' | translate }}
+ + +
+
+
widget-config.show-card-buttons
+ + {{ 'fullscreen.fullscreen' | translate }} + +
+
+
{{ 'widget-config.card-border-radius' | translate }}
+ + + +
+
+ + +
diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/bar-chart-with-labels-basic-config.component.ts b/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/bar-chart-with-labels-basic-config.component.ts new file mode 100644 index 0000000000..6b6929a36f --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/bar-chart-with-labels-basic-config.component.ts @@ -0,0 +1,323 @@ +/// +/// Copyright © 2016-2023 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 { Component, Injector } from '@angular/core'; +import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms'; +import { Store } from '@ngrx/store'; +import { AppState } from '@core/core.state'; +import { BasicWidgetConfigComponent } from '@home/components/widget/config/widget-config.component.models'; +import { WidgetConfigComponentData } from '@home/models/widget-component.models'; +import { + DataKey, + Datasource, + legendPositions, + legendPositionTranslationMap, + WidgetConfig, +} from '@shared/models/widget.models'; +import { WidgetConfigComponent } from '@home/components/widget/widget-config.component'; +import { DataKeyType } from '@shared/models/telemetry/telemetry.models'; +import { + getTimewindowConfig, + setTimewindowConfig +} from '@home/components/widget/config/timewindow-config-panel.component'; +import { formatValue, isUndefined } from '@core/utils'; +import { + cssSizeToStrSize, + DateFormatProcessor, + DateFormatSettings, + resolveCssSize +} from '@shared/models/widget-settings.models'; +import { + barChartWithLabelsDefaultSettings, + BarChartWithLabelsWidgetSettings +} from '@home/components/widget/lib/chart/bar-chart-with-labels-widget.models'; + +@Component({ + selector: 'tb-bar-chart-with-labels-basic-config', + templateUrl: './bar-chart-with-labels-basic-config.component.html', + styleUrls: ['../basic-config.scss'] +}) +export class BarChartWithLabelsBasicConfigComponent extends BasicWidgetConfigComponent { + + public get datasource(): Datasource { + const datasources: Datasource[] = this.barChartWidgetConfigForm.get('datasources').value; + if (datasources && datasources.length) { + return datasources[0]; + } else { + return null; + } + } + + legendPositions = legendPositions; + + legendPositionTranslationMap = legendPositionTranslationMap; + + barChartWidgetConfigForm: UntypedFormGroup; + + tooltipValuePreviewFn = this._tooltipValuePreviewFn.bind(this); + + tooltipDatePreviewFn = this._tooltipDatePreviewFn.bind(this); + + constructor(protected store: Store, + protected widgetConfigComponent: WidgetConfigComponent, + private $injector: Injector, + private fb: UntypedFormBuilder) { + super(store, widgetConfigComponent); + } + + protected configForm(): UntypedFormGroup { + return this.barChartWidgetConfigForm; + } + + protected defaultDataKeys(configData: WidgetConfigComponentData): DataKey[] { + return [{ name: 'temperature', label: 'Temperature', type: DataKeyType.timeseries }]; + } + + protected onConfigSet(configData: WidgetConfigComponentData) { + const settings: BarChartWithLabelsWidgetSettings = {...barChartWithLabelsDefaultSettings, ...(configData.config.settings || {})}; + const iconSize = resolveCssSize(configData.config.iconSize); + this.barChartWidgetConfigForm = this.fb.group({ + timewindowConfig: [getTimewindowConfig(configData.config), []], + datasources: [configData.config.datasources, []], + series: [this.getSeries(configData.config.datasources), []], + + showTitle: [configData.config.showTitle, []], + title: [configData.config.title, []], + titleFont: [configData.config.titleFont, []], + titleColor: [configData.config.titleColor, []], + + showIcon: [configData.config.showTitleIcon, []], + iconSize: [iconSize[0], [Validators.min(0)]], + iconSizeUnit: [iconSize[1], []], + icon: [configData.config.titleIcon, []], + iconColor: [configData.config.iconColor, []], + + showBarLabel: [settings.showBarLabel, []], + barLabelFont: [settings.barLabelFont, []], + barLabelColor: [settings.barLabelColor, []], + showBarValue: [settings.showBarValue, []], + barValueFont: [settings.barValueFont, []], + barValueColor: [settings.barValueColor, []], + + units: [configData.config.units, []], + decimals: [configData.config.decimals, []], + + showLegend: [settings.showLegend, []], + legendPosition: [settings.legendPosition, []], + legendLabelFont: [settings.legendLabelFont, []], + legendLabelColor: [settings.legendLabelColor, []], + + showTooltip: [settings.showTooltip, []], + tooltipValueFont: [settings.tooltipValueFont, []], + tooltipValueColor: [settings.tooltipValueColor, []], + tooltipShowDate: [settings.tooltipShowDate, []], + tooltipDateFormat: [settings.tooltipDateFormat, []], + tooltipDateFont: [settings.tooltipDateFont, []], + tooltipDateColor: [settings.tooltipDateColor, []], + tooltipBackgroundColor: [settings.tooltipBackgroundColor, []], + tooltipBackgroundBlur: [settings.tooltipBackgroundBlur, []], + + background: [settings.background, []], + + cardButtons: [this.getCardButtons(configData.config), []], + borderRadius: [configData.config.borderRadius, []], + + actions: [configData.config.actions || {}, []] + }); + } + + protected prepareOutputConfig(config: any): WidgetConfigComponentData { + setTimewindowConfig(this.widgetConfig.config, config.timewindowConfig); + this.widgetConfig.config.datasources = config.datasources; + this.setSeries(config.series, this.widgetConfig.config.datasources); + + this.widgetConfig.config.showTitle = config.showTitle; + this.widgetConfig.config.title = config.title; + this.widgetConfig.config.titleFont = config.titleFont; + this.widgetConfig.config.titleColor = config.titleColor; + + this.widgetConfig.config.showTitleIcon = config.showIcon; + this.widgetConfig.config.iconSize = cssSizeToStrSize(config.iconSize, config.iconSizeUnit); + this.widgetConfig.config.titleIcon = config.icon; + this.widgetConfig.config.iconColor = config.iconColor; + + this.widgetConfig.config.settings = this.widgetConfig.config.settings || {}; + + this.widgetConfig.config.settings.showBarLabel = config.showBarLabel; + this.widgetConfig.config.settings.barLabelFont = config.barLabelFont; + this.widgetConfig.config.settings.barLabelColor = config.barLabelColor; + this.widgetConfig.config.settings.showBarValue = config.showBarValue; + this.widgetConfig.config.settings.barValueFont = config.barValueFont; + this.widgetConfig.config.settings.barValueColor = config.barValueColor; + + this.widgetConfig.config.units = config.units; + this.widgetConfig.config.decimals = config.decimals; + + this.widgetConfig.config.settings.showLegend = config.showLegend; + this.widgetConfig.config.settings.legendPosition = config.legendPosition; + this.widgetConfig.config.settings.legendLabelFont = config.legendLabelFont; + this.widgetConfig.config.settings.legendLabelColor = config.legendLabelColor; + + this.widgetConfig.config.settings.showTooltip = config.showTooltip; + this.widgetConfig.config.settings.tooltipValueFont = config.tooltipValueFont; + this.widgetConfig.config.settings.tooltipValueColor = config.tooltipValueColor; + this.widgetConfig.config.settings.tooltipShowDate = config.tooltipShowDate; + this.widgetConfig.config.settings.tooltipDateFormat = config.tooltipDateFormat; + this.widgetConfig.config.settings.tooltipDateFont = config.tooltipDateFont; + this.widgetConfig.config.settings.tooltipDateColor = config.tooltipDateColor; + this.widgetConfig.config.settings.tooltipBackgroundColor = config.tooltipBackgroundColor; + this.widgetConfig.config.settings.tooltipBackgroundBlur = config.tooltipBackgroundBlur; + + this.widgetConfig.config.settings.background = config.background; + + this.setCardButtons(config.cardButtons, this.widgetConfig.config); + this.widgetConfig.config.borderRadius = config.borderRadius; + + this.widgetConfig.config.actions = config.actions; + return this.widgetConfig; + } + + protected validatorTriggers(): string[] { + return ['showTitle', 'showIcon', 'showBarLabel', 'showBarValue', 'showLegend', 'showTooltip', 'tooltipShowDate']; + } + + protected updateValidators(emitEvent: boolean, trigger?: string) { + const showTitle: boolean = this.barChartWidgetConfigForm.get('showTitle').value; + const showIcon: boolean = this.barChartWidgetConfigForm.get('showIcon').value; + const showBarLabel: boolean = this.barChartWidgetConfigForm.get('showBarLabel').value; + const showBarValue: boolean = this.barChartWidgetConfigForm.get('showBarValue').value; + const showLegend: boolean = this.barChartWidgetConfigForm.get('showLegend').value; + const showTooltip: boolean = this.barChartWidgetConfigForm.get('showTooltip').value; + const tooltipShowDate: boolean = this.barChartWidgetConfigForm.get('tooltipShowDate').value; + + if (showTitle) { + this.barChartWidgetConfigForm.get('title').enable(); + this.barChartWidgetConfigForm.get('titleFont').enable(); + this.barChartWidgetConfigForm.get('titleColor').enable(); + this.barChartWidgetConfigForm.get('showIcon').enable({emitEvent: false}); + if (showIcon) { + this.barChartWidgetConfigForm.get('iconSize').enable(); + this.barChartWidgetConfigForm.get('iconSizeUnit').enable(); + this.barChartWidgetConfigForm.get('icon').enable(); + this.barChartWidgetConfigForm.get('iconColor').enable(); + } else { + this.barChartWidgetConfigForm.get('iconSize').disable(); + this.barChartWidgetConfigForm.get('iconSizeUnit').disable(); + this.barChartWidgetConfigForm.get('icon').disable(); + this.barChartWidgetConfigForm.get('iconColor').disable(); + } + } else { + this.barChartWidgetConfigForm.get('title').disable(); + this.barChartWidgetConfigForm.get('titleFont').disable(); + this.barChartWidgetConfigForm.get('titleColor').disable(); + this.barChartWidgetConfigForm.get('showIcon').disable({emitEvent: false}); + this.barChartWidgetConfigForm.get('iconSize').disable(); + this.barChartWidgetConfigForm.get('iconSizeUnit').disable(); + this.barChartWidgetConfigForm.get('icon').disable(); + this.barChartWidgetConfigForm.get('iconColor').disable(); + } + + if (showBarLabel) { + this.barChartWidgetConfigForm.get('barLabelFont').enable(); + this.barChartWidgetConfigForm.get('barLabelColor').enable(); + } else { + this.barChartWidgetConfigForm.get('barLabelFont').disable(); + this.barChartWidgetConfigForm.get('barLabelColor').disable(); + } + + if (showBarValue) { + this.barChartWidgetConfigForm.get('barValueFont').enable(); + this.barChartWidgetConfigForm.get('barValueColor').enable(); + } else { + this.barChartWidgetConfigForm.get('barValueFont').disable(); + this.barChartWidgetConfigForm.get('barValueColor').disable(); + } + + if (showLegend) { + this.barChartWidgetConfigForm.get('legendPosition').enable(); + this.barChartWidgetConfigForm.get('legendLabelFont').enable(); + this.barChartWidgetConfigForm.get('legendLabelColor').enable(); + } else { + this.barChartWidgetConfigForm.get('legendPosition').disable(); + this.barChartWidgetConfigForm.get('legendLabelFont').disable(); + this.barChartWidgetConfigForm.get('legendLabelColor').disable(); + } + + if (showTooltip) { + this.barChartWidgetConfigForm.get('tooltipValueFont').enable(); + this.barChartWidgetConfigForm.get('tooltipValueColor').enable(); + this.barChartWidgetConfigForm.get('tooltipShowDate').enable({emitEvent: false}); + this.barChartWidgetConfigForm.get('tooltipBackgroundColor').enable(); + this.barChartWidgetConfigForm.get('tooltipBackgroundBlur').enable(); + if (tooltipShowDate) { + this.barChartWidgetConfigForm.get('tooltipDateFormat').enable(); + this.barChartWidgetConfigForm.get('tooltipDateFont').enable(); + this.barChartWidgetConfigForm.get('tooltipDateColor').enable(); + } else { + this.barChartWidgetConfigForm.get('tooltipDateFormat').disable(); + this.barChartWidgetConfigForm.get('tooltipDateFont').disable(); + this.barChartWidgetConfigForm.get('tooltipDateColor').disable(); + } + } else { + this.barChartWidgetConfigForm.get('tooltipValueFont').disable(); + this.barChartWidgetConfigForm.get('tooltipValueColor').disable(); + this.barChartWidgetConfigForm.get('tooltipShowDate').disable({emitEvent: false}); + this.barChartWidgetConfigForm.get('tooltipDateFormat').disable(); + this.barChartWidgetConfigForm.get('tooltipDateFont').disable(); + this.barChartWidgetConfigForm.get('tooltipDateColor').disable(); + this.barChartWidgetConfigForm.get('tooltipBackgroundColor').disable(); + this.barChartWidgetConfigForm.get('tooltipBackgroundBlur').disable(); + } + } + + private getSeries(datasources?: Datasource[]): DataKey[] { + if (datasources && datasources.length) { + return datasources[0].dataKeys || []; + } + return []; + } + + private setSeries(series: DataKey[], datasources?: Datasource[]) { + if (datasources && datasources.length) { + datasources[0].dataKeys = series; + } + } + + private getCardButtons(config: WidgetConfig): string[] { + const buttons: string[] = []; + if (isUndefined(config.enableFullscreen) || config.enableFullscreen) { + buttons.push('fullscreen'); + } + return buttons; + } + + private setCardButtons(buttons: string[], config: WidgetConfig) { + config.enableFullscreen = buttons.includes('fullscreen'); + } + + private _tooltipValuePreviewFn(): string { + const units: string = this.barChartWidgetConfigForm.get('units').value; + const decimals: number = this.barChartWidgetConfigForm.get('decimals').value; + return formatValue(22, decimals, units, false); + } + + private _tooltipDatePreviewFn(): string { + const dateFormat: DateFormatSettings = this.barChartWidgetConfigForm.get('tooltipDateFormat').value; + const processor = DateFormatProcessor.fromSettings(this.$injector, dateFormat); + processor.update(Date.now()); + return processor.formatted; + } +} diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/doughnut-basic-config.component.html b/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/doughnut-basic-config.component.html index 00c4929f3c..c12cf02299 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/doughnut-basic-config.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/doughnut-basic-config.component.html @@ -145,14 +145,14 @@
{{ 'legend.position' | translate }}
- - {{ doughnutLegendPositionTranslationMap.get(pos) | translate }} + + {{ legendPositionTranslationMap.get(pos) | translate }}
-
{{ 'widgets.doughnut.legend-label' | translate }}
+
{{ 'legend.label' | translate }}
@@ -164,7 +164,7 @@
-
{{ 'widgets.doughnut.legend-value' | translate }}
+
{{ 'legend.value' | translate }}
@@ -184,13 +184,13 @@ - {{ 'widgets.doughnut.tooltip' | translate }} + {{ 'widget-config.tooltip' | translate }}
-
{{ 'widgets.doughnut.tooltip-value' | translate }}
+
{{ 'tooltip.value' | translate }}
@@ -213,14 +213,14 @@
-
{{ 'widgets.doughnut.tooltip-background-color' | translate }}
+
{{ 'tooltip.background-color' | translate }}
-
{{ 'widgets.doughnut.tooltip-background-blur' | translate }}
+
{{ 'tooltip.background-blur' | translate }}
px
diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/doughnut-basic-config.component.ts b/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/doughnut-basic-config.component.ts index f8149bc97d..0ab89281bc 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/doughnut-basic-config.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/doughnut-basic-config.component.ts @@ -25,6 +25,8 @@ import { Datasource, datasourcesHasAggregation, datasourcesHasOnlyComparisonAggregation, + legendPositions, + legendPositionTranslationMap, WidgetConfig } from '@shared/models/widget.models'; import { WidgetConfigComponent } from '@home/components/widget/widget-config.component'; @@ -40,8 +42,6 @@ import { doughnutLayoutImages, doughnutLayouts, doughnutLayoutTranslations, - doughnutLegendPositions, - doughnutLegendPositionTranslations, DoughnutTooltipValueType, doughnutTooltipValueTypes, doughnutTooltipValueTypeTranslations, @@ -83,9 +83,9 @@ export class DoughnutBasicConfigComponent extends BasicWidgetConfigComponent { doughnutLayoutImageMap: Map; - doughnutLegendPositions = doughnutLegendPositions; + legendPositions = legendPositions; - doughnutLegendPositionTranslationMap = doughnutLegendPositionTranslations; + legendPositionTranslationMap = legendPositionTranslationMap; doughnutTooltipValueTypes = doughnutTooltipValueTypes; diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/range-chart-basic-config.component.html b/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/range-chart-basic-config.component.html index 66b4054df1..391007d155 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/range-chart-basic-config.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/range-chart-basic-config.component.html @@ -49,7 +49,7 @@
- {{ 'widgets.value-chart-card.icon' | translate }} + {{ 'widget-config.card-icon' | translate }}
@@ -127,7 +127,7 @@
-
{{ 'widgets.range-chart.legend-label' | translate }}
+
{{ 'legend.label' | translate }}
@@ -147,13 +147,13 @@ - {{ 'widgets.range-chart.tooltip' | translate }} + {{ 'widget-config.tooltip' | translate }}
-
{{ 'widgets.range-chart.tooltip-value' | translate }}
+
{{ 'tooltip.value' | translate }}
@@ -166,7 +166,7 @@
- {{ 'widgets.range-chart.tooltip-date' | translate }} + {{ 'tooltip.date' | translate }}
@@ -180,14 +180,14 @@
-
{{ 'widgets.range-chart.tooltip-background-color' | translate }}
+
{{ 'tooltip.background-color' | translate }}
-
{{ 'widgets.range-chart.tooltip-background-blur' | translate }}
+
{{ 'tooltip.background-blur' | translate }}
px
diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/indicator/signal-strength-basic-config.component.html b/ui-ngx/src/app/modules/home/components/widget/config/basic/indicator/signal-strength-basic-config.component.html index 4669bf5f82..9edf205d11 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/basic/indicator/signal-strength-basic-config.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/indicator/signal-strength-basic-config.component.html @@ -117,14 +117,14 @@ - {{ 'widgets.signal-strength.tooltip' | translate }} + {{ 'widget-config.tooltip' | translate }}
- {{ 'widgets.signal-strength.value' | translate }} + {{ 'tooltip.value' | translate }}
@@ -144,7 +144,7 @@
- {{ 'widgets.signal-strength.date' | translate }} + {{ 'tooltip.date' | translate }}
@@ -158,13 +158,13 @@
-
{{ 'widgets.signal-strength.background-color' | translate }}
+
{{ 'tooltip.background-color' | translate }}
-
widgets.signal-strength.background-blur
+
tooltip.background-blur
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/chart/bar-chart-with-labels-widget.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/chart/bar-chart-with-labels-widget.component.ts index 62c7209dbd..c325bb0e73 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/chart/bar-chart-with-labels-widget.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/chart/bar-chart-with-labels-widget.component.ts @@ -36,14 +36,8 @@ import { textStyle } from '@shared/models/widget-settings.models'; import { ResizeObserver } from '@juggle/resize-observer'; -import * as echarts from 'echarts/core'; -import { Axis } from 'echarts'; import { formatValue } from '@core/utils'; -import { GridComponent, GridComponentOption, TooltipComponent, TooltipComponentOption } from 'echarts/components'; -import { LabelLayout } from 'echarts/features'; -import { BarChart, BarSeriesOption} from 'echarts/charts'; -import { CanvasRenderer } from 'echarts/renderers'; -import { DataKey, DataSet } from '@shared/models/widget.models'; +import { DataKey } from '@shared/models/widget.models'; import { Observable } from 'rxjs'; import { ImagePipe } from '@shared/pipe/image.pipe'; import { DomSanitizer } from '@angular/platform-browser'; @@ -51,40 +45,19 @@ import { barChartWithLabelsDefaultSettings, BarChartWithLabelsWidgetSettings } from '@home/components/widget/lib/chart/bar-chart-with-labels-widget.models'; -import { LabelLayoutOptionCallback } from 'echarts/types/dist/shared'; -import BarSeriesModel from 'echarts/types/src/chart/bar/BarSeries'; - -const axisGetBandWidth = Axis.prototype.getBandWidth; - -Axis.prototype.getBandWidth = function(){ - const series: any[] = this.model?.parentModel?.getSeries(); - if (this.scale.type === 'time' && series?.length && series[0].type === 'series.bar') { - const barWidth = (series[0] as BarSeriesModel).getData().getLayout('size'); - return barWidth * (series.length + 1); - } else { - return axisGetBandWidth.call(this); - } -}; - -echarts.use([ - TooltipComponent, - GridComponent, - BarChart, - LabelLayout, - CanvasRenderer -]); - -type EChartsOption = echarts.ComposeOption< - | TooltipComponentOption - | GridComponentOption - | BarSeriesOption ->; - -type ECharts = echarts.ECharts; -type NamedDataSet = {name: string; value: [number, any]}[]; +import * as echarts from 'echarts/core'; +import { CustomSeriesOption } from 'echarts/charts'; +import { CallbackDataParams, CustomSeriesRenderItem, LabelLayoutOptionCallback } from 'echarts/types/dist/shared'; -type BarLabelOption = NonNullable; +import { + ECharts, + echartsModule, + EChartsOption, + echartsTooltipFormatter, + NamedDataSet, + toNamedData +} from '@home/components/widget/lib/chart/echarts-widget.models'; interface BarChartDataItem { id: string; @@ -100,17 +73,6 @@ interface BarChartLegendItem { enabled: boolean; } -const toNamedData = (data: DataSet): NamedDataSet => { - if (!data?.length) { - return []; - } else { - return data.map(d => ({ - name: d[0] + '', - value: d - })); - } -}; - @Component({ selector: 'tb-bar-chart-with-labels-widget', templateUrl: './bar-chart-with-labels-widget.component.html', @@ -153,7 +115,7 @@ export class BarChartWithLabelsWidgetComponent implements OnInit, OnDestroy, Aft private tooltipDateFormat: DateFormatProcessor; - private barLabelOptions: BarLabelOption; + private barRenderItem: CustomSeriesRenderItem; private barLabelLayoutCallback: LabelLayoutOptionCallback; constructor(private imagePipe: ImagePipe, @@ -216,41 +178,85 @@ export class BarChartWithLabelsWidgetComponent implements OnInit, OnDestroy, Aft const barValueStyle: ComponentStyle = textStyle(this.settings.barValueFont); delete barValueStyle.lineHeight; barValueStyle.fontSize = this.settings.barValueFont.size; - barValueStyle.color = this.settings.barValueColor; + barValueStyle.fill = this.settings.barValueColor; const barLabelStyle: ComponentStyle = textStyle(this.settings.barLabelFont); delete barLabelStyle.lineHeight; barLabelStyle.fontSize = this.settings.barLabelFont.size; - barLabelStyle.color = this.settings.barLabelColor; - - this.barLabelOptions = { - show: this.settings.showBarLabel || this.settings.showBarValue, - position: 'insideBottom', - distance: 15, - align: 'left', - verticalAlign: 'middle', - rotate: 90, - formatter: (params) => { - const parts: string[] = []; - if (this.settings.showBarValue) { - const value = formatValue(params.value[1], this.decimals, '', false); - parts.push(`{value|${value}}`); - } - if (this.settings.showBarLabel) { - parts.push(`{label|${params.seriesName}}`); - } - return parts.join(' '); - }, - rich: { - value: barValueStyle, - label: barLabelStyle + barLabelStyle.fill = this.settings.barLabelColor; + + this.barRenderItem = (params, api) => { + + const interval = this.ctx.defaultSubscription.timeWindow.interval; + const enabledDataItems = this.dataItems.filter(d => d.enabled); + const barInterval = interval / (enabledDataItems.length + 1); + const intervalGap = barInterval / 2; + + const index = enabledDataItems.findIndex(d => d.id === params.seriesId); + const time = api.value(0) as number; + const value = api.value(1); + const start = time - interval / 2; + const startTime = start + intervalGap + barInterval * index; + const delta = barInterval; + const lowerLeft = api.coord([startTime, value]); + const height = api.size([delta, value])[1]; + const width = api.size([delta, 10])[0]; + + const coordSys: {x: number; y: number; width: number; height: number} = params.coordSys as any; + + const rectShape = echarts.graphic.clipRectByRect({ + x: lowerLeft[0], + y: lowerLeft[1], + width, + height + }, { + x: coordSys.x, + y: coordSys.y, + width: coordSys.width, + height: coordSys.height + }); + + const zeroPos = api.coord([0, 0]); + const labelParts: string[] = []; + if (this.settings.showBarValue) { + const labelValue = formatValue(value, this.decimals, '', false); + labelParts.push(`{value|${labelValue}}`); } + if (this.settings.showBarLabel) { + labelParts.push(`{label|${params.seriesName}}`); + } + const barLabel = labelParts.join(' '); + return rectShape && { + type: 'rect', + id: time + '', + shape: rectShape, + style: { + fill: api.visual('color'), + text: barLabel, + textPosition: 'insideBottom', + textRotation: Math.PI / 2, + textDistance: 15, + textStrokeWidth: 0, + textAlign: 'left', + textVerticalAlign: 'middle', + rich: { + value: barValueStyle, + label: barLabelStyle + } + }, + focus: 'series', + transition: 'all', + enterFrom: { + style: { opacity: 0 }, + shape: { height: 0, y: zeroPos[1] } + } + }; }; this.barLabelLayoutCallback = (params) => { if (params.rect.width - params.labelRect.width < 2) { return { - y: '-100%' + y: '1000%', }; } else { return { @@ -288,38 +294,44 @@ export class BarChartWithLabelsWidgetComponent implements OnInit, OnDestroy, Aft public onDataUpdated() { let minTime = this.ctx.defaultSubscription.timeWindow.minTime; + let maxTime = this.ctx.defaultSubscription.timeWindow.maxTime; + let dataMin = Number.MAX_VALUE; + let dataMax = Number.MIN_VALUE; for (const item of this.dataItems) { const datasourceData = this.ctx.data ? this.ctx.data.find(d => d.dataKey === item.dataKey) : null; - const namedData = datasourceData?.data ? toNamedData(datasourceData.data) : []; - item.data = namedData; + item.data = datasourceData?.data ? toNamedData(datasourceData.data) : []; if (datasourceData.data.length) { - minTime = Math.min(datasourceData.data[0][0], minTime); + dataMin = Math.min(datasourceData.data[0][0], dataMin); + dataMax = Math.max(datasourceData.data[datasourceData.data.length-1][0], dataMax); } } + if (dataMin !== Number.MAX_VALUE) { + minTime = dataMin - this.ctx.defaultSubscription.timeWindow.interval / 2; + } + if (dataMax !== Number.MIN_VALUE) { + dataMax = dataMax + this.ctx.defaultSubscription.timeWindow.interval / 2; + maxTime = Math.max(dataMax, maxTime); + } if (this.barChart) { (this.barChartOptions.xAxis as any).min = minTime; - (this.barChartOptions.xAxis as any).max = this.ctx.defaultSubscription.timeWindow.maxTime; + (this.barChartOptions.xAxis as any).max = maxTime; + (this.barChartOptions.xAxis as any).tbTimewindowInterval = this.ctx.defaultSubscription.timeWindow.interval; this.barChartOptions.series = this.updateSeries(); this.barChart.setOption(this.barChartOptions); } } - private updateSeries(): Array { - const series: Array = []; + private updateSeries(): Array { + const series: Array = []; for (const item of this.dataItems) { if (item.enabled) { - const seriesOption: BarSeriesOption = { - type: 'bar', - barGap: 0, - barMaxWidth: 40, + const seriesOption: CustomSeriesOption = { + type: 'custom', id: item.id, name: item.dataKey.label, - label: this.barLabelOptions, color: item.dataKey.color, data: item.data, - emphasis: { - focus: 'series' - }, + renderItem: this.barRenderItem, labelLayout: this.barLabelLayoutCallback }; series.push(seriesOption); @@ -328,6 +340,7 @@ export class BarChartWithLabelsWidgetComponent implements OnInit, OnDestroy, Aft return series; } + public onLegendItemEnter(item: BarChartLegendItem) { this.barChart.dispatchAction({ type: 'highlight', @@ -347,26 +360,26 @@ export class BarChartWithLabelsWidgetComponent implements OnInit, OnDestroy, Aft const dataItem = this.dataItems.find(d => d.id === item.id); if (dataItem) { dataItem.enabled = enable; + if (!enable) { + this.barChart.dispatchAction({ + type: 'downplay', + seriesId: item.id + }); + } this.barChartOptions.series = this.updateSeries(); - this.barChart.setOption(this.barChartOptions, true); + this.barChart.setOption(this.barChartOptions, {replaceMerge: ['series']}); item.enabled = enable; if (enable) { this.barChart.dispatchAction({ type: 'highlight', seriesId: item.id }); - } else { - for (const otherItem of this.legendItems.filter(i => i.id !== item.id)) { - this.barChart.dispatchAction({ - type: 'highlight', - seriesId: otherItem.id - }); - } } } } private drawChart() { + echartsModule.init(); this.barChart = echarts.init(this.chartShape.nativeElement, null, { renderer: 'canvas', }); @@ -383,6 +396,7 @@ export class BarChartWithLabelsWidgetComponent implements OnInit, OnDestroy, Aft }, xAxis: { type: 'time', + scale: true, axisTick: { show: false }, @@ -393,17 +407,19 @@ export class BarChartWithLabelsWidgetComponent implements OnInit, OnDestroy, Aft axisLine: { onZero: false }, - min: this.ctx.defaultSubscription.timeWindow.minTime, - max: this.ctx.defaultSubscription.timeWindow.maxTime + min: this.ctx.defaultSubscription.timeWindow.minTime - this.ctx.defaultSubscription.timeWindow.interval / 2, + max: this.ctx.defaultSubscription.timeWindow.maxTime + this.ctx.defaultSubscription.timeWindow.interval / 2 }, yAxis: { type: 'value', axisLabel: { - formatter: value => formatValue(value, this.decimals, this.units, false) + formatter: (value: any) => formatValue(value, this.decimals, this.units, false) } } }; + (this.barChartOptions.xAxis as any).tbTimewindowInterval = this.ctx.defaultSubscription.timeWindow.interval; + this.barChartOptions.series = this.updateSeries(); if (this.settings.showTooltip) { @@ -412,44 +428,14 @@ export class BarChartWithLabelsWidgetComponent implements OnInit, OnDestroy, Aft axisPointer: { type: 'shadow' }, - formatter: (params: any[]) => { - if (!params.length || !params[0]) { - return null; - } - const tooltipElement: HTMLElement = this.renderer.createElement('div'); - this.renderer.setStyle(tooltipElement, 'display', 'flex'); - this.renderer.setStyle(tooltipElement, 'flex-direction', 'column'); - this.renderer.setStyle(tooltipElement, 'align-items', 'flex-start'); - this.renderer.setStyle(tooltipElement, 'gap', '4px'); - if (this.settings.tooltipShowDate) { - const dateElement: HTMLElement = this.renderer.createElement('div'); - const ts = params[0].value[0]; - this.tooltipDateFormat.update(ts); - this.renderer.appendChild(dateElement, this.renderer.createText(this.tooltipDateFormat.formatted)); - this.renderer.setStyle(dateElement, 'font-family', this.settings.tooltipDateFont.family); - this.renderer.setStyle(dateElement, 'font-size', this.settings.tooltipDateFont.size + this.settings.tooltipDateFont.sizeUnit); - this.renderer.setStyle(dateElement, 'font-style', this.settings.tooltipDateFont.style); - this.renderer.setStyle(dateElement, 'font-weight', this.settings.tooltipDateFont.weight); - this.renderer.setStyle(dateElement, 'line-height', this.settings.tooltipDateFont.lineHeight); - this.renderer.setStyle(dateElement, 'color', this.settings.tooltipDateColor); - this.renderer.appendChild(tooltipElement, dateElement); - } - let seriesParams = null; + formatter: (params: CallbackDataParams[]) => { const focusedSeriesIndex = this.focusedSeriesIndex(); - if (focusedSeriesIndex > -1) { - seriesParams = params.find(param => param.seriesIndex === focusedSeriesIndex); - } - if (seriesParams) { - this.renderer.appendChild(tooltipElement, this.constructTooltipSeriesElement(seriesParams)); - } else { - for (seriesParams of params) { - this.renderer.appendChild(tooltipElement, this.constructTooltipSeriesElement(seriesParams)); - } - } - return tooltipElement; + return echartsTooltipFormatter(this.renderer, this.tooltipDateFormat, + this.settings, params, this.decimals, this.units, focusedSeriesIndex); }, padding: [8, 12], backgroundColor: this.settings.tooltipBackgroundColor, + borderWidth: 0, extraCssText: `line-height: 1; backdrop-filter: blur(${this.settings.tooltipBackgroundBlur}px);` }; } @@ -463,65 +449,22 @@ export class BarChartWithLabelsWidgetComponent implements OnInit, OnDestroy, Aft this.onResize(); } - private constructTooltipSeriesElement(seriesParams): HTMLElement { - const labelValueElement: HTMLElement = this.renderer.createElement('div'); - this.renderer.setStyle(labelValueElement, 'display', 'flex'); - this.renderer.setStyle(labelValueElement, 'flex-direction', 'row'); - this.renderer.setStyle(labelValueElement, 'align-items', 'center'); - this.renderer.setStyle(labelValueElement, 'align-self', 'stretch'); - this.renderer.setStyle(labelValueElement, 'gap', '12px'); - const labelElement: HTMLElement = this.renderer.createElement('div'); - this.renderer.setStyle(labelElement, 'display', 'flex'); - this.renderer.setStyle(labelElement, 'align-items', 'center'); - this.renderer.setStyle(labelElement, 'gap', '8px'); - this.renderer.appendChild(labelValueElement, labelElement); - const circleElement: HTMLElement = this.renderer.createElement('div'); - this.renderer.setStyle(circleElement, 'width', '8px'); - this.renderer.setStyle(circleElement, 'height', '8px'); - this.renderer.setStyle(circleElement, 'border-radius', '50%'); - this.renderer.setStyle(circleElement, 'background', seriesParams.color); - this.renderer.appendChild(labelElement, circleElement); - const labelTextElement: HTMLElement = this.renderer.createElement('div'); - this.renderer.appendChild(labelTextElement, this.renderer.createText(seriesParams.seriesName)); - this.renderer.setStyle(labelTextElement, 'font-family', 'Roboto'); - this.renderer.setStyle(labelTextElement, 'font-size', '12px'); - this.renderer.setStyle(labelTextElement, 'font-style', 'normal'); - this.renderer.setStyle(labelTextElement, 'font-weight', '400'); - this.renderer.setStyle(labelTextElement, 'line-height', '16px'); - this.renderer.setStyle(labelTextElement, 'letter-spacing', '0.4px'); - this.renderer.setStyle(labelTextElement, 'color', 'rgba(0, 0, 0, 0.76)'); - this.renderer.appendChild(labelElement, labelTextElement); - const valueElement: HTMLElement = this.renderer.createElement('div'); - const value = formatValue(seriesParams.value[1], this.decimals, this.units, false); - this.renderer.appendChild(valueElement, this.renderer.createText(value)); - this.renderer.setStyle(valueElement, 'flex', '1'); - this.renderer.setStyle(valueElement, 'text-align', 'end'); - this.renderer.setStyle(valueElement, 'font-family', this.settings.tooltipValueFont.family); - this.renderer.setStyle(valueElement, 'font-size', this.settings.tooltipValueFont.size + this.settings.tooltipValueFont.sizeUnit); - this.renderer.setStyle(valueElement, 'font-style', this.settings.tooltipValueFont.style); - this.renderer.setStyle(valueElement, 'font-weight', this.settings.tooltipValueFont.weight); - this.renderer.setStyle(valueElement, 'line-height', this.settings.tooltipValueFont.lineHeight); - this.renderer.setStyle(valueElement, 'color', this.settings.tooltipValueColor); - this.renderer.appendChild(labelValueElement, valueElement); - return labelValueElement; - } - private focusedSeriesIndex(): number { let index = - 1; - // @ts-ignore - const views: any[] = this.barChart._chartsViews; + const views: any[] = (this.barChart as any)._chartsViews; if (views) { const hasBlurredView = !!views.find(view => { const graphicEls: any[] = view._data._graphicEls; - return !!graphicEls.find(el => el.currentStates.includes('blur')); + return !!graphicEls.find(el => el?.currentStates.includes('blur')); }); if (hasBlurredView) { const focusedView = views.find(view => { const graphicEls: any[] = view._data._graphicEls; - return !!graphicEls.find(el => !el.currentStates.includes('blur')); + return !!graphicEls.find(el => !el?.currentStates.includes('blur')); }); if (focusedView) { - index = focusedView._model.seriesIndex; + index = !!focusedView._model ? + focusedView._model.seriesIndex : (!!focusedView.__model ? focusedView.__model.seriesIndex : -1); } } } diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/chart/bar-chart-with-labels-widget.models.ts b/ui-ngx/src/app/modules/home/components/widget/lib/chart/bar-chart-with-labels-widget.models.ts index b56b2bc435..ecb5e8a667 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/chart/bar-chart-with-labels-widget.models.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/chart/bar-chart-with-labels-widget.models.ts @@ -14,15 +14,11 @@ /// limitations under the License. /// -import { - BackgroundSettings, - BackgroundType, customDateFormat, - DateFormatSettings, - Font -} from '@shared/models/widget-settings.models'; +import { BackgroundSettings, BackgroundType, customDateFormat, Font } from '@shared/models/widget-settings.models'; import { LegendPosition } from '@shared/models/widget.models'; +import { EChartsTooltipWidgetSettings } from '@home/components/widget/lib/chart/echarts-widget.models'; -export interface BarChartWithLabelsWidgetSettings { +export interface BarChartWithLabelsWidgetSettings extends EChartsTooltipWidgetSettings { showBarLabel: boolean; barLabelFont: Font; barLabelColor: string; @@ -33,15 +29,6 @@ export interface BarChartWithLabelsWidgetSettings { legendPosition: LegendPosition; legendLabelFont: Font; legendLabelColor: string; - showTooltip: boolean; - tooltipValueFont: Font; - tooltipValueColor: string; - tooltipShowDate: boolean; - tooltipDateFormat: DateFormatSettings; - tooltipDateFont: Font; - tooltipDateColor: string; - tooltipBackgroundColor: string; - tooltipBackgroundBlur: number; background: BackgroundSettings; } diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/chart/doughnut-widget.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/chart/doughnut-widget.component.ts index 928445d316..28550c339e 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/chart/doughnut-widget.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/chart/doughnut-widget.component.ts @@ -30,7 +30,6 @@ import { import { doughnutDefaultSettings, DoughnutLayout, - DoughnutLegendPosition, DoughnutTooltipValueType, DoughnutWidgetSettings } from '@home/components/widget/lib/chart/doughnut-widget.models'; @@ -49,25 +48,11 @@ import { TranslateService } from '@ngx-translate/core'; import { PieDataItemOption } from 'echarts/types/src/chart/pie/PieSeries'; import { formatValue, isDefinedAndNotNull, isNumeric } from '@core/utils'; import { SVG, Svg, Text } from '@svgdotjs/svg.js'; -import { DataKey } from '@shared/models/widget.models'; -import { TooltipComponent, TooltipComponentOption } from 'echarts/components'; -import { PieChart, PieSeriesOption } from 'echarts/charts'; -import { SVGRenderer } from 'echarts/renderers'; +import { DataKey, LegendPosition } from '@shared/models/widget.models'; import { Observable } from 'rxjs'; import { ImagePipe } from '@shared/pipe/image.pipe'; import { DomSanitizer } from '@angular/platform-browser'; - -echarts.use([ - TooltipComponent, - PieChart, - SVGRenderer -]); - -type EChartsOption = echarts.ComposeOption< - | TooltipComponentOption - | PieSeriesOption ->; -type ECharts = echarts.ECharts; +import { ECharts, echartsModule, EChartsOption } from '@home/components/widget/lib/chart/echarts-widget.models'; const shapeSize = 134; const shapeSegmentWidth = 13.4; @@ -178,7 +163,7 @@ export class DoughnutWidgetComponent implements OnInit, OnDestroy, AfterViewInit if (this.showLegend) { this.legendItems = []; this.legendClass = `legend-${this.settings.legendPosition}`; - this.legendHorizontal = [DoughnutLegendPosition.left, DoughnutLegendPosition.right].includes(this.settings.legendPosition); + this.legendHorizontal = [LegendPosition.left, LegendPosition.right].includes(this.settings.legendPosition); this.legendLabelStyle = textStyle(this.settings.legendLabelFont); this.disabledLegendLabelStyle = textStyle(this.settings.legendLabelFont); this.legendLabelStyle.color = this.settings.legendLabelColor; @@ -387,6 +372,7 @@ export class DoughnutWidgetComponent implements OnInit, OnDestroy, AfterViewInit } private drawDoughnut() { + echartsModule.init(); const shapeWidth = this.doughnutShape.nativeElement.getBoundingClientRect().width; const shapeHeight = this.doughnutShape.nativeElement.getBoundingClientRect().height; const size = this.settings.autoScale ? shapeSize : Math.min(shapeWidth, shapeHeight); diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/chart/doughnut-widget.models.ts b/ui-ngx/src/app/modules/home/components/widget/lib/chart/doughnut-widget.models.ts index 1771dbbb8a..52507dc2b5 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/chart/doughnut-widget.models.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/chart/doughnut-widget.models.ts @@ -21,6 +21,7 @@ import { constantColor, Font } from '@shared/models/widget-settings.models'; +import { LegendPosition } from '@shared/models/widget.models'; export enum DoughnutLayout { default = 'default', @@ -50,24 +51,6 @@ export const horizontalDoughnutLayoutImages = new Map( ] ); -export enum DoughnutLegendPosition { - top = 'top', - bottom = 'bottom', - left = 'left', - right = 'right' -} - -export const doughnutLegendPositions = Object.keys(DoughnutLegendPosition) as DoughnutLegendPosition[]; - -export const doughnutLegendPositionTranslations = new Map( - [ - [DoughnutLegendPosition.top, 'widgets.doughnut.legend-position-top'], - [DoughnutLegendPosition.bottom, 'widgets.doughnut.legend-position-bottom'], - [DoughnutLegendPosition.left, 'widgets.doughnut.legend-position-left'], - [DoughnutLegendPosition.right, 'widgets.doughnut.legend-position-right'] - ] -); - export enum DoughnutTooltipValueType { absolute = 'absolute', percentage = 'percentage' @@ -90,7 +73,7 @@ export interface DoughnutWidgetSettings { totalValueFont: Font; totalValueColor: ColorSettings; showLegend: boolean; - legendPosition: DoughnutLegendPosition; + legendPosition: LegendPosition; legendLabelFont: Font; legendLabelColor: string; legendValueFont: Font; @@ -120,7 +103,7 @@ export const doughnutDefaultSettings = (horizontal: boolean): DoughnutWidgetSett }, totalValueColor: constantColor('rgba(0, 0, 0, 0.87)'), showLegend: true, - legendPosition: horizontal ? DoughnutLegendPosition.right : DoughnutLegendPosition.bottom, + legendPosition: horizontal ? LegendPosition.right : LegendPosition.bottom, legendLabelFont: { family: 'Roboto', size: 12, diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/chart/echarts-widget.models.ts b/ui-ngx/src/app/modules/home/components/widget/lib/chart/echarts-widget.models.ts new file mode 100644 index 0000000000..3587a246ae --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/lib/chart/echarts-widget.models.ts @@ -0,0 +1,214 @@ +/// +/// Copyright © 2016-2023 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 * as echarts from 'echarts/core'; +import { Axis } from 'echarts'; +import AxisModel from 'echarts/types/src/coord/cartesian/AxisModel'; +import { formatValue, isNumber } from '@core/utils'; +import TimeScale from 'echarts/types/src/scale/Time'; +import { + DataZoomComponent, DataZoomComponentOption, + GridComponent, GridComponentOption, + MarkLineComponent, MarkLineComponentOption, + TooltipComponent, TooltipComponentOption, + VisualMapComponent, VisualMapComponentOption +} from 'echarts/components'; +import { + BarChart, + LineChart, + CustomChart, + CustomSeriesOption, + LineSeriesOption, + BarSeriesOption, PieSeriesOption, PieChart +} from 'echarts/charts'; +import { LabelLayout } from 'echarts/features'; +import { CanvasRenderer, SVGRenderer } from 'echarts/renderers'; +import { DataSet } from '@shared/models/widget.models'; +import { CallbackDataParams } from 'echarts/types/dist/shared'; +import { Renderer2 } from '@angular/core'; +import { DateFormatProcessor, DateFormatSettings, Font } from '@shared/models/widget-settings.models'; + +class EChartsModule { + private initialized = false; + + init() { + if (!this.initialized) { + const axisGetBandWidth = Axis.prototype.getBandWidth; + + Axis.prototype.getBandWidth = function(){ + const model: AxisModel = this.model; + const axisOption = model.option; + const tbTimewindowInterval = (axisOption as any).tbTimewindowInterval; + if (this.scale.type === 'time' && isNumber(tbTimewindowInterval)) { + const timeScale: TimeScale = this.scale; + const axisExtent: [number, number] = this._extent; + const dataExtent = timeScale.getExtent(); + const size = Math.abs(axisExtent[1] - axisExtent[0]); + return tbTimewindowInterval * (size / (dataExtent[1] - dataExtent[0])); + } else { + return axisGetBandWidth.call(this); + } + }; + + echarts.use([ + TooltipComponent, + GridComponent, + VisualMapComponent, + DataZoomComponent, + MarkLineComponent, + LineChart, + BarChart, + PieChart, + CustomChart, + LabelLayout, + CanvasRenderer, + SVGRenderer + ]); + + this.initialized = true; + } + } +} + +export const echartsModule = new EChartsModule(); + +export type EChartsOption = echarts.ComposeOption< + | TooltipComponentOption + | GridComponentOption + | VisualMapComponentOption + | DataZoomComponentOption + | MarkLineComponentOption + | LineSeriesOption + | CustomSeriesOption + | BarSeriesOption + | PieSeriesOption +>; + +export type ECharts = echarts.ECharts; + +export type NamedDataSet = {name: string; value: [number, any]}[]; + +export const toNamedData = (data: DataSet): NamedDataSet => { + if (!data?.length) { + return []; + } else { + return data.map(d => ({ + name: d[0] + '', + value: d + })); + } +}; + +export interface EChartsTooltipWidgetSettings { + showTooltip: boolean; + tooltipValueFont: Font; + tooltipValueColor: string; + tooltipShowDate: boolean; + tooltipDateFormat: DateFormatSettings; + tooltipDateFont: Font; + tooltipDateColor: string; + tooltipBackgroundColor: string; + tooltipBackgroundBlur: number; +} + +export const echartsTooltipFormatter = (renderer: Renderer2, + tooltipDateFormat: DateFormatProcessor, + settings: EChartsTooltipWidgetSettings, + params: CallbackDataParams[], + decimals: number, + units: string, + focusedSeriesIndex: number): null | HTMLElement => { + if (!params.length || !params[0]) { + return null; + } + const tooltipElement: HTMLElement = renderer.createElement('div'); + renderer.setStyle(tooltipElement, 'display', 'flex'); + renderer.setStyle(tooltipElement, 'flex-direction', 'column'); + renderer.setStyle(tooltipElement, 'align-items', 'flex-start'); + renderer.setStyle(tooltipElement, 'gap', '4px'); + if (settings.tooltipShowDate) { + const dateElement: HTMLElement = renderer.createElement('div'); + const ts = params[0].value[0]; + tooltipDateFormat.update(ts); + renderer.appendChild(dateElement, renderer.createText(tooltipDateFormat.formatted)); + renderer.setStyle(dateElement, 'font-family', settings.tooltipDateFont.family); + renderer.setStyle(dateElement, 'font-size', settings.tooltipDateFont.size + settings.tooltipDateFont.sizeUnit); + renderer.setStyle(dateElement, 'font-style', settings.tooltipDateFont.style); + renderer.setStyle(dateElement, 'font-weight', settings.tooltipDateFont.weight); + renderer.setStyle(dateElement, 'line-height', settings.tooltipDateFont.lineHeight); + renderer.setStyle(dateElement, 'color', settings.tooltipDateColor); + renderer.appendChild(tooltipElement, dateElement); + } + let seriesParams: CallbackDataParams = null; + if (focusedSeriesIndex > -1) { + seriesParams = params.find(param => param.seriesIndex === focusedSeriesIndex); + } + if (seriesParams) { + renderer.appendChild(tooltipElement, constructEchartsTooltipSeriesElement(renderer, settings, seriesParams, decimals, units)); + } else { + for (seriesParams of params) { + renderer.appendChild(tooltipElement, constructEchartsTooltipSeriesElement(renderer, settings, seriesParams, decimals, units)); + } + } + return tooltipElement; +}; + +const constructEchartsTooltipSeriesElement = (renderer: Renderer2, + settings: EChartsTooltipWidgetSettings, + seriesParams: CallbackDataParams, + decimals: number, + units: string): HTMLElement => { + const labelValueElement: HTMLElement = renderer.createElement('div'); + renderer.setStyle(labelValueElement, 'display', 'flex'); + renderer.setStyle(labelValueElement, 'flex-direction', 'row'); + renderer.setStyle(labelValueElement, 'align-items', 'center'); + renderer.setStyle(labelValueElement, 'align-self', 'stretch'); + renderer.setStyle(labelValueElement, 'gap', '12px'); + const labelElement: HTMLElement = renderer.createElement('div'); + renderer.setStyle(labelElement, 'display', 'flex'); + renderer.setStyle(labelElement, 'align-items', 'center'); + renderer.setStyle(labelElement, 'gap', '8px'); + renderer.appendChild(labelValueElement, labelElement); + const circleElement: HTMLElement = renderer.createElement('div'); + renderer.setStyle(circleElement, 'width', '8px'); + renderer.setStyle(circleElement, 'height', '8px'); + renderer.setStyle(circleElement, 'border-radius', '50%'); + renderer.setStyle(circleElement, 'background', seriesParams.color); + renderer.appendChild(labelElement, circleElement); + const labelTextElement: HTMLElement = renderer.createElement('div'); + renderer.appendChild(labelTextElement, renderer.createText(seriesParams.seriesName)); + renderer.setStyle(labelTextElement, 'font-family', 'Roboto'); + renderer.setStyle(labelTextElement, 'font-size', '12px'); + renderer.setStyle(labelTextElement, 'font-style', 'normal'); + renderer.setStyle(labelTextElement, 'font-weight', '400'); + renderer.setStyle(labelTextElement, 'line-height', '16px'); + renderer.setStyle(labelTextElement, 'letter-spacing', '0.4px'); + renderer.setStyle(labelTextElement, 'color', 'rgba(0, 0, 0, 0.76)'); + renderer.appendChild(labelElement, labelTextElement); + const valueElement: HTMLElement = renderer.createElement('div'); + const value = formatValue(seriesParams.value[1], decimals, units, false); + renderer.appendChild(valueElement, renderer.createText(value)); + renderer.setStyle(valueElement, 'flex', '1'); + renderer.setStyle(valueElement, 'text-align', 'end'); + renderer.setStyle(valueElement, 'font-family', settings.tooltipValueFont.family); + renderer.setStyle(valueElement, 'font-size', settings.tooltipValueFont.size + settings.tooltipValueFont.sizeUnit); + renderer.setStyle(valueElement, 'font-style', settings.tooltipValueFont.style); + renderer.setStyle(valueElement, 'font-weight', settings.tooltipValueFont.weight); + renderer.setStyle(valueElement, 'line-height', settings.tooltipValueFont.lineHeight); + renderer.setStyle(valueElement, 'color', settings.tooltipValueColor); + renderer.appendChild(labelValueElement, valueElement); + return labelValueElement; +}; diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/chart/range-chart-widget.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/chart/range-chart-widget.component.ts index 4625e4a2a9..4ff9c53a71 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/chart/range-chart-widget.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/chart/range-chart-widget.component.ts @@ -32,7 +32,8 @@ import { backgroundStyle, ColorRange, ComponentStyle, - DateFormatProcessor, filterIncludingColorRanges, + DateFormatProcessor, + filterIncludingColorRanges, getDataKey, overlayStyle, sortedColorRange, @@ -41,46 +42,18 @@ import { import { ResizeObserver } from '@juggle/resize-observer'; import * as echarts from 'echarts/core'; import { formatValue, isDefinedAndNotNull, isNumber } from '@core/utils'; -import { - DataZoomComponent, - DataZoomComponentOption, - GridComponent, - GridComponentOption, - MarkLineComponent, - MarkLineComponentOption, - TooltipComponent, - TooltipComponentOption, - VisualMapComponent, - VisualMapComponentOption -} from 'echarts/components'; -import { LineChart, LineSeriesOption, } from 'echarts/charts'; -import { CanvasRenderer } from 'echarts/renderers'; import { rangeChartDefaultSettings, RangeChartWidgetSettings } from './range-chart-widget.models'; -import { DataSet } from '@shared/models/widget.models'; import { Observable } from 'rxjs'; import { ImagePipe } from '@shared/pipe/image.pipe'; import { DomSanitizer } from '@angular/platform-browser'; - -echarts.use([ - TooltipComponent, - GridComponent, - VisualMapComponent, - DataZoomComponent, - MarkLineComponent, - LineChart, - CanvasRenderer -]); - -type EChartsOption = echarts.ComposeOption< - | TooltipComponentOption - | GridComponentOption - | VisualMapComponentOption - | DataZoomComponentOption - | MarkLineComponentOption - | LineSeriesOption ->; - -type ECharts = echarts.ECharts; +import { + ECharts, + echartsModule, + EChartsOption, + echartsTooltipFormatter, + toNamedData +} from '@home/components/widget/lib/chart/echarts-widget.models'; +import { CallbackDataParams } from 'echarts/types/dist/shared'; interface VisualPiece { lt?: number; @@ -180,17 +153,6 @@ const toRangeItems = (colorRanges: Array): RangeItem[] => { return rangeItems; }; -const toNamedData = (data: DataSet): {name: string; value: [number, any]}[] => { - if (!data?.length) { - return []; - } else { - return data.map(d => ({ - name: d[0] + '', - value: d - })); - } -}; - const getMarkPoints = (ranges: Array): number[] => { const points = new Set(); for (const range of ranges) { @@ -346,6 +308,7 @@ export class RangeChartWidgetComponent implements OnInit, OnDestroy, AfterViewIn } private drawChart() { + echartsModule.init(); const dataKey = getDataKey(this.ctx.datasources); this.rangeChart = echarts.init(this.chartShape.nativeElement, null, { renderer: 'canvas', @@ -379,7 +342,7 @@ export class RangeChartWidgetComponent implements OnInit, OnDestroy, AfterViewIn yAxis: { type: 'value', axisLabel: { - formatter: value => formatValue(value, this.decimals, this.units, false) + formatter: (value: any) => formatValue(value, this.decimals, this.units, false) } }, series: [{ @@ -442,71 +405,11 @@ export class RangeChartWidgetComponent implements OnInit, OnDestroy, AfterViewIn if (this.settings.showTooltip) { this.rangeChartOptions.tooltip = { trigger: 'axis', - formatter: (params) => { - if (!params.length || !params[0]) { - return null; - } - const seriesParams = params[0]; - const value = formatValue(seriesParams.value[1], this.decimals, this.units, false); - const tooltipElement: HTMLElement = this.renderer.createElement('div'); - this.renderer.setStyle(tooltipElement, 'display', 'flex'); - this.renderer.setStyle(tooltipElement, 'flex-direction', 'column'); - this.renderer.setStyle(tooltipElement, 'align-items', 'flex-start'); - this.renderer.setStyle(tooltipElement, 'gap', '4px'); - if (this.settings.tooltipShowDate) { - const dateElement: HTMLElement = this.renderer.createElement('div'); - const ts = seriesParams.value[0]; - this.tooltipDateFormat.update(ts); - this.renderer.appendChild(dateElement, this.renderer.createText(this.tooltipDateFormat.formatted)); - this.renderer.setStyle(dateElement, 'font-family', this.settings.tooltipDateFont.family); - this.renderer.setStyle(dateElement, 'font-size', this.settings.tooltipDateFont.size + this.settings.tooltipDateFont.sizeUnit); - this.renderer.setStyle(dateElement, 'font-style', this.settings.tooltipDateFont.style); - this.renderer.setStyle(dateElement, 'font-weight', this.settings.tooltipDateFont.weight); - this.renderer.setStyle(dateElement, 'line-height', this.settings.tooltipDateFont.lineHeight); - this.renderer.setStyle(dateElement, 'color', this.settings.tooltipDateColor); - this.renderer.appendChild(tooltipElement, dateElement); - } - const labelValueElement: HTMLElement = this.renderer.createElement('div'); - this.renderer.setStyle(labelValueElement, 'display', 'flex'); - this.renderer.setStyle(labelValueElement, 'flex-direction', 'row'); - this.renderer.setStyle(labelValueElement, 'align-items', 'center'); - this.renderer.setStyle(labelValueElement, 'align-self', 'stretch'); - this.renderer.setStyle(labelValueElement, 'gap', '12px'); - this.renderer.appendChild(tooltipElement, labelValueElement); - const labelElement: HTMLElement = this.renderer.createElement('div'); - this.renderer.setStyle(labelElement, 'display', 'flex'); - this.renderer.setStyle(labelElement, 'align-items', 'center'); - this.renderer.setStyle(labelElement, 'gap', '8px'); - this.renderer.appendChild(labelValueElement, labelElement); - const circleElement: HTMLElement = this.renderer.createElement('div'); - this.renderer.setStyle(circleElement, 'width', '8px'); - this.renderer.setStyle(circleElement, 'height', '8px'); - this.renderer.setStyle(circleElement, 'border-radius', '50%'); - this.renderer.setStyle(circleElement, 'background', seriesParams.color); - this.renderer.appendChild(labelElement, circleElement); - const labelTextElement: HTMLElement = this.renderer.createElement('div'); - this.renderer.appendChild(labelTextElement, this.renderer.createText(seriesParams.seriesName)); - this.renderer.setStyle(labelTextElement, 'font-family', 'Roboto'); - this.renderer.setStyle(labelTextElement, 'font-size', '12px'); - this.renderer.setStyle(labelTextElement, 'font-style', 'normal'); - this.renderer.setStyle(labelTextElement, 'font-weight', '400'); - this.renderer.setStyle(labelTextElement, 'line-height', '16px'); - this.renderer.setStyle(labelTextElement, 'letter-spacing', '0.4px'); - this.renderer.setStyle(labelTextElement, 'color', 'rgba(0, 0, 0, 0.76)'); - this.renderer.appendChild(labelElement, labelTextElement); - const valueElement: HTMLElement = this.renderer.createElement('div'); - this.renderer.appendChild(valueElement, this.renderer.createText(value)); - this.renderer.setStyle(valueElement, 'font-family', this.settings.tooltipValueFont.family); - this.renderer.setStyle(valueElement, 'font-size', this.settings.tooltipValueFont.size + this.settings.tooltipValueFont.sizeUnit); - this.renderer.setStyle(valueElement, 'font-style', this.settings.tooltipValueFont.style); - this.renderer.setStyle(valueElement, 'font-weight', this.settings.tooltipValueFont.weight); - this.renderer.setStyle(valueElement, 'line-height', this.settings.tooltipValueFont.lineHeight); - this.renderer.setStyle(valueElement, 'color', this.settings.tooltipValueColor); - this.renderer.appendChild(labelValueElement, valueElement); - return tooltipElement; - }, + formatter: (params: CallbackDataParams[]) => echartsTooltipFormatter(this.renderer, this.tooltipDateFormat, + this.settings, params, this.decimals, this.units, 0), padding: [8, 12], backgroundColor: this.settings.tooltipBackgroundColor, + borderWidth: 0, extraCssText: `line-height: 1; backdrop-filter: blur(${this.settings.tooltipBackgroundBlur}px);` }; } diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/chart/range-chart-widget.models.ts b/ui-ngx/src/app/modules/home/components/widget/lib/chart/range-chart-widget.models.ts index 6bcd0c1497..0c8bb73150 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/chart/range-chart-widget.models.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/chart/range-chart-widget.models.ts @@ -18,12 +18,13 @@ import { BackgroundSettings, BackgroundType, ColorRange, - DateFormatSettings, - Font, simpleDateFormat + Font, + simpleDateFormat } from '@shared/models/widget-settings.models'; import { LegendPosition } from '@shared/models/widget.models'; +import { EChartsTooltipWidgetSettings } from '@home/components/widget/lib/chart/echarts-widget.models'; -export interface RangeChartWidgetSettings { +export interface RangeChartWidgetSettings extends EChartsTooltipWidgetSettings { dataZoom: boolean; rangeColors: Array; outOfRangeColor: string; @@ -32,15 +33,6 @@ export interface RangeChartWidgetSettings { legendPosition: LegendPosition; legendLabelFont: Font; legendLabelColor: string; - showTooltip: boolean; - tooltipValueFont: Font; - tooltipValueColor: string; - tooltipShowDate: boolean; - tooltipDateFormat: DateFormatSettings; - tooltipDateFont: Font; - tooltipDateColor: string; - tooltipBackgroundColor: string; - tooltipBackgroundBlur: number; background: BackgroundSettings; } diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/bar-chart-with-labels-widget-settings.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/bar-chart-with-labels-widget-settings.component.html new file mode 100644 index 0000000000..5652d626ee --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/bar-chart-with-labels-widget-settings.component.html @@ -0,0 +1,150 @@ + + +
+
widgets.bar-chart.bar-chart-card-style
+
+ + {{ 'widgets.bar-chart.label-on-bar' | translate }} + +
+ + + + +
+
+
+ + {{ 'widgets.bar-chart.value-on-bar' | translate }} + +
+ + + + +
+
+
+ + + + + {{ 'widget-config.legend' | translate }} + + + + +
+
{{ 'legend.position' | translate }}
+ + + + {{ legendPositionTranslationMap.get(pos) | translate }} + + + +
+
+
{{ 'legend.label' | translate }}
+
+ + + + +
+
+
+
+
+
+ + + + + {{ 'widget-config.tooltip' | translate }} + + + + +
+
{{ 'tooltip.value' | translate }}
+
+ + + + +
+
+
+ + {{ 'tooltip.date' | translate }} + +
+ + + + + +
+
+
+
{{ 'tooltip.background-color' | translate }}
+ + +
+
+
{{ 'tooltip.background-blur' | translate }}
+ + +
px
+
+
+
+
+
+
+
{{ 'widgets.background.background' | translate }}
+ + +
+
+
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/bar-chart-with-labels-widget-settings.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/bar-chart-with-labels-widget-settings.component.ts new file mode 100644 index 0000000000..3eee431476 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/bar-chart-with-labels-widget-settings.component.ts @@ -0,0 +1,170 @@ +/// +/// Copyright © 2016-2023 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 { Component, Injector } from '@angular/core'; +import { + legendPositions, + legendPositionTranslationMap, + WidgetSettings, + WidgetSettingsComponent +} from '@shared/models/widget.models'; +import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms'; +import { Store } from '@ngrx/store'; +import { AppState } from '@core/core.state'; +import { formatValue } from '@core/utils'; +import { DateFormatProcessor, DateFormatSettings } from '@shared/models/widget-settings.models'; +import { + barChartWithLabelsDefaultSettings +} from '@home/components/widget/lib/chart/bar-chart-with-labels-widget.models'; + +@Component({ + selector: 'tb-bar-chart-with-labels-widget-settings', + templateUrl: './bar-chart-with-labels-widget-settings.component.html', + styleUrls: [] +}) +export class BarChartWithLabelsWidgetSettingsComponent extends WidgetSettingsComponent { + + legendPositions = legendPositions; + + legendPositionTranslationMap = legendPositionTranslationMap; + + barChartWidgetSettingsForm: UntypedFormGroup; + + tooltipValuePreviewFn = this._tooltipValuePreviewFn.bind(this); + + tooltipDatePreviewFn = this._tooltipDatePreviewFn.bind(this); + + constructor(protected store: Store, + private $injector: Injector, + private fb: UntypedFormBuilder) { + super(store); + } + + protected settingsForm(): UntypedFormGroup { + return this.barChartWidgetSettingsForm; + } + + protected defaultSettings(): WidgetSettings { + return {...barChartWithLabelsDefaultSettings}; + } + + protected onSettingsSet(settings: WidgetSettings) { + this.barChartWidgetSettingsForm = this.fb.group({ + + showBarLabel: [settings.showBarLabel, []], + barLabelFont: [settings.barLabelFont, []], + barLabelColor: [settings.barLabelColor, []], + showBarValue: [settings.showBarValue, []], + barValueFont: [settings.barValueFont, []], + barValueColor: [settings.barValueColor, []], + + showLegend: [settings.showLegend, []], + legendPosition: [settings.legendPosition, []], + legendLabelFont: [settings.legendLabelFont, []], + legendLabelColor: [settings.legendLabelColor, []], + + showTooltip: [settings.showTooltip, []], + tooltipValueFont: [settings.tooltipValueFont, []], + tooltipValueColor: [settings.tooltipValueColor, []], + tooltipShowDate: [settings.tooltipShowDate, []], + tooltipDateFormat: [settings.tooltipDateFormat, []], + tooltipDateFont: [settings.tooltipDateFont, []], + tooltipDateColor: [settings.tooltipDateColor, []], + tooltipBackgroundColor: [settings.tooltipBackgroundColor, []], + tooltipBackgroundBlur: [settings.tooltipBackgroundBlur, []], + + background: [settings.background, []] + }); + } + + protected validatorTriggers(): string[] { + return ['showBarLabel', 'showBarValue', 'showLegend', 'showTooltip', 'tooltipShowDate']; + } + + protected updateValidators(emitEvent: boolean) { + const showBarLabel: boolean = this.barChartWidgetSettingsForm.get('showBarLabel').value; + const showBarValue: boolean = this.barChartWidgetSettingsForm.get('showBarValue').value; + const showLegend: boolean = this.barChartWidgetSettingsForm.get('showLegend').value; + const showTooltip: boolean = this.barChartWidgetSettingsForm.get('showTooltip').value; + const tooltipShowDate: boolean = this.barChartWidgetSettingsForm.get('tooltipShowDate').value; + + if (showBarLabel) { + this.barChartWidgetSettingsForm.get('barLabelFont').enable(); + this.barChartWidgetSettingsForm.get('barLabelColor').enable(); + } else { + this.barChartWidgetSettingsForm.get('barLabelFont').disable(); + this.barChartWidgetSettingsForm.get('barLabelColor').disable(); + } + + if (showBarValue) { + this.barChartWidgetSettingsForm.get('barValueFont').enable(); + this.barChartWidgetSettingsForm.get('barValueColor').enable(); + } else { + this.barChartWidgetSettingsForm.get('barValueFont').disable(); + this.barChartWidgetSettingsForm.get('barValueColor').disable(); + } + + if (showLegend) { + this.barChartWidgetSettingsForm.get('legendPosition').enable(); + this.barChartWidgetSettingsForm.get('legendLabelFont').enable(); + this.barChartWidgetSettingsForm.get('legendLabelColor').enable(); + } else { + this.barChartWidgetSettingsForm.get('legendPosition').disable(); + this.barChartWidgetSettingsForm.get('legendLabelFont').disable(); + this.barChartWidgetSettingsForm.get('legendLabelColor').disable(); + } + + if (showTooltip) { + this.barChartWidgetSettingsForm.get('tooltipValueFont').enable(); + this.barChartWidgetSettingsForm.get('tooltipValueColor').enable(); + this.barChartWidgetSettingsForm.get('tooltipShowDate').enable({emitEvent: false}); + this.barChartWidgetSettingsForm.get('tooltipBackgroundColor').enable(); + this.barChartWidgetSettingsForm.get('tooltipBackgroundBlur').enable(); + if (tooltipShowDate) { + this.barChartWidgetSettingsForm.get('tooltipDateFormat').enable(); + this.barChartWidgetSettingsForm.get('tooltipDateFont').enable(); + this.barChartWidgetSettingsForm.get('tooltipDateColor').enable(); + } else { + this.barChartWidgetSettingsForm.get('tooltipDateFormat').disable(); + this.barChartWidgetSettingsForm.get('tooltipDateFont').disable(); + this.barChartWidgetSettingsForm.get('tooltipDateColor').disable(); + } + } else { + this.barChartWidgetSettingsForm.get('tooltipValueFont').disable(); + this.barChartWidgetSettingsForm.get('tooltipValueColor').disable(); + this.barChartWidgetSettingsForm.get('tooltipShowDate').disable({emitEvent: false}); + this.barChartWidgetSettingsForm.get('tooltipDateFormat').disable(); + this.barChartWidgetSettingsForm.get('tooltipDateFont').disable(); + this.barChartWidgetSettingsForm.get('tooltipDateColor').disable(); + this.barChartWidgetSettingsForm.get('tooltipBackgroundColor').disable(); + this.barChartWidgetSettingsForm.get('tooltipBackgroundBlur').disable(); + } + } + + private _tooltipValuePreviewFn(): string { + const units: string = this.widgetConfig.config.units; + const decimals: number = this.widgetConfig.config.decimals; + return formatValue(22, decimals, units, false); + } + + private _tooltipDatePreviewFn(): string { + const dateFormat: DateFormatSettings = this.barChartWidgetSettingsForm.get('tooltipDateFormat').value; + const processor = DateFormatProcessor.fromSettings(this.$injector, dateFormat); + processor.update(Date.now()); + return processor.formatted; + } + +} diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/doughnut-widget-settings.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/doughnut-widget-settings.component.html index a0e76da09c..3975ee5f98 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/doughnut-widget-settings.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/doughnut-widget-settings.component.html @@ -70,14 +70,14 @@
{{ 'legend.position' | translate }}
- - {{ doughnutLegendPositionTranslationMap.get(pos) | translate }} + + {{ legendPositionTranslationMap.get(pos) | translate }}
-
{{ 'widgets.doughnut.legend-label' | translate }}
+
{{ 'legend.label' | translate }}
@@ -89,7 +89,7 @@
-
{{ 'widgets.doughnut.legend-value' | translate }}
+
{{ 'legend.value' | translate }}
@@ -109,13 +109,13 @@ - {{ 'widgets.doughnut.tooltip' | translate }} + {{ 'widget-config.tooltip' | translate }}
-
{{ 'widgets.doughnut.tooltip-value' | translate }}
+
{{ 'tooltip.value' | translate }}
@@ -138,14 +138,14 @@
-
{{ 'widgets.doughnut.tooltip-background-color' | translate }}
+
{{ 'tooltip.background-color' | translate }}
-
{{ 'widgets.doughnut.tooltip-background-blur' | translate }}
+
{{ 'tooltip.background-blur' | translate }}
px
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/doughnut-widget-settings.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/doughnut-widget-settings.component.ts index 220fc7c320..e9ad95be1b 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/doughnut-widget-settings.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/doughnut-widget-settings.component.ts @@ -15,7 +15,12 @@ /// import { Component } from '@angular/core'; -import { WidgetSettings, WidgetSettingsComponent } from '@shared/models/widget.models'; +import { + legendPositions, + legendPositionTranslationMap, + WidgetSettings, + WidgetSettingsComponent +} from '@shared/models/widget.models'; import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms'; import { Store } from '@ngrx/store'; import { AppState } from '@core/core.state'; @@ -26,8 +31,6 @@ import { doughnutLayoutImages, doughnutLayouts, doughnutLayoutTranslations, - doughnutLegendPositions, - doughnutLegendPositionTranslations, DoughnutTooltipValueType, doughnutTooltipValueTypes, doughnutTooltipValueTypeTranslations, @@ -55,9 +58,9 @@ export class DoughnutWidgetSettingsComponent extends WidgetSettingsComponent { doughnutLayoutImageMap: Map; - doughnutLegendPositions = doughnutLegendPositions; + legendPositions = legendPositions; - doughnutLegendPositionTranslationMap = doughnutLegendPositionTranslations; + legendPositionTranslationMap = legendPositionTranslationMap; doughnutTooltipValueTypes = doughnutTooltipValueTypes; diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/range-chart-widget-settings.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/range-chart-widget-settings.component.html index 155d09f53f..e3ce71491c 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/range-chart-widget-settings.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/range-chart-widget-settings.component.html @@ -62,7 +62,7 @@
-
{{ 'widgets.range-chart.legend-label' | translate }}
+
{{ 'legend.label' | translate }}
@@ -82,13 +82,13 @@ - {{ 'widgets.range-chart.tooltip' | translate }} + {{ 'widget-config.tooltip' | translate }}
-
{{ 'widgets.range-chart.tooltip-value' | translate }}
+
{{ 'tooltip.value' | translate }}
@@ -101,7 +101,7 @@
- {{ 'widgets.range-chart.tooltip-date' | translate }} + {{ 'tooltip.date' | translate }}
@@ -115,14 +115,14 @@
-
{{ 'widgets.range-chart.tooltip-background-color' | translate }}
+
{{ 'tooltip.background-color' | translate }}
-
{{ 'widgets.range-chart.tooltip-background-blur' | translate }}
+
{{ 'tooltip.background-blur' | translate }}
px
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/font-settings-panel.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/font-settings-panel.component.ts index 562001e3c4..3e7d328adf 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/font-settings-panel.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/font-settings-panel.component.ts @@ -27,7 +27,7 @@ import { import { PageComponent } from '@shared/components/page.component'; import { commonFonts, - ComponentStyle, + ComponentStyle, cssUnit, Font, fontStyles, fontStyleTranslations, @@ -73,6 +73,9 @@ export class FontSettingsPanelComponent extends PageComponent implements OnInit @coerceBoolean() disabledLineHeight = false; + @Input() + forceSizeUnit: cssUnit; + @Input() popover: TbPopoverComponent; @@ -106,7 +109,8 @@ export class FontSettingsPanelComponent extends PageComponent implements OnInit this.fontFormGroup = this.fb.group( { size: [{value: this.font?.size, disabled: this.autoScale}, [Validators.min(0)]], - sizeUnit: [{ value: (this.font?.sizeUnit || 'px'), disabled: this.autoScale}, []], + sizeUnit: [{ value: (!!this.forceSizeUnit ? + this.forceSizeUnit : (this.font?.sizeUnit || 'px')), disabled: this.autoScale || !!this.forceSizeUnit}, []], family: [this.font?.family, []], weight: [this.font?.weight, []], style: [this.font?.style, []], @@ -150,11 +154,14 @@ export class FontSettingsPanelComponent extends PageComponent implements OnInit } clearFont() { - this.fontFormGroup.reset({sizeUnit: 'px'}); + this.fontFormGroup.reset({sizeUnit: this.forceSizeUnit || 'px'}); this.fontFormGroup.markAsDirty(); } private updatePreviewStyle(font: Font) { + if (!!this.forceSizeUnit) { + font = {...font, ...{sizeUnit: this.forceSizeUnit}}; + } this.previewStyle = {...(this.initialPreviewStyle || {}), ...textStyle(font)}; } diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/font-settings.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/font-settings.component.ts index 0fc3b20da1..0530519c2d 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/font-settings.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/font-settings.component.ts @@ -16,7 +16,7 @@ import { Component, forwardRef, Input, OnInit, Renderer2, ViewContainerRef } from '@angular/core'; import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; -import { ComponentStyle, Font } from '@shared/models/widget-settings.models'; +import { ComponentStyle, cssUnit, Font } from '@shared/models/widget-settings.models'; import { MatButton } from '@angular/material/button'; import { TbPopoverService } from '@shared/components/popover.service'; import { FontSettingsPanelComponent } from '@home/components/widget/lib/settings/common/font-settings-panel.component'; @@ -58,6 +58,9 @@ export class FontSettingsComponent implements OnInit, ControlValueAccessor { @coerceBoolean() disabledLineHeight = false; + @Input() + forceSizeUnit: cssUnit; + private modelValue: Font; private propagateChange = null; @@ -97,7 +100,8 @@ export class FontSettingsComponent implements OnInit, ControlValueAccessor { initialPreviewStyle: this.initialPreviewStyle, clearButton: this.clearButton, autoScale: this.autoScale, - disabledLineHeight: this.disabledLineHeight + disabledLineHeight: this.disabledLineHeight, + forceSizeUnit: this.forceSizeUnit }; if (isDefinedAndNotNull(this.previewText)) { const previewText = typeof this.previewText === 'string' ? this.previewText : this.previewText(); diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/indicator/signal-strength-widget-settings.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/indicator/signal-strength-widget-settings.component.html index 808bbe11d9..19d3d98d5d 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/indicator/signal-strength-widget-settings.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/indicator/signal-strength-widget-settings.component.html @@ -70,14 +70,14 @@ - {{ 'widgets.signal-strength.tooltip' | translate }} + {{ 'widget-config.tooltip' | translate }}
- {{ 'widgets.signal-strength.value' | translate }} + {{ 'tooltip.value' | translate }}
- {{ 'widgets.signal-strength.date' | translate }} + {{ 'tooltip.date' | translate }}
@@ -105,13 +105,13 @@
-
{{ 'widgets.signal-strength.background-color' | translate }}
+
{{ 'tooltip.background-color' | translate }}
-
widgets.signal-strength.background-blur
+
tooltip.background-blur
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/widget-settings.module.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/widget-settings.module.ts index 5d1bce1745..ed53f82ffd 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/widget-settings.module.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/widget-settings.module.ts @@ -308,6 +308,9 @@ import { import { RangeChartWidgetSettingsComponent } from '@home/components/widget/lib/settings/chart/range-chart-widget-settings.component'; +import { + BarChartWithLabelsWidgetSettingsComponent +} from '@home/components/widget/lib/settings/chart/bar-chart-with-labels-widget-settings.component'; @NgModule({ declarations: [ @@ -420,7 +423,8 @@ import { ProgressBarWidgetSettingsComponent, LiquidLevelCardWidgetSettingsComponent, DoughnutWidgetSettingsComponent, - RangeChartWidgetSettingsComponent + RangeChartWidgetSettingsComponent, + BarChartWithLabelsWidgetSettingsComponent ], imports: [ CommonModule, @@ -538,7 +542,8 @@ import { ProgressBarWidgetSettingsComponent, LiquidLevelCardWidgetSettingsComponent, DoughnutWidgetSettingsComponent, - RangeChartWidgetSettingsComponent + RangeChartWidgetSettingsComponent, + BarChartWithLabelsWidgetSettingsComponent ] }) export class WidgetSettingsModule { @@ -622,5 +627,6 @@ export const widgetSettingsComponentsMap: {[key: string]: Type max) { - newIntervalMs = max; + } else if (newIntervalMs >= max && updateToPreferred) { + newIntervalMs = this.timeService.boundMaxInterval(max / 7); } if (!this.advanced) { newIntervalMs = this.timeService.boundToPredefinedInterval(min, max, newIntervalMs); @@ -159,7 +159,7 @@ export class TimeintervalComponent implements OnInit, ControlValueAccessor { } } - updateView() { + updateView(updateToPreferred = false) { if (!this.rendered) { return; } @@ -178,7 +178,7 @@ export class TimeintervalComponent implements OnInit, ControlValueAccessor { } this.modelValue = value; this.propagateChange(this.modelValue); - this.boundInterval(); + this.boundInterval(updateToPreferred); } calculateIntervalMs(): number { diff --git a/ui-ngx/src/assets/locale/locale.constant-en_US.json b/ui-ngx/src/assets/locale/locale.constant-en_US.json index 12de697bc8..de8d7706d5 100644 --- a/ui-ngx/src/assets/locale/locale.constant-en_US.json +++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json @@ -3159,7 +3159,9 @@ "weeks": "(week ago)", "months": "(month ago)", "years": "(year ago)" - } + }, + "label": "Label", + "value": "Value" }, "login": { "login": "Login", @@ -4276,6 +4278,12 @@ "displayTypePrefix": "Display Realtime/History prefix", "preview": "Preview" }, + "tooltip": { + "value": "Value", + "date": "Date", + "background-color": "Background color", + "background-blur": "Background blur" + }, "unit": { "millimeter": "Millimeter", "centimeter": "Centimeter", @@ -5152,6 +5160,12 @@ "blur": "Blur", "preview": "Preview" }, + "bar-chart": { + "bar-appearance": "Bar appearance", + "label-on-bar": "Label on bar", + "value-on-bar": "Value on bar", + "bar-chart-card-style": "Bar chart card style" + }, "battery-level": { "layout": "Layout", "layout-vertical-solid": "Vertical. Solid", @@ -5177,9 +5191,6 @@ "date": "Date", "active-bars-color": "Active signal bars color", "inactive-bars-color": "Inactive signal bars color", - "tooltip": "Tooltip", - "background-color": "Background color", - "background-blur": "Background blur", "signal-strength-card-style": "Signal strength card style" }, "chart": { @@ -5422,18 +5433,8 @@ "clockwise-layout": "Clockwise layout", "sort-series": "Sort series by label", "central-total-value": "Central total value", - "legend-position-top": "Top", - "legend-position-bottom": "Bottom", - "legend-position-left": "Left", - "legend-position-right": "Right", - "legend-label": "Label", - "legend-value": "Value", - "tooltip": "Tooltip", - "tooltip-value": "Value", "tooltip-value-type-absolute": "Absolute", "tooltip-value-type-percentage": "Percentage", - "tooltip-background-color": "Background color", - "tooltip-background-blur": "Background blur", "doughnut-card-style": "Doughnut card style" }, "entities-hierarchy": { @@ -5915,12 +5916,6 @@ "range-colors": "Range colors", "out-of-range-color": "Out of range color", "fill-area": "Fill area", - "legend-label": "Label", - "tooltip": "Tooltip", - "tooltip-value": "Value", - "tooltip-date": "Date", - "tooltip-background-color": "Background color", - "tooltip-background-blur": "Background blur", "range-chart-card-style": "Range chart card style" }, "rpc": { diff --git a/ui-ngx/src/assets/locale/locale.constant-zh_CN.json b/ui-ngx/src/assets/locale/locale.constant-zh_CN.json index f0d07fa506..28c4d20f59 100644 --- a/ui-ngx/src/assets/locale/locale.constant-zh_CN.json +++ b/ui-ngx/src/assets/locale/locale.constant-zh_CN.json @@ -3087,7 +3087,9 @@ "weeks": "(一周前)", "months": "(一个月前)", "years": "(一年前)" - } + }, + "label": "标签", + "value": "值" }, "login": { "login": "登录", @@ -4197,6 +4199,12 @@ "displayTypePrefix": "显示实时/历史前缀", "preview": "预览" }, + "tooltip": { + "value": "值", + "date": "日期", + "background-color": "背景颜色", + "background-blur": "背景模糊" + }, "unit": { "millimeter": "mm", "centimeter": "cm", @@ -5082,9 +5090,6 @@ "date": "日期", "active-bars-color": "活动信号条颜色", "inactive-bars-color": "非活动信号条颜色", - "tooltip": "文字提示", - "background-color": "背景颜色", - "background-blur": "背景模糊", "signal-strength-card-style": "信号强度卡片样式" }, "chart": { @@ -5327,18 +5332,8 @@ "clockwise-layout": "顺时针布局", "sort-series": "按标签对系列排序", "central-total-value": "中央总计值", - "legend-position-top": "顶部", - "legend-position-bottom": "底部", - "legend-position-left": "左侧", - "legend-position-right": "右侧", - "legend-label": "标签", - "legend-value": "值", - "tooltip": "文字提示", - "tooltip-value": "值", "tooltip-value-type-absolute": "绝对值", "tooltip-value-type-percentage": "百分比", - "tooltip-background-color": "背景颜色", - "tooltip-background-blur": "背景模糊", "doughnut-card-style": "圆环样式" }, "entities-hierarchy": { @@ -5820,12 +5815,6 @@ "range-colors": "范围颜色", "out-of-range-color": "超出范围颜色", "fill-area": "填充区域", - "legend-label": "标签", - "tooltip": "文字提示", - "tooltip-value": "值", - "tooltip-date": "日期", - "tooltip-background-color": "背景颜色", - "tooltip-background-blur": "背景模糊", "range-chart-card-style": "范围图表卡片样式" }, "rpc": { From c5a72ed8dfc6d857521d270f43227eea14aae72c Mon Sep 17 00:00:00 2001 From: Igor Kulikov Date: Tue, 9 Jan 2024 10:46:16 +0200 Subject: [PATCH 055/179] Update license header to 2024 year. --- .github/release.yml | 2 +- .github/workflows/check-configuration-files.yml | 2 +- application/pom.xml | 2 +- application/src/main/conf/logback.xml | 2 +- application/src/main/conf/thingsboard.conf | 2 +- .../main/data/upgrade/1.3.0/schema_update.cql | 2 +- .../main/data/upgrade/1.3.1/schema_update.sql | 2 +- .../main/data/upgrade/1.4.0/schema_update.cql | 2 +- .../main/data/upgrade/1.4.0/schema_update.sql | 2 +- .../main/data/upgrade/2.0.0/schema_update.cql | 2 +- .../main/data/upgrade/2.0.0/schema_update.sql | 2 +- .../main/data/upgrade/2.1.1/schema_update.cql | 2 +- .../main/data/upgrade/2.1.1/schema_update.sql | 2 +- .../main/data/upgrade/2.1.2/schema_update.cql | 2 +- .../main/data/upgrade/2.1.2/schema_update.sql | 2 +- .../main/data/upgrade/2.2.0/schema_update.sql | 2 +- .../main/data/upgrade/2.3.1/schema_update.sql | 2 +- .../main/data/upgrade/2.4.0/schema_update.sql | 2 +- .../main/data/upgrade/2.4.2/schema_update.sql | 2 +- .../2.4.3/schema_update_psql_drop_partitions.sql | 2 +- .../data/upgrade/2.4.3/schema_update_psql_ts.sql | 2 +- .../upgrade/2.4.3/schema_update_timescale_ts.sql | 2 +- .../data/upgrade/2.4.3/schema_update_ttl.sql | 2 +- .../main/data/upgrade/3.0.1/schema_ts_latest.sql | 2 +- .../data/upgrade/3.0.1/schema_update_to_uuid.sql | 2 +- .../main/data/upgrade/3.1.0/schema_update.sql | 2 +- .../data/upgrade/3.1.1/schema_update_after.sql | 2 +- .../data/upgrade/3.1.1/schema_update_before.sql | 2 +- .../main/data/upgrade/3.2.1/schema_update.sql | 2 +- .../data/upgrade/3.2.1/schema_update_ttl.sql | 2 +- .../main/data/upgrade/3.2.2/schema_update.sql | 2 +- .../data/upgrade/3.2.2/schema_update_event.sql | 2 +- .../data/upgrade/3.2.2/schema_update_ttl.sql | 2 +- .../main/data/upgrade/3.3.2/schema_update.sql | 2 +- .../3.3.2/schema_update_lwm2m_bootstrap.sql | 2 +- .../upgrade/3.3.3/schema_event_ttl_procedure.sql | 2 +- .../main/data/upgrade/3.3.3/schema_update.sql | 2 +- .../main/data/upgrade/3.3.4/schema_update.sql | 2 +- .../main/data/upgrade/3.4.0/schema_update.sql | 2 +- .../main/data/upgrade/3.4.1/schema_update.sql | 2 +- .../data/upgrade/3.4.1/schema_update_after.sql | 2 +- .../data/upgrade/3.4.1/schema_update_before.sql | 2 +- .../main/data/upgrade/3.4.4/schema_update.sql | 2 +- .../main/data/upgrade/3.5.0/schema_update.sql | 2 +- .../main/data/upgrade/3.5.1/schema_update.sql | 2 +- .../main/data/upgrade/3.6.0/schema_update.sql | 2 +- .../3.6.1/save_attributes_node_update.sql | 2 +- .../main/data/upgrade/3.6.1/schema_update.sql | 2 +- .../main/data/upgrade/3.6.2/schema_update.sql | 2 +- .../server/ThingsboardInstallApplication.java | 2 +- .../server/ThingsboardServerApplication.java | 2 +- .../server/actors/ActorSystemContext.java | 2 +- .../actors/TbEntityTypeActorIdPredicate.java | 2 +- .../thingsboard/server/actors/app/AppActor.java | 2 +- .../server/actors/app/AppInitMsg.java | 2 +- .../server/actors/device/DeviceActor.java | 2 +- .../server/actors/device/DeviceActorCreator.java | 2 +- .../device/DeviceActorMessageProcessor.java | 2 +- .../server/actors/device/SessionInfo.java | 2 +- .../actors/device/SessionInfoMetaData.java | 2 +- .../actors/device/SessionTimeoutCheckMsg.java | 2 +- .../device/ToDeviceRpcRequestMetadata.java | 2 +- .../device/ToServerRpcRequestMetadata.java | 2 +- .../actors/ruleChain/DefaultTbContext.java | 2 +- .../server/actors/ruleChain/RuleChainActor.java | 2 +- .../RuleChainActorMessageProcessor.java | 2 +- .../actors/ruleChain/RuleChainInputMsg.java | 2 +- .../actors/ruleChain/RuleChainManagerActor.java | 2 +- .../actors/ruleChain/RuleChainOutputMsg.java | 2 +- .../ruleChain/RuleChainToRuleChainMsg.java | 2 +- .../actors/ruleChain/RuleChainToRuleNodeMsg.java | 2 +- .../ruleChain/RuleEngineComponentActor.java | 2 +- .../server/actors/ruleChain/RuleNodeActor.java | 2 +- .../ruleChain/RuleNodeActorMessageProcessor.java | 2 +- .../server/actors/ruleChain/RuleNodeCtx.java | 2 +- .../actors/ruleChain/RuleNodeRelation.java | 2 +- .../RuleNodeToRuleChainTellNextMsg.java | 2 +- .../actors/ruleChain/RuleNodeToSelfMsg.java | 2 +- .../actors/ruleChain/TbToRuleChainActorMsg.java | 2 +- .../actors/ruleChain/TbToRuleNodeActorMsg.java | 2 +- .../server/actors/service/ActorService.java | 2 +- .../server/actors/service/ComponentActor.java | 2 +- .../server/actors/service/ContextAwareActor.java | 2 +- .../actors/service/ContextBasedCreator.java | 2 +- .../actors/service/DefaultActorService.java | 2 +- .../shared/AbstractContextAwareMsgProcessor.java | 2 +- .../actors/shared/ActorTerminationMsg.java | 2 +- .../actors/shared/ComponentMsgProcessor.java | 2 +- .../actors/shared/RuleChainErrorActor.java | 2 +- .../server/actors/stats/StatsActor.java | 2 +- .../server/actors/stats/StatsPersistMsg.java | 2 +- .../server/actors/stats/StatsPersistTick.java | 2 +- .../server/actors/tenant/DebugTbRateLimits.java | 2 +- .../server/actors/tenant/TenantActor.java | 2 +- .../thingsboard/server/config/CryptoConfig.java | 2 +- ...CustomOAuth2AuthorizationRequestResolver.java | 2 +- .../server/config/MvcCorsProperties.java | 2 +- .../server/config/RateLimitProcessingFilter.java | 2 +- .../server/config/SchedulingConfiguration.java | 2 +- .../server/config/SwaggerConfiguration.java | 2 +- .../TbRuleEngineSecurityConfiguration.java | 2 +- .../config/ThingsboardMessageConfiguration.java | 2 +- .../config/ThingsboardSecurityConfiguration.java | 2 +- .../org/thingsboard/server/config/WebConfig.java | 2 +- .../server/config/WebSocketConfiguration.java | 2 +- .../server/controller/AbstractRpcController.java | 2 +- .../server/controller/AdminController.java | 2 +- .../controller/AlarmCommentController.java | 2 +- .../server/controller/AlarmController.java | 2 +- .../server/controller/AssetController.java | 2 +- .../controller/AssetProfileController.java | 2 +- .../server/controller/AuditLogController.java | 2 +- .../server/controller/AuthController.java | 2 +- .../server/controller/AutoCommitController.java | 2 +- .../server/controller/BaseController.java | 2 +- .../ComponentDescriptorController.java | 2 +- .../server/controller/ControllerConstants.java | 2 +- .../server/controller/CustomerController.java | 2 +- .../server/controller/DashboardController.java | 2 +- .../controller/DeviceConnectivityController.java | 2 +- .../server/controller/DeviceController.java | 2 +- .../controller/DeviceProfileController.java | 2 +- .../server/controller/EdgeController.java | 2 +- .../server/controller/EdgeEventController.java | 2 +- .../EntitiesVersionControlController.java | 2 +- .../server/controller/EntityQueryController.java | 2 +- .../controller/EntityRelationController.java | 2 +- .../server/controller/EntityViewController.java | 2 +- .../server/controller/EventController.java | 2 +- .../controller/HttpValidationCallback.java | 2 +- .../server/controller/ImageController.java | 2 +- .../server/controller/Lwm2mController.java | 2 +- .../controller/MailConfigTemplateController.java | 2 +- .../controller/NotificationController.java | 2 +- .../controller/NotificationRuleController.java | 2 +- .../controller/NotificationTargetController.java | 2 +- .../NotificationTemplateController.java | 2 +- .../OAuth2ConfigTemplateController.java | 2 +- .../server/controller/OAuth2Controller.java | 2 +- .../server/controller/OtaPackageController.java | 2 +- .../server/controller/QueueController.java | 2 +- .../server/controller/RpcV1Controller.java | 2 +- .../server/controller/RpcV2Controller.java | 2 +- .../server/controller/RuleChainController.java | 2 +- .../server/controller/SystemInfoController.java | 2 +- .../server/controller/TbResourceController.java | 2 +- .../server/controller/TbUrlConstants.java | 2 +- .../server/controller/TelemetryController.java | 2 +- .../server/controller/TenantController.java | 2 +- .../controller/TenantProfileController.java | 2 +- .../TwoFactorAuthConfigController.java | 2 +- .../controller/TwoFactorAuthController.java | 2 +- .../server/controller/UiSettingsController.java | 2 +- .../server/controller/UsageInfoController.java | 2 +- .../server/controller/UserController.java | 2 +- .../server/controller/WidgetTypeController.java | 2 +- .../controller/WidgetsBundleController.java | 2 +- .../controller/plugin/TbWebSocketHandler.java | 2 +- .../server/controller/plugin/TbWebSocketMsg.java | 2 +- .../controller/plugin/TbWebSocketMsgType.java | 2 +- .../controller/plugin/TbWebSocketPingMsg.java | 2 +- .../controller/plugin/TbWebSocketTextMsg.java | 2 +- .../server/exception/AccessDeniedException.java | 2 +- .../exception/EntityNotFoundException.java | 2 +- .../server/exception/InternalErrorException.java | 2 +- .../exception/InvalidParametersException.java | 2 +- .../ThingsboardCredentialsExpiredResponse.java | 2 +- .../ThingsboardCredentialsViolationResponse.java | 2 +- .../exception/ThingsboardErrorResponse.java | 2 +- .../ThingsboardErrorResponseHandler.java | 2 +- .../server/exception/ToErrorResponseEntity.java | 2 +- .../server/exception/UnauthorizedException.java | 2 +- .../server/exception/UncheckedApiException.java | 2 +- .../install/ThingsboardInstallConfiguration.java | 2 +- .../install/ThingsboardInstallException.java | 2 +- .../install/ThingsboardInstallService.java | 2 +- .../service/action/EntityActionService.java | 2 +- .../service/apiusage/BaseApiUsageState.java | 2 +- .../service/apiusage/CustomerApiUsageState.java | 2 +- .../apiusage/DefaultTbApiUsageStateService.java | 2 +- .../service/apiusage/TbApiUsageStateService.java | 2 +- .../service/apiusage/TenantApiUsageState.java | 2 +- .../service/asset/AssetBulkImportService.java | 2 +- .../AnnotationComponentDiscoveryService.java | 2 +- .../component/ComponentDiscoveryService.java | 2 +- .../service/component/RuleNodeClassInfo.java | 2 +- .../service/device/ClaimDevicesServiceImpl.java | 2 +- .../service/device/DeviceBulkImportService.java | 2 +- .../device/DeviceProvisionServiceImpl.java | 2 +- .../edge/DefaultEdgeNotificationService.java | 2 +- .../service/edge/EdgeBulkImportService.java | 2 +- .../service/edge/EdgeContextComponent.java | 2 +- .../service/edge/EdgeEventSourcingListener.java | 2 +- .../service/edge/EdgeNotificationService.java | 2 +- .../DefaultEdgeInstallInstructionsService.java | 2 +- .../DefaultEdgeUpgradeInstructionsService.java | 2 +- .../EdgeInstallInstructionsService.java | 2 +- .../EdgeUpgradeInstructionsService.java | 2 +- .../edge/rpc/EdgeEventStorageSettings.java | 2 +- .../server/service/edge/rpc/EdgeGrpcService.java | 2 +- .../server/service/edge/rpc/EdgeGrpcSession.java | 2 +- .../server/service/edge/rpc/EdgeRpcService.java | 2 +- .../service/edge/rpc/EdgeSessionState.java | 2 +- .../server/service/edge/rpc/EdgeSyncCursor.java | 2 +- .../constructor/BaseMsgConstructorFactory.java | 2 +- .../edge/rpc/constructor/MsgConstructor.java | 2 +- .../constructor/alarm/AlarmMsgConstructor.java | 2 +- .../alarm/AlarmMsgConstructorFactory.java | 2 +- .../constructor/alarm/AlarmMsgConstructorV1.java | 2 +- .../constructor/alarm/AlarmMsgConstructorV2.java | 2 +- .../constructor/asset/AssetMsgConstructor.java | 2 +- .../asset/AssetMsgConstructorFactory.java | 2 +- .../constructor/asset/AssetMsgConstructorV1.java | 2 +- .../constructor/asset/AssetMsgConstructorV2.java | 2 +- .../asset/BaseAssetMsgConstructor.java | 2 +- .../customer/BaseCustomerMsgConstructor.java | 2 +- .../customer/CustomerMsgConstructor.java | 2 +- .../customer/CustomerMsgConstructorFactory.java | 2 +- .../customer/CustomerMsgConstructorV1.java | 2 +- .../customer/CustomerMsgConstructorV2.java | 2 +- .../dashboard/BaseDashboardMsgConstructor.java | 2 +- .../dashboard/DashboardMsgConstructor.java | 2 +- .../DashboardMsgConstructorFactory.java | 2 +- .../dashboard/DashboardMsgConstructorV1.java | 2 +- .../dashboard/DashboardMsgConstructorV2.java | 2 +- .../device/BaseDeviceMsgConstructor.java | 2 +- .../constructor/device/DeviceMsgConstructor.java | 2 +- .../device/DeviceMsgConstructorFactory.java | 2 +- .../device/DeviceMsgConstructorV1.java | 2 +- .../device/DeviceMsgConstructorV2.java | 2 +- .../rpc/constructor/edge/EdgeMsgConstructor.java | 2 +- .../entityview/BaseEntityViewMsgConstructor.java | 2 +- .../entityview/EntityViewMsgConstructor.java | 2 +- .../EntityViewMsgConstructorFactory.java | 2 +- .../entityview/EntityViewMsgConstructorV1.java | 2 +- .../entityview/EntityViewMsgConstructorV2.java | 2 +- .../ota/BaseOtaPackageMsgConstructor.java | 2 +- .../ota/OtaPackageMsgConstructor.java | 2 +- .../ota/OtaPackageMsgConstructorFactory.java | 2 +- .../ota/OtaPackageMsgConstructorV1.java | 2 +- .../ota/OtaPackageMsgConstructorV2.java | 2 +- .../queue/BaseQueueMsgConstructor.java | 2 +- .../constructor/queue/QueueMsgConstructor.java | 2 +- .../queue/QueueMsgConstructorFactory.java | 2 +- .../constructor/queue/QueueMsgConstructorV1.java | 2 +- .../constructor/queue/QueueMsgConstructorV2.java | 2 +- .../relation/RelationMsgConstructor.java | 2 +- .../relation/RelationMsgConstructorFactory.java | 2 +- .../relation/RelationMsgConstructorV1.java | 2 +- .../relation/RelationMsgConstructorV2.java | 2 +- .../resource/BaseResourceMsgConstructor.java | 2 +- .../resource/ResourceMsgConstructor.java | 2 +- .../resource/ResourceMsgConstructorFactory.java | 2 +- .../resource/ResourceMsgConstructorV1.java | 2 +- .../resource/ResourceMsgConstructorV2.java | 2 +- .../rule/BaseRuleChainMetadataConstructor.java | 2 +- .../rule/BaseRuleChainMsgConstructor.java | 2 +- .../rule/RuleChainMetadataConstructor.java | 2 +- .../RuleChainMetadataConstructorFactory.java | 2 +- .../rule/RuleChainMetadataConstructorV330.java | 2 +- .../rule/RuleChainMetadataConstructorV340.java | 2 +- .../rule/RuleChainMetadataConstructorV362.java | 2 +- .../rule/RuleChainMsgConstructor.java | 2 +- .../rule/RuleChainMsgConstructorFactory.java | 2 +- .../rule/RuleChainMsgConstructorV1.java | 2 +- .../rule/RuleChainMsgConstructorV2.java | 2 +- .../settings/AdminSettingsMsgConstructor.java | 2 +- .../AdminSettingsMsgConstructorFactory.java | 2 +- .../settings/AdminSettingsMsgConstructorV1.java | 2 +- .../settings/AdminSettingsMsgConstructorV2.java | 2 +- .../telemetry/EntityDataMsgConstructor.java | 2 +- .../constructor/tenant/TenantMsgConstructor.java | 2 +- .../tenant/TenantMsgConstructorFactory.java | 2 +- .../tenant/TenantMsgConstructorV1.java | 2 +- .../tenant/TenantMsgConstructorV2.java | 2 +- .../constructor/user/BaseUserMsgConstructor.java | 2 +- .../rpc/constructor/user/UserMsgConstructor.java | 2 +- .../user/UserMsgConstructorFactory.java | 2 +- .../constructor/user/UserMsgConstructorV1.java | 2 +- .../constructor/user/UserMsgConstructorV2.java | 2 +- .../widget/BaseWidgetMsgConstructor.java | 2 +- .../constructor/widget/WidgetMsgConstructor.java | 2 +- .../widget/WidgetMsgConstructorFactory.java | 2 +- .../widget/WidgetMsgConstructorV1.java | 2 +- .../widget/WidgetMsgConstructorV2.java | 2 +- .../rpc/fetch/AdminSettingsEdgeEventFetcher.java | 2 +- .../rpc/fetch/AssetProfilesEdgeEventFetcher.java | 2 +- .../edge/rpc/fetch/AssetsEdgeEventFetcher.java | 2 +- .../rpc/fetch/BasePageableEdgeEventFetcher.java | 2 +- .../rpc/fetch/BaseUsersEdgeEventFetcher.java | 2 +- .../fetch/BaseWidgetTypesEdgeEventFetcher.java | 2 +- .../BaseWidgetsBundlesEdgeEventFetcher.java | 2 +- .../edge/rpc/fetch/CustomerEdgeEventFetcher.java | 2 +- .../rpc/fetch/CustomerUsersEdgeEventFetcher.java | 2 +- .../rpc/fetch/DashboardsEdgeEventFetcher.java | 2 +- .../fetch/DefaultProfilesEdgeEventFetcher.java | 2 +- .../fetch/DeviceProfilesEdgeEventFetcher.java | 2 +- .../edge/rpc/fetch/DevicesEdgeEventFetcher.java | 2 +- .../service/edge/rpc/fetch/EdgeEventFetcher.java | 2 +- .../rpc/fetch/EntityViewsEdgeEventFetcher.java | 2 +- .../edge/rpc/fetch/GeneralEdgeEventFetcher.java | 2 +- .../rpc/fetch/OtaPackagesEdgeEventFetcher.java | 2 +- .../edge/rpc/fetch/QueuesEdgeEventFetcher.java | 2 +- .../rpc/fetch/RuleChainsEdgeEventFetcher.java | 2 +- .../fetch/SystemWidgetTypesEdgeEventFetcher.java | 2 +- .../SystemWidgetsBundlesEdgeEventFetcher.java | 2 +- .../fetch/TenantAdminUsersEdgeEventFetcher.java | 2 +- .../edge/rpc/fetch/TenantEdgeEventFetcher.java | 2 +- .../fetch/TenantResourcesEdgeEventFetcher.java | 2 +- .../fetch/TenantWidgetTypesEdgeEventFetcher.java | 2 +- .../TenantWidgetsBundlesEdgeEventFetcher.java | 2 +- .../edge/rpc/processor/BaseEdgeProcessor.java | 2 +- .../rpc/processor/BaseEdgeProcessorFactory.java | 2 +- .../edge/rpc/processor/EdgeProcessor.java | 2 +- .../rpc/processor/alarm/AlarmEdgeProcessor.java | 2 +- .../alarm/AlarmEdgeProcessorFactory.java | 2 +- .../processor/alarm/AlarmEdgeProcessorV1.java | 2 +- .../processor/alarm/AlarmEdgeProcessorV2.java | 2 +- .../edge/rpc/processor/alarm/AlarmProcessor.java | 2 +- .../rpc/processor/alarm/BaseAlarmProcessor.java | 2 +- .../rpc/processor/asset/AssetEdgeProcessor.java | 2 +- .../asset/AssetEdgeProcessorFactory.java | 2 +- .../processor/asset/AssetEdgeProcessorV1.java | 2 +- .../processor/asset/AssetEdgeProcessorV2.java | 2 +- .../edge/rpc/processor/asset/AssetProcessor.java | 2 +- .../rpc/processor/asset/BaseAssetProcessor.java | 2 +- .../asset/profile/AssetProfileEdgeProcessor.java | 2 +- .../AssetProfileEdgeProcessorFactory.java | 2 +- .../profile/AssetProfileEdgeProcessorV1.java | 2 +- .../profile/AssetProfileEdgeProcessorV2.java | 2 +- .../asset/profile/AssetProfileProcessor.java | 2 +- .../asset/profile/BaseAssetProfileProcessor.java | 2 +- .../customer/CustomerEdgeProcessor.java | 2 +- .../dashboard/BaseDashboardProcessor.java | 2 +- .../dashboard/DashboardEdgeProcessor.java | 2 +- .../dashboard/DashboardEdgeProcessorFactory.java | 2 +- .../dashboard/DashboardEdgeProcessorV1.java | 2 +- .../dashboard/DashboardEdgeProcessorV2.java | 2 +- .../processor/dashboard/DashboardProcessor.java | 2 +- .../processor/device/BaseDeviceProcessor.java | 2 +- .../processor/device/DeviceEdgeProcessor.java | 2 +- .../device/DeviceEdgeProcessorFactory.java | 2 +- .../processor/device/DeviceEdgeProcessorV1.java | 2 +- .../processor/device/DeviceEdgeProcessorV2.java | 2 +- .../rpc/processor/device/DeviceProcessor.java | 2 +- .../profile/BaseDeviceProfileProcessor.java | 2 +- .../profile/DeviceProfileEdgeProcessor.java | 2 +- .../DeviceProfileEdgeProcessorFactory.java | 2 +- .../profile/DeviceProfileEdgeProcessorV1.java | 2 +- .../profile/DeviceProfileEdgeProcessorV2.java | 2 +- .../device/profile/DeviceProfileProcessor.java | 2 +- .../edge/rpc/processor/edge/EdgeProcessor.java | 2 +- .../entityview/BaseEntityViewProcessor.java | 2 +- .../entityview/EntityViewEdgeProcessor.java | 2 +- .../entityview/EntityViewProcessor.java | 2 +- .../entityview/EntityViewProcessorFactory.java | 2 +- .../entityview/EntityViewProcessorV1.java | 2 +- .../entityview/EntityViewProcessorV2.java | 2 +- .../processor/ota/OtaPackageEdgeProcessor.java | 2 +- .../rpc/processor/queue/QueueEdgeProcessor.java | 2 +- .../relation/BaseRelationProcessor.java | 2 +- .../relation/RelationEdgeProcessor.java | 2 +- .../relation/RelationEdgeProcessorFactory.java | 2 +- .../relation/RelationEdgeProcessorV1.java | 2 +- .../relation/RelationEdgeProcessorV2.java | 2 +- .../processor/relation/RelationProcessor.java | 2 +- .../resource/BaseResourceProcessor.java | 2 +- .../resource/ResourceEdgeProcessor.java | 2 +- .../resource/ResourceEdgeProcessorFactory.java | 2 +- .../resource/ResourceEdgeProcessorV1.java | 2 +- .../resource/ResourceEdgeProcessorV2.java | 2 +- .../processor/resource/ResourceProcessor.java | 2 +- .../processor/rule/RuleChainEdgeProcessor.java | 2 +- .../settings/AdminSettingsEdgeProcessor.java | 2 +- .../telemetry/BaseTelemetryProcessor.java | 2 +- .../telemetry/TelemetryEdgeProcessor.java | 2 +- .../processor/tenant/TenantEdgeProcessor.java | 2 +- .../tenant/TenantProfileEdgeProcessor.java | 2 +- .../rpc/processor/user/UserEdgeProcessor.java | 2 +- .../widget/WidgetBundleEdgeProcessor.java | 2 +- .../widget/WidgetTypeEdgeProcessor.java | 2 +- .../rpc/sync/DefaultEdgeRequestsService.java | 2 +- .../edge/rpc/sync/EdgeRequestsService.java | 2 +- .../service/edge/rpc/utils/EdgeVersionUtils.java | 2 +- .../service/entitiy/AbstractTbEntityService.java | 2 +- .../DefaultTbNotificationEntityService.java | 2 +- .../service/entitiy/SimpleTbEntityService.java | 2 +- .../entitiy/TbNotificationEntityService.java | 2 +- .../alarm/DefaultTbAlarmCommentService.java | 2 +- .../entitiy/alarm/DefaultTbAlarmService.java | 2 +- .../entitiy/alarm/TbAlarmCommentService.java | 2 +- .../service/entitiy/alarm/TbAlarmService.java | 2 +- .../entitiy/asset/DefaultTbAssetService.java | 2 +- .../service/entitiy/asset/TbAssetService.java | 2 +- .../profile/DefaultTbAssetProfileService.java | 2 +- .../asset/profile/TbAssetProfileService.java | 2 +- .../customer/DefaultTbCustomerService.java | 2 +- .../entitiy/customer/TbCustomerService.java | 2 +- .../dashboard/DefaultTbDashboardService.java | 2 +- .../entitiy/dashboard/TbDashboardService.java | 2 +- .../entitiy/device/DefaultTbDeviceService.java | 2 +- .../service/entitiy/device/TbDeviceService.java | 2 +- .../profile/DefaultTbDeviceProfileService.java | 2 +- .../device/profile/TbDeviceProfileService.java | 2 +- .../entitiy/edge/DefaultTbEdgeService.java | 2 +- .../service/entitiy/edge/TbEdgeService.java | 2 +- .../relation/DefaultTbEntityRelationService.java | 2 +- .../entity/relation/TbEntityRelationService.java | 2 +- .../entityview/DefaultTbEntityViewService.java | 2 +- .../entitiy/entityview/TbEntityViewService.java | 2 +- .../entitiy/ota/DefaultTbOtaPackageService.java | 2 +- .../service/entitiy/ota/TbOtaPackageService.java | 2 +- .../entitiy/queue/DefaultTbQueueService.java | 2 +- .../service/entitiy/queue/TbQueueService.java | 2 +- .../entitiy/tenant/DefaultTbTenantService.java | 2 +- .../service/entitiy/tenant/TbTenantService.java | 2 +- .../profile/DefaultTbTenantProfileService.java | 2 +- .../tenant/profile/TbTenantProfileService.java | 2 +- .../user/DefaultTbUserSettingsService.java | 2 +- .../service/entitiy/user/DefaultUserService.java | 2 +- .../service/entitiy/user/TbUserService.java | 2 +- .../entitiy/user/TbUserSettingsService.java | 2 +- .../bundle/DefaultWidgetsBundleService.java | 2 +- .../widgets/bundle/TbWidgetsBundleService.java | 2 +- .../widgets/type/DefaultWidgetTypeService.java | 2 +- .../widgets/type/TbWidgetTypeService.java | 2 +- .../executors/DbCallbackExecutorService.java | 2 +- .../executors/ExternalCallExecutorService.java | 2 +- .../executors/GrpcCallbackExecutorService.java | 2 +- .../executors/NotificationExecutorService.java | 2 +- .../PubSubRuleNodeExecutorProvider.java | 2 +- .../executors/SharedEventLoopGroupService.java | 2 +- .../executors/VersionControlExecutor.java | 2 +- .../DefaultGatewayNotificationsService.java | 2 +- .../GatewayNotificationsService.java | 2 +- .../InMemoryHouseKeeperServiceService.java | 2 +- .../AbstractCassandraDatabaseUpgradeService.java | 2 +- .../AbstractSqlTsDatabaseUpgradeService.java | 2 +- .../CassandraAbstractDatabaseSchemaService.java | 2 +- .../install/CassandraKeyspaceService.java | 2 +- .../CassandraTsDatabaseSchemaService.java | 2 +- .../CassandraTsDatabaseUpgradeService.java | 2 +- .../CassandraTsLatestDatabaseSchemaService.java | 2 +- .../install/DatabaseEntitiesUpgradeService.java | 2 +- .../server/service/install/DatabaseHelper.java | 2 +- .../service/install/DatabaseSchemaService.java | 2 +- .../install/DatabaseTsUpgradeService.java | 2 +- .../install/DbUpgradeExecutorService.java | 2 +- .../install/DefaultSystemDataLoaderService.java | 2 +- .../install/EntityDatabaseSchemaService.java | 2 +- .../server/service/install/InstallScripts.java | 2 +- .../service/install/NoSqlKeyspaceService.java | 2 +- .../SqlAbstractDatabaseSchemaService.java | 2 +- .../install/SqlDatabaseUpgradeService.java | 2 +- .../install/SqlEntityDatabaseSchemaService.java | 2 +- .../install/SqlTsDatabaseSchemaService.java | 2 +- .../install/SqlTsDatabaseUpgradeService.java | 2 +- .../service/install/SystemDataLoaderService.java | 2 +- .../install/TbRuleEngineQueueConfigService.java | 2 +- .../TimescaleTsDatabaseSchemaService.java | 2 +- .../TimescaleTsDatabaseUpgradeService.java | 2 +- .../service/install/TsDatabaseSchemaService.java | 2 +- .../install/TsLatestDatabaseSchemaService.java | 2 +- .../service/install/cql/CQLStatementsParser.java | 2 +- .../service/install/cql/CassandraDbHelper.java | 2 +- .../CassandraEntitiesToSqlMigrateService.java | 2 +- .../install/migrate/CassandraToSqlColumn.java | 2 +- .../migrate/CassandraToSqlColumnData.java | 2 +- .../migrate/CassandraToSqlColumnType.java | 2 +- .../migrate/CassandraToSqlEventTsColumn.java | 2 +- .../install/migrate/CassandraToSqlTable.java | 2 +- .../CassandraTsLatestToSqlMigrateService.java | 2 +- .../install/migrate/EntitiesMigrateService.java | 2 +- .../install/migrate/TsLatestMigrateService.java | 2 +- .../server/service/install/sql/SqlDbHelper.java | 2 +- .../install/update/CacheCleanupService.java | 2 +- .../install/update/DataUpdateService.java | 2 +- .../update/DefaultCacheCleanupService.java | 2 +- .../install/update/DefaultDataUpdateService.java | 2 +- .../service/install/update/ImagesUpdater.java | 2 +- .../service/install/update/PaginatedUpdater.java | 2 +- .../install/update/RateLimitsUpdater.java | 2 +- .../server/service/lwm2m/LwM2MService.java | 2 +- .../server/service/lwm2m/LwM2MServiceImpl.java | 2 +- .../server/service/mail/DefaultMailService.java | 2 +- .../mail/DefaultTbMailConfigTemplateService.java | 2 +- .../server/service/mail/MailExecutorService.java | 2 +- .../mail/PasswordResetExecutorService.java | 2 +- .../mail/RefreshTokenExpCheckService.java | 2 +- .../mail/TbMailConfigTemplateService.java | 2 +- .../service/mail/TbMailContextComponent.java | 2 +- .../server/service/mail/TbMailSender.java | 2 +- .../notification/DefaultNotificationCenter.java | 2 +- .../DefaultNotificationSchedulerService.java | 2 +- .../NotificationProcessingContext.java | 2 +- .../NotificationSchedulerService.java | 2 +- .../channels/EmailNotificationChannel.java | 2 +- .../MicrosoftTeamsNotificationChannel.java | 2 +- .../channels/NotificationChannel.java | 2 +- .../channels/SlackNotificationChannel.java | 2 +- .../channels/SmsNotificationChannel.java | 2 +- .../rule/DefaultNotificationRuleProcessor.java | 2 +- .../cache/DefaultNotificationRulesCache.java | 2 +- .../rule/cache/NotificationRulesCache.java | 2 +- .../trigger/AlarmAssignmentTriggerProcessor.java | 2 +- .../trigger/AlarmCommentTriggerProcessor.java | 2 +- .../rule/trigger/AlarmTriggerProcessor.java | 2 +- .../trigger/ApiUsageLimitTriggerProcessor.java | 2 +- .../trigger/DeviceActivityTriggerProcessor.java | 2 +- .../trigger/EntitiesLimitTriggerProcessor.java | 2 +- .../trigger/EntityActionTriggerProcessor.java | 2 +- .../NewPlatformVersionTriggerProcessor.java | 2 +- .../NotificationRuleTriggerProcessor.java | 2 +- .../rule/trigger/RateLimitsTriggerProcessor.java | 2 +- ...eComponentLifecycleEventTriggerProcessor.java | 2 +- .../ota/DefaultOtaPackageStateService.java | 2 +- .../service/ota/OtaPackageStateService.java | 2 +- .../partition/AbstractPartitionBasedService.java | 2 +- .../service/partition/TbCoreStartupService.java | 2 +- .../profile/DefaultTbAssetProfileCache.java | 2 +- .../profile/DefaultTbDeviceProfileCache.java | 2 +- .../service/profile/TbAssetProfileCache.java | 2 +- .../service/profile/TbDeviceProfileCache.java | 2 +- .../service/query/DefaultEntityQueryService.java | 2 +- .../server/service/query/EntityQueryService.java | 2 +- .../queue/DefaultQueueRoutingInfoService.java | 2 +- .../service/queue/DefaultTbClusterService.java | 2 +- .../queue/DefaultTbCoreConsumerService.java | 2 +- .../DefaultTbRuleEngineConsumerService.java | 2 +- .../queue/DefaultTenantRoutingInfoService.java | 2 +- .../service/queue/TbCoreConsumerService.java | 2 +- .../service/queue/TbCoreConsumerStats.java | 2 +- .../server/service/queue/TbMsgPackCallback.java | 2 +- .../queue/TbMsgPackProcessingContext.java | 2 +- .../server/service/queue/TbMsgProfilerInfo.java | 2 +- .../server/service/queue/TbPackCallback.java | 2 +- .../service/queue/TbPackProcessingContext.java | 2 +- .../queue/TbRuleEngineConsumerService.java | 2 +- .../service/queue/TbRuleEngineConsumerStats.java | 2 +- .../service/queue/TbRuleNodeProfilerInfo.java | 2 +- .../service/queue/TbTenantRuleEngineStats.java | 2 +- .../queue/TbTopicWithConsumerPerPartition.java | 2 +- .../processing/AbstractConsumerService.java | 2 +- .../AbstractTbRuleEngineSubmitStrategy.java | 2 +- .../BatchTbRuleEngineSubmitStrategy.java | 2 +- .../BurstTbRuleEngineSubmitStrategy.java | 2 +- .../service/queue/processing/IdMsgPair.java | 2 +- ...tialByEntityIdTbRuleEngineSubmitStrategy.java | 2 +- ...ByOriginatorIdTbRuleEngineSubmitStrategy.java | 2 +- ...tialByTenantIdTbRuleEngineSubmitStrategy.java | 2 +- .../SequentialTbRuleEngineSubmitStrategy.java | 2 +- .../TbRuleEngineProcessingDecision.java | 2 +- .../processing/TbRuleEngineProcessingResult.java | 2 +- .../TbRuleEngineProcessingStrategy.java | 2 +- .../TbRuleEngineProcessingStrategyFactory.java | 2 +- .../processing/TbRuleEngineSubmitStrategy.java | 2 +- .../TbRuleEngineSubmitStrategyFactory.java | 2 +- .../service/queue/ruleengine/QueueEvent.java | 2 +- .../ruleengine/TbQueueConsumerManagerTask.java | 2 +- .../queue/ruleengine/TbQueueConsumerTask.java | 2 +- .../ruleengine/TbRuleEngineConsumerContext.java | 2 +- .../TbRuleEngineQueueConsumerManager.java | 2 +- .../service/resource/DefaultTbImageService.java | 2 +- .../resource/DefaultTbResourceService.java | 2 +- .../server/service/resource/TbImageService.java | 2 +- .../service/resource/TbResourceService.java | 2 +- .../rpc/DefaultTbCoreDeviceRpcService.java | 2 +- .../rpc/DefaultTbRuleEngineRpcService.java | 2 +- .../server/service/rpc/LocalRequestMetaData.java | 2 +- .../server/service/rpc/RpcSubmitStrategy.java | 2 +- .../service/rpc/TbCoreDeviceRpcService.java | 2 +- .../server/service/rpc/TbRpcService.java | 2 +- .../rpc/TbRuleEngineDeviceRpcService.java | 2 +- .../service/rule/DefaultTbRuleChainService.java | 2 +- .../server/service/rule/TbRuleChainService.java | 2 +- .../service/script/RuleNodeJsScriptEngine.java | 2 +- .../service/script/RuleNodeScriptEngine.java | 2 +- .../service/script/RuleNodeTbelScriptEngine.java | 2 +- .../server/service/security/AccessValidator.java | 2 +- .../service/security/ValidationCallback.java | 2 +- .../service/security/ValidationResult.java | 2 +- .../service/security/ValidationResultCode.java | 2 +- .../auth/AbstractJwtAuthenticationToken.java | 2 +- .../auth/DefaultTokenOutdatingService.java | 2 +- .../security/auth/JwtAuthenticationToken.java | 2 +- .../security/auth/MfaAuthenticationToken.java | 2 +- .../auth/RefreshAuthenticationToken.java | 2 +- .../security/auth/TokenOutdatingService.java | 2 +- .../auth/jwt/JwtAuthenticationProvider.java | 2 +- .../JwtTokenAuthenticationProcessingFilter.java | 2 +- .../jwt/RefreshTokenAuthenticationProvider.java | 2 +- .../auth/jwt/RefreshTokenProcessingFilter.java | 2 +- .../security/auth/jwt/RefreshTokenRequest.java | 2 +- .../auth/jwt/SkipPathRequestMatcher.java | 2 +- .../jwt/extractor/JwtHeaderTokenExtractor.java | 2 +- .../jwt/extractor/JwtQueryTokenExtractor.java | 2 +- .../auth/jwt/extractor/TokenExtractor.java | 2 +- .../jwt/settings/DefaultJwtSettingsService.java | 2 +- .../settings/DefaultJwtSettingsValidator.java | 2 +- .../settings/InstallJwtSettingsValidator.java | 2 +- .../auth/jwt/settings/JwtSettingsService.java | 2 +- .../auth/jwt/settings/JwtSettingsValidator.java | 2 +- .../auth/mfa/DefaultTwoFactorAuthService.java | 2 +- .../security/auth/mfa/TwoFactorAuthService.java | 2 +- .../mfa/config/DefaultTwoFaConfigManager.java | 2 +- .../auth/mfa/config/TwoFaConfigManager.java | 2 +- .../auth/mfa/provider/TwoFaProvider.java | 2 +- .../provider/impl/BackupCodeTwoFaProvider.java | 2 +- .../mfa/provider/impl/EmailTwoFaProvider.java | 2 +- .../mfa/provider/impl/OtpBasedTwoFaProvider.java | 2 +- .../auth/mfa/provider/impl/SmsTwoFaProvider.java | 2 +- .../mfa/provider/impl/TotpTwoFaProvider.java | 2 +- .../auth/oauth2/AbstractOAuth2ClientMapper.java | 2 +- .../auth/oauth2/AppleOAuth2ClientMapper.java | 2 +- .../security/auth/oauth2/BasicMapperUtils.java | 2 +- .../auth/oauth2/BasicOAuth2ClientMapper.java | 2 +- .../security/auth/oauth2/CookieUtils.java | 2 +- .../auth/oauth2/CustomOAuth2ClientMapper.java | 2 +- .../auth/oauth2/GithubOAuth2ClientMapper.java | 2 +- ...okieOAuth2AuthorizationRequestRepository.java | 2 +- .../security/auth/oauth2/OAuth2ClientMapper.java | 2 +- .../auth/oauth2/OAuth2ClientMapperProvider.java | 2 +- .../Oauth2AuthenticationFailureHandler.java | 2 +- .../Oauth2AuthenticationSuccessHandler.java | 2 +- .../auth/oauth2/TbOAuth2ParameterNames.java | 2 +- .../service/security/auth/rest/LoginRequest.java | 2 +- .../security/auth/rest/LoginResponse.java | 2 +- .../security/auth/rest/PublicLoginRequest.java | 2 +- .../auth/rest/RestAuthenticationDetails.java | 2 +- .../rest/RestAuthenticationDetailsSource.java | 2 +- .../auth/rest/RestAuthenticationProvider.java | 2 +- .../RestAwareAuthenticationFailureHandler.java | 2 +- .../RestAwareAuthenticationSuccessHandler.java | 2 +- .../auth/rest/RestLoginProcessingFilter.java | 2 +- .../rest/RestPublicLoginProcessingFilter.java | 2 +- .../device/DefaultDeviceAuthService.java | 2 +- .../AuthMethodNotSupportedException.java | 2 +- .../exception/JwtExpiredTokenException.java | 2 +- .../exception/UserPasswordExpiredException.java | 2 +- .../exception/UserPasswordNotValidException.java | 2 +- .../security/model/ActivateUserRequest.java | 2 +- .../security/model/ChangePasswordRequest.java | 2 +- .../model/ResetPasswordEmailRequest.java | 2 +- .../security/model/ResetPasswordRequest.java | 2 +- .../service/security/model/SecurityUser.java | 2 +- .../service/security/model/UserPrincipal.java | 2 +- .../security/model/token/AccessJwtToken.java | 2 +- .../security/model/token/JwtTokenFactory.java | 2 +- .../model/token/OAuth2AppTokenFactory.java | 2 +- .../security/model/token/RawAccessJwtToken.java | 2 +- .../security/permission/AbstractPermissions.java | 2 +- .../permission/AccessControlService.java | 2 +- .../permission/CustomerUserPermissions.java | 2 +- .../permission/DefaultAccessControlService.java | 2 +- .../service/security/permission/Operation.java | 2 +- .../security/permission/PermissionChecker.java | 2 +- .../service/security/permission/Permissions.java | 2 +- .../service/security/permission/Resource.java | 2 +- .../security/permission/SysAdminPermissions.java | 2 +- .../permission/TenantAdminPermissions.java | 2 +- .../system/DefaultSystemSecurityService.java | 2 +- .../security/system/SystemSecurityService.java | 2 +- .../DefaultDeviceSessionCacheService.java | 2 +- .../session/DeviceSessionCacheService.java | 2 +- .../service/session/SessionCaffeineCache.java | 2 +- .../service/session/SessionRedisCache.java | 2 +- .../service/slack/DefaultSlackService.java | 2 +- .../server/service/sms/AbstractSmsSender.java | 2 +- .../service/sms/DefaultSmsSenderFactory.java | 2 +- .../server/service/sms/DefaultSmsService.java | 2 +- .../server/service/sms/SmsExecutorService.java | 2 +- .../server/service/sms/aws/AwsSmsSender.java | 2 +- .../server/service/sms/smpp/SmppSmsSender.java | 2 +- .../service/sms/twilio/TwilioSmsSender.java | 2 +- .../service/state/DefaultDeviceStateService.java | 2 +- .../server/service/state/DeviceState.java | 2 +- .../server/service/state/DeviceStateData.java | 2 +- .../server/service/state/DeviceStateService.java | 2 +- .../service/stats/DefaultJsInvokeStats.java | 2 +- .../DefaultRuleEngineStatisticsService.java | 2 +- .../stats/RuleEngineStatisticsService.java | 2 +- .../DefaultSubscriptionManagerService.java | 2 +- .../DefaultTbEntityDataSubscriptionService.java | 2 +- .../DefaultTbLocalSubscriptionService.java | 2 +- .../service/subscription/ReadTsKvQueryInfo.java | 2 +- .../subscription/SubscriptionErrorCode.java | 2 +- .../subscription/SubscriptionManagerService.java | 2 +- .../SubscriptionSchedulerComponent.java | 2 +- .../SubscriptionServiceStatistics.java | 2 +- .../subscription/TbAbstractDataSubCtx.java | 2 +- .../service/subscription/TbAbstractSubCtx.java | 2 +- .../service/subscription/TbAlarmCountSubCtx.java | 2 +- .../service/subscription/TbAlarmDataSubCtx.java | 2 +- .../subscription/TbAlarmsSubscription.java | 2 +- .../subscription/TbAttributeSubscription.java | 2 +- .../TbAttributeSubscriptionScope.java | 2 +- .../subscription/TbEntityCountSubCtx.java | 2 +- .../service/subscription/TbEntityDataSubCtx.java | 2 +- .../TbEntityDataSubscriptionService.java | 2 +- .../subscription/TbEntityLocalSubsInfo.java | 2 +- .../subscription/TbEntityRemoteSubsInfo.java | 2 +- .../service/subscription/TbEntitySubEvent.java | 2 +- .../subscription/TbEntityUpdatesInfo.java | 2 +- .../subscription/TbLocalSubscriptionService.java | 2 +- .../service/subscription/TbSubscription.java | 2 +- .../service/subscription/TbSubscriptionType.java | 2 +- .../subscription/TbSubscriptionUtils.java | 2 +- .../subscription/TbSubscriptionsInfo.java | 2 +- .../subscription/TbTimeSeriesSubscription.java | 2 +- .../ie/DefaultEntitiesExportImportService.java | 2 +- .../sync/ie/EntitiesExportImportService.java | 2 +- .../DefaultExportableEntitiesService.java | 2 +- .../sync/ie/exporting/EntityExportService.java | 2 +- .../ie/exporting/ExportableEntitiesService.java | 2 +- .../ie/exporting/impl/AssetExportService.java | 2 +- .../impl/AssetProfileExportService.java | 2 +- .../exporting/impl/BaseEntityExportService.java | 2 +- .../exporting/impl/DashboardExportService.java | 2 +- .../impl/DefaultEntityExportService.java | 2 +- .../ie/exporting/impl/DeviceExportService.java | 2 +- .../impl/DeviceProfileExportService.java | 2 +- .../exporting/impl/EntityViewExportService.java | 2 +- .../impl/NotificationRuleExportService.java | 2 +- .../impl/NotificationTargetExportService.java | 2 +- .../impl/NotificationTemplateExportService.java | 2 +- .../ie/exporting/impl/ResourceExportService.java | 2 +- .../exporting/impl/RuleChainExportService.java | 2 +- .../exporting/impl/WidgetTypeExportService.java | 2 +- .../impl/WidgetsBundleExportService.java | 2 +- .../sync/ie/importing/EntityImportService.java | 2 +- .../importing/csv/AbstractBulkImportService.java | 2 +- .../ie/importing/csv/ImportedEntityInfo.java | 2 +- .../ie/importing/impl/AssetImportService.java | 2 +- .../impl/AssetProfileImportService.java | 2 +- .../importing/impl/BaseEntityImportService.java | 2 +- .../ie/importing/impl/CustomerImportService.java | 2 +- .../importing/impl/DashboardImportService.java | 2 +- .../ie/importing/impl/DeviceImportService.java | 2 +- .../impl/DeviceProfileImportService.java | 2 +- .../importing/impl/EntityViewImportService.java | 2 +- .../importing/impl/ImportServiceException.java | 2 +- .../importing/impl/MissingEntityException.java | 2 +- .../impl/NotificationRuleImportService.java | 2 +- .../impl/NotificationTargetImportService.java | 2 +- .../impl/NotificationTemplateImportService.java | 2 +- .../ie/importing/impl/ResourceImportService.java | 2 +- .../importing/impl/RuleChainImportService.java | 2 +- .../importing/impl/WidgetTypeImportService.java | 2 +- .../impl/WidgetsBundleImportService.java | 2 +- .../vc/DefaultEntitiesVersionControlService.java | 2 +- .../vc/DefaultGitVersionControlQueueService.java | 2 +- .../sync/vc/EntitiesVersionControlService.java | 2 +- .../sync/vc/GitVersionControlQueueService.java | 2 +- .../service/sync/vc/LoadEntityException.java | 2 +- .../TbAbstractVersionControlSettingsService.java | 2 +- .../sync/vc/VersionControlTaskCacheEntry.java | 2 +- .../sync/vc/VersionControlTaskCaffeineCache.java | 2 +- .../sync/vc/VersionControlTaskRedisCache.java | 2 +- .../AutoCommitSettingsCaffeineCache.java | 2 +- .../autocommit/AutoCommitSettingsRedisCache.java | 2 +- .../DefaultTbAutoCommitSettingsService.java | 2 +- .../autocommit/TbAutoCommitSettingsService.java | 2 +- .../sync/vc/data/ClearRepositoryGitRequest.java | 2 +- .../service/sync/vc/data/CommitGitRequest.java | 2 +- .../sync/vc/data/ComplexEntitiesExportCtx.java | 2 +- .../sync/vc/data/ContentsDiffGitRequest.java | 2 +- .../sync/vc/data/EntitiesContentGitRequest.java | 2 +- .../service/sync/vc/data/EntitiesExportCtx.java | 2 +- .../service/sync/vc/data/EntitiesImportCtx.java | 2 +- .../sync/vc/data/EntityContentGitRequest.java | 2 +- .../sync/vc/data/EntityTypeExportCtx.java | 2 +- .../sync/vc/data/ListBranchesGitRequest.java | 2 +- .../sync/vc/data/ListEntitiesGitRequest.java | 2 +- .../sync/vc/data/ListVersionsGitRequest.java | 2 +- .../service/sync/vc/data/PendingGitRequest.java | 2 +- .../service/sync/vc/data/ReimportTask.java | 2 +- .../sync/vc/data/SimpleEntitiesExportCtx.java | 2 +- .../sync/vc/data/VersionsDiffGitRequest.java | 2 +- .../service/sync/vc/data/VoidGitRequest.java | 2 +- .../DefaultTbRepositorySettingsService.java | 2 +- .../RepositorySettingsCaffeineCache.java | 2 +- .../repository/RepositorySettingsRedisCache.java | 2 +- .../repository/TbRepositorySettingsService.java | 2 +- .../service/system/DefaultSystemInfoService.java | 2 +- .../server/service/system/SystemInfoService.java | 2 +- .../telemetry/AbstractSubscriptionService.java | 2 +- .../telemetry/AlarmSubscriptionService.java | 2 +- .../server/service/telemetry/AttributeData.java | 2 +- .../DefaultAlarmSubscriptionService.java | 2 +- .../DefaultTelemetrySubscriptionService.java | 2 +- .../telemetry/InternalTelemetryService.java | 2 +- .../telemetry/TelemetrySubscriptionService.java | 2 +- .../server/service/telemetry/TsData.java | 2 +- .../BasicCredentialsValidationResult.java | 2 +- .../DefaultTbCoreToTransportService.java | 2 +- .../transport/DefaultTransportApiService.java | 2 +- .../transport/TbCoreToTransportService.java | 2 +- .../transport/TbCoreTransportApiService.java | 2 +- .../service/transport/TransportApiService.java | 2 +- .../msg/TransportToDeviceActorMsgWrapper.java | 2 +- .../service/ttl/AbstractCleanUpService.java | 2 +- .../server/service/ttl/AlarmsCleanUpService.java | 2 +- .../service/ttl/AuditLogsCleanUpService.java | 2 +- .../service/ttl/EdgeEventsCleanUpService.java | 2 +- .../server/service/ttl/EventsCleanUpService.java | 2 +- .../service/ttl/NotificationsCleanUpService.java | 2 +- .../service/ttl/TimeseriesCleanUpService.java | 2 +- .../service/ttl/rpc/RpcCleanUpService.java | 2 +- .../service/update/DefaultUpdateService.java | 2 +- .../server/service/update/UpdateService.java | 2 +- .../thingsboard/server/service/ws/AuthCmd.java | 2 +- .../service/ws/DefaultWebSocketService.java | 2 +- .../server/service/ws/SessionEvent.java | 2 +- .../server/service/ws/WebSocketMsgEndpoint.java | 2 +- .../server/service/ws/WebSocketService.java | 2 +- .../server/service/ws/WebSocketSessionRef.java | 2 +- .../server/service/ws/WebSocketSessionType.java | 2 +- .../org/thingsboard/server/service/ws/WsCmd.java | 2 +- .../thingsboard/server/service/ws/WsCmdType.java | 2 +- .../server/service/ws/WsCommandsWrapper.java | 2 +- .../server/service/ws/WsSessionMetaData.java | 2 +- .../DefaultNotificationCommandsHandler.java | 2 +- .../NotificationCommandsHandler.java | 2 +- .../cmd/MarkAllNotificationsAsReadCmd.java | 2 +- .../cmd/MarkNotificationsAsReadCmd.java | 2 +- .../cmd/NotificationCmdsWrapper.java | 2 +- .../cmd/NotificationsCountSubCmd.java | 2 +- .../ws/notification/cmd/NotificationsSubCmd.java | 2 +- .../notification/cmd/NotificationsUnsubCmd.java | 2 +- .../cmd/UnreadNotificationsCountUpdate.java | 2 +- .../cmd/UnreadNotificationsUpdate.java | 2 +- .../sub/NotificationRequestUpdate.java | 2 +- .../ws/notification/sub/NotificationUpdate.java | 2 +- .../sub/NotificationsCountSubscription.java | 2 +- .../sub/NotificationsSubscription.java | 2 +- .../sub/NotificationsSubscriptionUpdate.java | 2 +- .../service/ws/telemetry/TelemetryFeature.java | 2 +- .../ws/telemetry/TelemetryWebSocketTextMsg.java | 2 +- .../ws/telemetry/cmd/TelemetryCmdsWrapper.java | 2 +- .../cmd/v1/AttributesSubscriptionCmd.java | 2 +- .../ws/telemetry/cmd/v1/GetHistoryCmd.java | 2 +- .../ws/telemetry/cmd/v1/SubscriptionCmd.java | 2 +- .../ws/telemetry/cmd/v1/TelemetryPluginCmd.java | 2 +- .../cmd/v1/TimeseriesSubscriptionCmd.java | 2 +- .../ws/telemetry/cmd/v2/AggHistoryCmd.java | 2 +- .../service/ws/telemetry/cmd/v2/AggKey.java | 2 +- .../ws/telemetry/cmd/v2/AggTimeSeriesCmd.java | 2 +- .../ws/telemetry/cmd/v2/AlarmCountCmd.java | 2 +- .../cmd/v2/AlarmCountUnsubscribeCmd.java | 2 +- .../ws/telemetry/cmd/v2/AlarmCountUpdate.java | 2 +- .../ws/telemetry/cmd/v2/AlarmDataCmd.java | 2 +- .../cmd/v2/AlarmDataUnsubscribeCmd.java | 2 +- .../ws/telemetry/cmd/v2/AlarmDataUpdate.java | 2 +- .../service/ws/telemetry/cmd/v2/CmdUpdate.java | 2 +- .../ws/telemetry/cmd/v2/CmdUpdateType.java | 2 +- .../service/ws/telemetry/cmd/v2/DataCmd.java | 2 +- .../service/ws/telemetry/cmd/v2/DataUpdate.java | 2 +- .../ws/telemetry/cmd/v2/EntityCountCmd.java | 2 +- .../cmd/v2/EntityCountUnsubscribeCmd.java | 2 +- .../ws/telemetry/cmd/v2/EntityCountUpdate.java | 2 +- .../ws/telemetry/cmd/v2/EntityDataCmd.java | 2 +- .../cmd/v2/EntityDataUnsubscribeCmd.java | 2 +- .../ws/telemetry/cmd/v2/EntityDataUpdate.java | 2 +- .../ws/telemetry/cmd/v2/EntityHistoryCmd.java | 2 +- .../service/ws/telemetry/cmd/v2/GetTsCmd.java | 2 +- .../ws/telemetry/cmd/v2/LatestValueCmd.java | 2 +- .../ws/telemetry/cmd/v2/TimeSeriesCmd.java | 2 +- .../ws/telemetry/cmd/v2/UnsubscribeCmd.java | 2 +- .../telemetry/sub/AlarmSubscriptionUpdate.java | 2 +- .../ws/telemetry/sub/SubscriptionState.java | 2 +- .../sub/TelemetrySubscriptionUpdate.java | 2 +- ...pringfoxHandlerProviderBeanPostProcessor.java | 2 +- .../org/thingsboard/server/utils/CsvUtils.java | 2 +- .../server/utils/LwM2mObjectModelUtils.java | 2 +- .../org/thingsboard/server/utils/MiscUtils.java | 2 +- .../server/utils/TbNodeUpgradeUtils.java | 2 +- application/src/main/resources/logback.xml | 2 +- .../templates/2fa.verification.code.ftl | 2 +- .../resources/templates/account.activated.ftl | 2 +- .../main/resources/templates/account.lockout.ftl | 2 +- .../src/main/resources/templates/activation.ftl | 2 +- .../resources/templates/password.was.reset.ftl | 2 +- .../main/resources/templates/reset.password.ftl | 2 +- .../main/resources/templates/state.disabled.ftl | 2 +- .../main/resources/templates/state.enabled.ftl | 2 +- .../main/resources/templates/state.warning.ftl | 2 +- .../src/main/resources/templates/test.ftl | 2 +- application/src/main/resources/thingsboard.yml | 2 +- .../device/DeviceActorMessageProcessorTest.java | 2 +- .../server/actors/stats/StatsActorTest.java | 2 +- .../server/actors/stats/StatsPersistMsgTest.java | 2 +- .../CaffeineCacheDefaultConfigurationTest.java | 2 +- .../controller/AbstractControllerTest.java | 2 +- .../controller/AbstractInMemoryStorageTest.java | 2 +- .../controller/AbstractNotifyEntityTest.java | 2 +- .../AbstractRuleEngineControllerTest.java | 2 +- .../server/controller/AbstractWebTest.java | 2 +- .../server/controller/AdminControllerTest.java | 2 +- .../controller/AlarmCommentControllerTest.java | 2 +- .../server/controller/AlarmControllerTest.java | 2 +- .../server/controller/AssetControllerTest.java | 2 +- .../controller/AssetProfileControllerTest.java | 2 +- .../controller/AuditLogControllerTest.java | 2 +- .../server/controller/AuthControllerTest.java | 2 +- .../controller/BaseQueueControllerTest.java | 2 +- .../ComponentDescriptorControllerTest.java | 2 +- .../controller/CustomerControllerTest.java | 2 +- .../controller/DashboardControllerTest.java | 2 +- .../DeviceConnectivityControllerTest.java | 2 +- .../server/controller/DeviceControllerTest.java | 2 +- .../controller/DeviceProfileControllerTest.java | 2 +- .../server/controller/EdgeControllerTest.java | 2 +- .../controller/EdgeEventControllerTest.java | 2 +- .../controller/EntityQueryControllerTest.java | 2 +- .../controller/EntityRelationControllerTest.java | 2 +- .../controller/EntityViewControllerTest.java | 2 +- .../server/controller/HomePageApiTest.java | 2 +- .../server/controller/ImageControllerTest.java | 2 +- .../controller/OtaPackageControllerTest.java | 2 +- .../server/controller/RpcControllerTest.java | 2 +- .../controller/RuleChainControllerTest.java | 2 +- .../controller/TbResourceControllerTest.java | 2 +- .../server/controller/TbTestWebSocketClient.java | 2 +- .../controller/TelemetryControllerTest.java | 2 +- .../server/controller/TenantControllerTest.java | 2 +- .../controller/TenantProfileControllerTest.java | 2 +- .../controller/TwoFactorAuthConfigTest.java | 2 +- .../server/controller/TwoFactorAuthTest.java | 2 +- .../server/controller/UserControllerTest.java | 2 +- .../server/controller/WebsocketApiTest.java | 2 +- .../controller/WidgetTypeControllerTest.java | 2 +- .../controller/WidgetsBundleControllerTest.java | 2 +- .../plugin/TbWebSocketHandlerTest.java | 2 +- .../server/edge/AbstractEdgeTest.java | 2 +- .../thingsboard/server/edge/AlarmEdgeTest.java | 2 +- .../thingsboard/server/edge/AssetEdgeTest.java | 2 +- .../server/edge/AssetProfileEdgeTest.java | 2 +- .../server/edge/CustomerEdgeTest.java | 2 +- .../server/edge/DashboardEdgeTest.java | 2 +- .../thingsboard/server/edge/DeviceEdgeTest.java | 2 +- .../server/edge/DeviceProfileEdgeTest.java | 2 +- .../org/thingsboard/server/edge/EdgeTest.java | 2 +- .../server/edge/EntityViewEdgeTest.java | 2 +- .../server/edge/OtaPackageEdgeTest.java | 2 +- .../thingsboard/server/edge/QueueEdgeTest.java | 2 +- .../server/edge/RelationEdgeTest.java | 2 +- .../server/edge/ResourceEdgeTest.java | 2 +- .../server/edge/RuleChainEdgeTest.java | 2 +- .../server/edge/TelemetryEdgeTest.java | 2 +- .../thingsboard/server/edge/TenantEdgeTest.java | 2 +- .../server/edge/TenantProfileEdgeTest.java | 2 +- .../thingsboard/server/edge/UserEdgeTest.java | 2 +- .../thingsboard/server/edge/WidgetEdgeTest.java | 2 +- .../server/edge/imitator/EdgeImitator.java | 2 +- .../discovery/HashPartitionServiceTest.java | 2 +- .../AbstractRuleEngineFlowIntegrationTest.java | 2 +- .../sql/RuleEngineFlowSqlIntegrationTest.java | 2 +- ...stractRuleEngineLifecycleIntegrationTest.java | 2 +- .../RuleEngineLifecycleSqlIntegrationTest.java | 2 +- .../DefaultTbApiUsageStateServiceTest.java | 2 +- .../provision/DeviceProvisionServiceTest.java | 2 +- .../constructor/RuleChainMsgConstructorTest.java | 2 +- .../rpc/processor/BaseEdgeProcessorTest.java | 2 +- .../asset/AbstractAssetProcessorTest.java | 2 +- .../processor/asset/AssetEdgeProcessorTest.java | 2 +- .../asset/AssetProfileEdgeProcessorTest.java | 2 +- .../device/AbstractDeviceProcessorTest.java | 2 +- .../device/DeviceEdgeProcessorTest.java | 2 +- .../device/DeviceProfileEdgeProcessorTest.java | 2 +- .../telemetry/TelemetryEdgeProcessorTest.java | 2 +- .../entitiy/alarm/DefaultTbAlarmServiceTest.java | 2 +- .../DefaultTbAlarmCommentServiceTest.java | 2 +- .../service/install/InstallScriptsTest.java | 2 +- .../SqlEntityDatabaseSchemaServiceTest.java | 2 +- .../update/DefaultDataUpdateServiceTest.java | 2 +- .../service/limits/RateLimitServiceTest.java | 2 +- .../server/service/mail/TbMailSenderTest.java | 2 +- .../AbstractNotificationApiTest.java | 2 +- .../notification/NotificationApiTest.java | 2 +- .../notification/NotificationApiWsClient.java | 2 +- .../notification/NotificationRuleApiTest.java | 2 +- .../notification/NotificationTargetApiTest.java | 2 +- .../NotificationTemplateApiTest.java | 2 +- .../TestNotificationSettingsService.java | 2 +- .../queue/DefaultTbClusterServiceTest.java | 2 +- .../service/queue/TbMsgPackCallbackTest.java | 2 +- .../queue/TbMsgPackProcessingContextTest.java | 2 +- .../TbRuleEngineQueueConsumerManagerTest.java | 2 +- .../resource/sql/BaseTbResourceServiceTest.java | 2 +- .../service/rpc/RpcSubmitStrategyTest.java | 2 +- .../service/script/MockJsInvokeService.java | 2 +- .../script/NashornJsInvokeServiceTest.java | 2 +- .../script/RemoteJsInvokeServiceTest.java | 2 +- .../service/script/TbelInvokeServiceTest.java | 2 +- .../security/auth/JwtTokenFactoryTest.java | 2 +- .../security/auth/TokenOutdatingTest.java | 2 +- .../security/auth/oauth2/CookieUtilsTest.java | 2 +- .../Oauth2AuthenticationSuccessHandlerTest.java | 2 +- .../service/sms/DefaultSmsServiceTest.java | 2 +- .../service/sms/smpp/SmppSmsSenderTest.java | 2 +- .../sql/SequentialTimeseriesPersistenceTest.java | 2 +- .../state/DefaultDeviceStateServiceTest.java | 2 +- .../service/stats/DevicesStatisticsTest.java | 2 +- .../sync/ie/BaseExportImportServiceTest.java | 2 +- .../sync/ie/ExportImportServiceSqlTest.java | 2 +- .../DefaultTransportApiServiceTest.java | 2 +- .../service/ttl/AlarmsCleanUpServiceTest.java | 2 +- .../service/ttl/EventsCleanUpServiceTest.java | 2 +- .../server/system/BaseHttpDeviceApiTest.java | 2 +- .../server/system/BaseRestApiLimitsTest.java | 2 +- .../system/RestTemplateConvertersTest.java | 2 +- .../server/system/sql/DeviceApiSqlTest.java | 2 +- .../server/system/sql/RestApiLimitsSqlTest.java | 2 +- .../AbstractTransportIntegrationTest.java | 2 +- .../transport/TransportNoSqlTestSuite.java | 2 +- .../coap/AbstractCoapIntegrationTest.java | 2 +- .../server/transport/coap/CoapTestCallback.java | 2 +- .../server/transport/coap/CoapTestClient.java | 2 +- .../transport/coap/CoapTestConfigProperties.java | 2 +- .../AbstractCoapAttributesIntegrationTest.java | 2 +- .../CoapAttributesRequestIntegrationTest.java | 2 +- ...CoapAttributesRequestJsonIntegrationTest.java | 2 +- ...oapAttributesRequestProtoIntegrationTest.java | 2 +- .../CoapAttributesUpdatesIntegrationTest.java | 2 +- ...CoapAttributesUpdatesJsonIntegrationTest.java | 2 +- ...oapAttributesUpdatesProtoIntegrationTest.java | 2 +- .../coap/claim/CoapClaimDeviceTest.java | 2 +- .../coap/claim/CoapClaimJsonDeviceTest.java | 2 +- .../coap/claim/CoapClaimProtoDeviceTest.java | 2 +- .../coap/client/CoapClientIntegrationTest.java | 2 +- .../provision/CoapProvisionJsonDeviceTest.java | 2 +- .../provision/CoapProvisionProtoDeviceTest.java | 2 +- ...AbstractCoapServerSideRpcIntegrationTest.java | 2 +- .../CoapServerSideRpcDefaultIntegrationTest.java | 2 +- .../CoapServerSideRpcJsonIntegrationTest.java | 2 +- .../CoapServerSideRpcProtoIntegrationTest.java | 2 +- .../CoapAttributesIntegrationTest.java | 2 +- .../CoapAttributesJsonIntegrationTest.java | 2 +- .../CoapAttributesProtoIntegrationTest.java | 2 +- .../AbstractCoapTimeseriesIntegrationTest.java | 2 +- ...bstractCoapTimeseriesJsonIntegrationTest.java | 2 +- ...stractCoapTimeseriesProtoIntegrationTest.java | 2 +- .../CoapTimeseriesNoSqlIntegrationTest.java | 2 +- .../CoapTimeseriesNoSqlJsonIntegrationTest.java | 2 +- .../CoapTimeseriesNoSqlProtoIntegrationTest.java | 2 +- .../sql/CoapTimeseriesSqlIntegrationTest.java | 2 +- .../CoapTimeseriesSqlJsonIntegrationTest.java | 2 +- .../CoapTimeseriesSqlProtoIntegrationTest.java | 2 +- .../lwm2m/AbstractLwM2MIntegrationTest.java | 2 +- .../server/transport/lwm2m/Lwm2mTestHelper.java | 2 +- .../transport/lwm2m/client/FwLwM2MDevice.java | 2 +- .../lwm2m/client/LwM2MLocationParams.java | 2 +- .../transport/lwm2m/client/LwM2MTestClient.java | 2 +- .../client/LwM2mBinaryAppDataContainer.java | 2 +- .../transport/lwm2m/client/LwM2mLocation.java | 2 +- .../lwm2m/client/LwM2mTemperatureSensor.java | 2 +- .../transport/lwm2m/client/Lwm2mServer.java | 2 +- .../lwm2m/client/SimpleLwM2MDevice.java | 2 +- .../transport/lwm2m/client/SwLwM2MDevice.java | 2 +- .../ota/AbstractOtaLwM2MIntegrationTest.java | 2 +- .../lwm2m/ota/sql/OtaLwM2MIntegrationTest.java | 2 +- .../rpc/AbstractRpcLwM2MIntegrationTest.java | 2 +- .../rpc/sql/RpcLwm2mIntegrationCreateTest.java | 2 +- .../rpc/sql/RpcLwm2mIntegrationDeleteTest.java | 2 +- .../rpc/sql/RpcLwm2mIntegrationDiscoverTest.java | 2 +- .../rpc/sql/RpcLwm2mIntegrationExecuteTest.java | 2 +- .../rpc/sql/RpcLwm2mIntegrationObserveTest.java | 2 +- .../rpc/sql/RpcLwm2mIntegrationReadTest.java | 2 +- .../RpcLwm2mIntegrationWriteAttributesTest.java | 2 +- .../rpc/sql/RpcLwm2mIntegrationWriteTest.java | 2 +- .../AbstractSecurityLwM2MIntegrationTest.java | 2 +- .../security/sql/NoSecLwM2MIntegrationTest.java | 2 +- .../security/sql/PskLwm2mIntegrationTest.java | 2 +- .../security/sql/RpkLwM2MIntegrationTest.java | 2 +- .../sql/X509_NoTrustLwM2MIntegrationTest.java | 2 +- .../sql/X509_TrustLwM2MIntegrationTest.java | 2 +- .../server/LwM2mTransportServerHelperTest.java | 2 +- .../mqtt/AbstractMqttIntegrationTest.java | 2 +- .../transport/mqtt/MqttTestConfigProperties.java | 2 +- .../transport/mqtt/mqttv3/MqttTestCallback.java | 2 +- .../transport/mqtt/mqttv3/MqttTestClient.java | 2 +- .../mqttv3/MqttTestSubscribeOnTopicCallback.java | 2 +- .../AbstractMqttAttributesIntegrationTest.java | 2 +- ...uestBackwardCompatibilityIntegrationTest.java | 2 +- .../MqttAttributesRequestIntegrationTest.java | 2 +- ...MqttAttributesRequestJsonIntegrationTest.java | 2 +- ...qttAttributesRequestProtoIntegrationTest.java | 2 +- ...atesBackwardCompatibilityIntegrationTest.java | 2 +- .../MqttAttributesUpdatesIntegrationTest.java | 2 +- ...MqttAttributesUpdatesJsonIntegrationTest.java | 2 +- ...qttAttributesUpdatesProtoIntegrationTest.java | 2 +- ...MqttClaimBackwardCompatibilityDeviceTest.java | 2 +- .../mqtt/mqttv3/claim/MqttClaimDeviceTest.java | 2 +- .../mqttv3/claim/MqttClaimJsonDeviceTest.java | 2 +- .../mqttv3/claim/MqttClaimProtoDeviceTest.java | 2 +- .../client/AbstractMqttClientConnectionTest.java | 2 +- .../mqttv3/client/MqttClientConnectionTest.java | 2 +- .../credentials/BasicMqttCredentialsTest.java | 2 +- .../provision/MqttProvisionJsonDeviceTest.java | 2 +- .../provision/MqttProvisionProtoDeviceTest.java | 2 +- ...AbstractMqttServerSideRpcIntegrationTest.java | 2 +- ...eRpcBackwardCompatibilityIntegrationTest.java | 2 +- .../MqttServerSideRpcDefaultIntegrationTest.java | 2 +- .../MqttServerSideRpcJsonIntegrationTest.java | 2 +- .../MqttServerSideRpcProtoIntegrationTest.java | 2 +- ...erverSideRpcSequenceOnAckIntegrationTest.java | 2 +- ...SideRpcSequenceOnResponseIntegrationTest.java | 2 +- .../MqttAttributesIntegrationTest.java | 2 +- .../MqttAttributesJsonIntegrationTest.java | 2 +- .../MqttAttributesProtoIntegrationTest.java | 2 +- .../AbstractMqttTimeseriesIntegrationTest.java | 2 +- ...bstractMqttTimeseriesJsonIntegrationTest.java | 2 +- ...stractMqttTimeseriesProtoIntegrationTest.java | 2 +- .../MqttTimeseriesNoSqlIntegrationTest.java | 2 +- .../MqttTimeseriesNoSqlJsonIntegrationTest.java | 2 +- .../MqttTimeseriesNoSqlProtoIntegrationTest.java | 2 +- .../sql/MqttTimeseriesSqlIntegrationTest.java | 2 +- .../MqttTimeseriesSqlJsonIntegrationTest.java | 2 +- .../MqttTimeseriesSqlProtoIntegrationTest.java | 2 +- .../mqtt/mqttv5/AbstractMqttV5Test.java | 2 +- .../mqtt/mqttv5/MqttV5TestCallback.java | 2 +- .../transport/mqtt/mqttv5/MqttV5TestClient.java | 2 +- .../attributes/AbstractAttributesMqttV5Test.java | 2 +- .../updates/AttributesUpdatesTest.java | 2 +- .../attributes/upload/AttributesPublishTest.java | 2 +- .../mqttv5/claim/AbstractMqttV5ClaimTest.java | 2 +- .../mqtt/mqttv5/claim/MqttV5ClaimTest.java | 2 +- .../AbstractMqttV5ClientConnectionTest.java | 2 +- .../connection/MqttV5ClientConnectionTest.java | 2 +- .../publish/AbstractMqttV5ClientPublishTest.java | 2 +- .../client/publish/MqttV5ClientPublishTest.java | 2 +- .../AbstractMqttV5ClientSubscriptionTest.java | 2 +- .../subscribe/MqttV5ClientSubscriptionTest.java | 2 +- .../AbstractMqttV5ClientUnsubscribeTest.java | 2 +- .../unsubscribe/MqttV5ClientUnsubscribeTest.java | 2 +- .../provision/MqttV5ProvisionDeviceTest.java | 2 +- .../mqtt/mqttv5/rpc/AbstractMqttV5RpcTest.java | 2 +- .../transport/mqtt/mqttv5/rpc/MqttV5RpcTest.java | 2 +- .../timeseries/AbstractMqttV5TimeseriesTest.java | 2 +- .../mqttv5/timeseries/MqttV5TimeseriesTest.java | 2 +- .../AbstractMqttV5ClientSparkplugTest.java | 2 +- ...tractMqttV5ClientSparkplugAttributesTest.java | 2 +- ...5ClientSparkplugBAttributesInProfileTest.java | 2 +- .../MqttV5ClientSparkplugBAttributesTest.java | 2 +- ...tractMqttV5ClientSparkplugConnectionTest.java | 2 +- .../MqttV5ClientSparkplugBConnectionTest.java | 2 +- .../rpc/AbstractMqttV5RpcSparkplugTest.java | 2 +- .../sparkplug/rpc/MqttV5RpcSparkplugTest.java | 2 +- ...stractMqttV5ClientSparkplugTelemetryTest.java | 2 +- .../MqttV5ClientSparkplugBTelemetryTest.java | 2 +- .../server/utils/TbNodeUpgradeUtilsTest.java | 2 +- build_proto.sh | 2 +- common/actor/pom.xml | 2 +- .../server/actors/AbstractTbActor.java | 2 +- .../server/actors/DefaultTbActorSystem.java | 2 +- .../thingsboard/server/actors/Dispatcher.java | 2 +- .../server/actors/InitFailureStrategy.java | 2 +- .../thingsboard/server/actors/JsInvokeStats.java | 2 +- .../server/actors/ProcessFailureStrategy.java | 2 +- .../org/thingsboard/server/actors/TbActor.java | 2 +- .../server/actors/TbActorCreator.java | 2 +- .../thingsboard/server/actors/TbActorCtx.java | 2 +- .../server/actors/TbActorException.java | 2 +- .../org/thingsboard/server/actors/TbActorId.java | 2 +- .../server/actors/TbActorMailbox.java | 2 +- .../actors/TbActorNotRegisteredException.java | 2 +- .../thingsboard/server/actors/TbActorRef.java | 2 +- .../thingsboard/server/actors/TbActorSystem.java | 2 +- .../server/actors/TbActorSystemSettings.java | 2 +- .../server/actors/TbEntityActorId.java | 2 +- .../server/actors/TbRuleNodeUpdateException.java | 2 +- .../server/actors/TbStringActorId.java | 2 +- .../server/actors/ActorSystemTest.java | 2 +- .../thingsboard/server/actors/ActorTestCtx.java | 2 +- .../server/actors/FailedToInitActor.java | 2 +- .../thingsboard/server/actors/IntTbActorMsg.java | 2 +- .../server/actors/SlowCreateActor.java | 2 +- .../thingsboard/server/actors/SlowInitActor.java | 2 +- .../thingsboard/server/actors/TestRootActor.java | 2 +- common/cache/pom.xml | 2 +- .../org/thingsboard/server/cache/CacheSpecs.java | 2 +- .../thingsboard/server/cache/CacheSpecsMap.java | 2 +- .../server/cache/CaffeineTbCacheTransaction.java | 2 +- .../cache/CaffeineTbTransactionalCache.java | 2 +- .../server/cache/RedisTbCacheTransaction.java | 2 +- .../server/cache/RedisTbTransactionalCache.java | 2 +- .../server/cache/SimpleTbCacheValueWrapper.java | 2 +- .../server/cache/TBRedisCacheConfiguration.java | 2 +- .../cache/TBRedisClusterConfiguration.java | 2 +- .../cache/TBRedisSentinelConfiguration.java | 2 +- .../cache/TBRedisStandaloneConfiguration.java | 2 +- .../server/cache/TbCacheTransaction.java | 2 +- .../server/cache/TbCacheValueWrapper.java | 2 +- .../cache/TbCaffeineCacheConfiguration.java | 2 +- .../server/cache/TbFSTRedisSerializer.java | 2 +- .../server/cache/TbRedisSerializer.java | 2 +- .../server/cache/TbTransactionalCache.java | 2 +- .../cache/device/DeviceCacheEvictEvent.java | 2 +- .../server/cache/device/DeviceCacheKey.java | 2 +- .../server/cache/device/DeviceCaffeineCache.java | 2 +- .../server/cache/device/DeviceRedisCache.java | 2 +- .../cache/ota/CaffeineOtaPackageCache.java | 2 +- .../server/cache/ota/OtaPackageDataCache.java | 2 +- .../cache/ota/RedisOtaPackageDataCache.java | 2 +- .../cache/resourceInfo/ResourceInfoCacheKey.java | 2 +- .../resourceInfo/ResourceInfoCaffeineCache.java | 2 +- .../resourceInfo/ResourceInfoEvictEvent.java | 2 +- .../resourceInfo/ResourceInfoRedisCache.java | 2 +- .../UsersSessionInvalidationCaffeineCache.java | 2 +- .../UsersSessionInvalidationRedisCache.java | 2 +- .../server/cache/CacheSpecsMapTest.java | 2 +- common/cluster-api/pom.xml | 2 +- .../server/cluster/TbClusterService.java | 2 +- .../thingsboard/server/queue/TbQueueAdmin.java | 2 +- .../server/queue/TbQueueCallback.java | 2 +- .../server/queue/TbQueueClusterService.java | 2 +- .../server/queue/TbQueueConsumer.java | 2 +- .../thingsboard/server/queue/TbQueueHandler.java | 2 +- .../org/thingsboard/server/queue/TbQueueMsg.java | 2 +- .../server/queue/TbQueueMsgDecoder.java | 2 +- .../server/queue/TbQueueMsgHeaders.java | 2 +- .../server/queue/TbQueueMsgMetadata.java | 2 +- .../server/queue/TbQueueProducer.java | 2 +- .../server/queue/TbQueueRequestTemplate.java | 2 +- .../server/queue/TbQueueResponseTemplate.java | 2 +- common/coap-server/pom.xml | 2 +- .../server/coapserver/CoapServerContext.java | 2 +- .../server/coapserver/CoapServerService.java | 2 +- .../coapserver/DefaultCoapServerService.java | 2 +- .../TbCoapDtlsCertificateVerifier.java | 2 +- .../TbCoapDtlsSessionInMemoryStorage.java | 2 +- .../server/coapserver/TbCoapDtlsSessionInfo.java | 2 +- .../server/coapserver/TbCoapDtlsSettings.java | 2 +- .../server/coapserver/TbCoapServerComponent.java | 2 +- .../coapserver/TbCoapServerMessageDeliverer.java | 2 +- common/dao-api/pom.xml | 2 +- .../server/dao/alarm/AlarmCommentService.java | 2 +- .../server/dao/alarm/AlarmService.java | 2 +- .../server/dao/asset/AssetProfileService.java | 2 +- .../server/dao/asset/AssetService.java | 2 +- .../server/dao/attributes/AttributesService.java | 2 +- .../server/dao/audit/AuditLogService.java | 2 +- .../dao/cassandra/AbstractCassandraCluster.java | 2 +- .../server/dao/cassandra/CassandraCluster.java | 2 +- .../dao/cassandra/CassandraDriverOptions.java | 2 +- .../dao/cassandra/CassandraInstallCluster.java | 2 +- .../dao/cassandra/guava/DefaultGuavaSession.java | 2 +- .../dao/cassandra/guava/GuavaDriverContext.java | 2 +- .../cassandra/guava/GuavaMultiPageResultSet.java | 2 +- .../guava/GuavaRequestAsyncProcessor.java | 2 +- .../server/dao/cassandra/guava/GuavaSession.java | 2 +- .../dao/cassandra/guava/GuavaSessionBuilder.java | 2 +- .../dao/cassandra/guava/GuavaSessionUtils.java | 2 +- .../component/ComponentDescriptorService.java | 2 +- .../server/dao/customer/CustomerService.java | 2 +- .../server/dao/dashboard/DashboardService.java | 2 +- .../server/dao/device/ClaimDevicesService.java | 2 +- .../dao/device/DeviceConnectivityService.java | 2 +- .../dao/device/DeviceCredentialsService.java | 2 +- .../server/dao/device/DeviceProfileService.java | 2 +- .../dao/device/DeviceProvisionService.java | 2 +- .../server/dao/device/DeviceService.java | 2 +- .../server/dao/device/claim/ClaimData.java | 2 +- .../server/dao/device/claim/ClaimResponse.java | 2 +- .../server/dao/device/claim/ClaimResult.java | 2 +- .../server/dao/device/claim/ReclaimResult.java | 2 +- .../provision/ProvisionFailedException.java | 2 +- .../dao/device/provision/ProvisionRequest.java | 2 +- .../dao/device/provision/ProvisionResponse.java | 2 +- .../provision/ProvisionResponseStatus.java | 2 +- .../server/dao/edge/EdgeEventService.java | 2 +- .../thingsboard/server/dao/edge/EdgeService.java | 2 +- .../dao/edge/EdgeSynchronizationManager.java | 2 +- .../server/dao/entity/EntityCountService.java | 2 +- .../server/dao/entity/EntityDaoService.java | 2 +- .../server/dao/entity/EntityService.java | 2 +- .../server/dao/entity/EntityServiceRegistry.java | 2 +- .../server/dao/entityview/EntityViewService.java | 2 +- .../server/dao/event/EventService.java | 2 +- .../dao/housekeeper/HouseKeeperService.java | 2 +- .../server/dao/nosql/CassandraStatementTask.java | 2 +- .../server/dao/nosql/TbResultSet.java | 2 +- .../server/dao/nosql/TbResultSetFuture.java | 2 +- .../notification/NotificationRequestService.java | 2 +- .../notification/NotificationRuleService.java | 2 +- .../dao/notification/NotificationService.java | 2 +- .../NotificationSettingsService.java | 2 +- .../notification/NotificationTargetService.java | 2 +- .../NotificationTemplateService.java | 2 +- .../dao/oauth2/OAuth2ConfigTemplateService.java | 2 +- .../server/dao/oauth2/OAuth2Service.java | 2 +- .../server/dao/oauth2/OAuth2User.java | 2 +- .../server/dao/ota/OtaPackageService.java | 2 +- .../server/dao/queue/QueueService.java | 2 +- .../server/dao/relation/RelationService.java | 2 +- .../server/dao/resource/ImageService.java | 2 +- .../server/dao/resource/ResourceService.java | 2 +- .../thingsboard/server/dao/rpc/RpcService.java | 2 +- .../server/dao/rule/RuleChainService.java | 2 +- .../server/dao/rule/RuleNodeStateService.java | 2 +- .../dao/settings/AdminSettingsService.java | 2 +- .../server/dao/tenant/TbTenantProfileCache.java | 2 +- .../server/dao/tenant/TenantProfileService.java | 2 +- .../server/dao/tenant/TenantService.java | 2 +- .../server/dao/timeseries/TimeseriesService.java | 2 +- .../server/dao/usage/UsageInfoService.java | 2 +- .../server/dao/usagerecord/ApiLimitService.java | 2 +- .../dao/usagerecord/ApiUsageStateService.java | 2 +- .../thingsboard/server/dao/user/UserService.java | 2 +- .../server/dao/user/UserSettingsService.java | 2 +- .../thingsboard/server/dao/util/AsyncTask.java | 2 +- .../server/dao/util/DbTypeInfoComponent.java | 2 +- .../dao/util/DefaultDbTypeInfoComponent.java | 2 +- .../thingsboard/server/dao/util/NoSqlAnyDao.java | 2 +- .../server/dao/util/NoSqlAnyDaoNonCloud.java | 2 +- .../thingsboard/server/dao/util/NoSqlTsDao.java | 2 +- .../server/dao/util/NoSqlTsLatestDao.java | 2 +- .../org/thingsboard/server/dao/util/SqlDao.java | 2 +- .../thingsboard/server/dao/util/SqlTsDao.java | 2 +- .../server/dao/util/SqlTsLatestAnyDao.java | 2 +- .../server/dao/util/SqlTsLatestDao.java | 2 +- .../server/dao/util/SqlTsOrTsLatestAnyDao.java | 2 +- .../server/dao/util/TbAutoConfiguration.java | 2 +- .../server/dao/util/TimescaleDBTsDao.java | 2 +- .../server/dao/util/TimescaleDBTsLatestDao.java | 2 +- .../dao/util/TimescaleDBTsOrTsLatestDao.java | 2 +- .../server/dao/widget/WidgetTypeService.java | 2 +- .../server/dao/widget/WidgetsBundleService.java | 2 +- common/data/pom.xml | 2 +- .../server/common/data/AdminSettings.java | 2 +- .../server/common/data/ApiFeature.java | 2 +- .../server/common/data/ApiUsageRecordKey.java | 2 +- .../server/common/data/ApiUsageRecordState.java | 2 +- .../server/common/data/ApiUsageState.java | 2 +- .../server/common/data/ApiUsageStateValue.java | 2 +- .../thingsboard/server/common/data/BaseData.java | 2 +- .../common/data/BaseDataWithAdditionalInfo.java | 2 +- .../server/common/data/CacheConstants.java | 2 +- .../server/common/data/ClaimRequest.java | 2 +- .../server/common/data/CoapDeviceType.java | 2 +- .../server/common/data/ContactBased.java | 2 +- .../thingsboard/server/common/data/Customer.java | 2 +- .../server/common/data/Dashboard.java | 2 +- .../server/common/data/DashboardInfo.java | 2 +- .../server/common/data/DataConstants.java | 2 +- .../thingsboard/server/common/data/Device.java | 2 +- .../server/common/data/DeviceIdInfo.java | 2 +- .../server/common/data/DeviceInfo.java | 2 +- .../server/common/data/DeviceInfoFilter.java | 2 +- .../server/common/data/DeviceProfile.java | 2 +- .../server/common/data/DeviceProfileInfo.java | 2 +- .../common/data/DeviceProfileProvisionType.java | 2 +- .../server/common/data/DeviceProfileType.java | 2 +- .../server/common/data/DeviceTransportType.java | 2 +- .../server/common/data/DynamicProtoUtils.java | 2 +- .../server/common/data/EdgeUpgradeInfo.java | 2 +- .../server/common/data/EdgeUpgradeMessage.java | 2 +- .../server/common/data/EdgeUtils.java | 2 +- .../server/common/data/EntityFieldsData.java | 2 +- .../server/common/data/EntityInfo.java | 2 +- .../server/common/data/EntitySubtype.java | 2 +- .../server/common/data/EntityType.java | 2 +- .../server/common/data/EntityView.java | 2 +- .../server/common/data/EntityViewInfo.java | 2 +- .../server/common/data/EventInfo.java | 2 +- .../server/common/data/ExportableEntity.java | 2 +- .../thingsboard/server/common/data/FSTUtils.java | 2 +- .../server/common/data/FeaturesInfo.java | 2 +- .../server/common/data/FstStatsService.java | 2 +- .../server/common/data/HasAdditionalInfo.java | 2 +- .../server/common/data/HasCustomerId.java | 2 +- .../thingsboard/server/common/data/HasEmail.java | 2 +- .../thingsboard/server/common/data/HasImage.java | 2 +- .../thingsboard/server/common/data/HasLabel.java | 2 +- .../thingsboard/server/common/data/HasName.java | 2 +- .../server/common/data/HasOtaPackage.java | 2 +- .../server/common/data/HasRuleEngineProfile.java | 2 +- .../server/common/data/HasTenantId.java | 2 +- .../thingsboard/server/common/data/HasTitle.java | 2 +- .../server/common/data/HomeDashboard.java | 2 +- .../server/common/data/HomeDashboardInfo.java | 2 +- .../server/common/data/ImageDescriptor.java | 2 +- .../server/common/data/ImageExportData.java | 2 +- .../server/common/data/OtaPackage.java | 2 +- .../server/common/data/OtaPackageInfo.java | 2 +- .../server/common/data/ResourceType.java | 2 +- .../server/common/data/ResourceUtils.java | 2 +- .../data/SaveDeviceWithCredentialsRequest.java | 2 +- .../common/data/SaveOtaPackageInfoRequest.java | 2 +- .../server/common/data/ShortCustomerInfo.java | 2 +- .../server/common/data/StringUtils.java | 2 +- .../server/common/data/SystemInfo.java | 2 +- .../server/common/data/SystemInfoData.java | 2 +- .../server/common/data/SystemParams.java | 2 +- .../server/common/data/TbImageDeleteResult.java | 2 +- .../server/common/data/TbProperty.java | 2 +- .../server/common/data/TbResource.java | 2 +- .../server/common/data/TbResourceInfo.java | 2 +- .../server/common/data/TbResourceInfoFilter.java | 2 +- .../server/common/data/TbTransportService.java | 2 +- .../thingsboard/server/common/data/Tenant.java | 2 +- .../server/common/data/TenantInfo.java | 2 +- .../server/common/data/TenantProfile.java | 2 +- .../server/common/data/TenantProfileType.java | 2 +- .../server/common/data/TransportPayloadType.java | 2 +- .../server/common/data/UUIDConverter.java | 2 +- .../server/common/data/UpdateMessage.java | 2 +- .../server/common/data/UsageInfo.java | 2 +- .../org/thingsboard/server/common/data/User.java | 2 +- .../server/common/data/UserEmailInfo.java | 2 +- .../server/common/data/alarm/Alarm.java | 2 +- .../common/data/alarm/AlarmApiCallResult.java | 2 +- .../server/common/data/alarm/AlarmAssignee.java | 2 +- .../common/data/alarm/AlarmAssigneeUpdate.java | 2 +- .../server/common/data/alarm/AlarmComment.java | 2 +- .../common/data/alarm/AlarmCommentInfo.java | 2 +- .../common/data/alarm/AlarmCommentType.java | 2 +- .../alarm/AlarmCreateOrUpdateActiveRequest.java | 2 +- .../server/common/data/alarm/AlarmInfo.java | 2 +- .../data/alarm/AlarmModificationRequest.java | 2 +- .../common/data/alarm/AlarmPropagationInfo.java | 2 +- .../server/common/data/alarm/AlarmQuery.java | 2 +- .../server/common/data/alarm/AlarmQueryV2.java | 2 +- .../common/data/alarm/AlarmSearchStatus.java | 2 +- .../server/common/data/alarm/AlarmSeverity.java | 2 +- .../server/common/data/alarm/AlarmStatus.java | 2 +- .../common/data/alarm/AlarmStatusFilter.java | 2 +- .../common/data/alarm/AlarmUpdateRequest.java | 2 +- .../server/common/data/alarm/EntityAlarm.java | 2 +- .../server/common/data/asset/Asset.java | 2 +- .../server/common/data/asset/AssetInfo.java | 2 +- .../server/common/data/asset/AssetProfile.java | 2 +- .../common/data/asset/AssetProfileInfo.java | 2 +- .../common/data/asset/AssetSearchQuery.java | 2 +- .../server/common/data/audit/ActionStatus.java | 2 +- .../server/common/data/audit/ActionType.java | 2 +- .../server/common/data/audit/AuditLog.java | 2 +- .../common/data/device/DeviceSearchQuery.java | 2 +- .../device/credentials/BasicMqttCredentials.java | 2 +- .../ProvisionDeviceCredentialsData.java | 2 +- ...ctLwM2MBootstrapClientCredentialWithKeys.java | 2 +- .../lwm2m/AbstractLwM2MClientCredential.java | 2 +- .../AbstractLwM2MClientSecurityCredential.java | 2 +- .../lwm2m/LwM2MBootstrapClientCredential.java | 2 +- .../lwm2m/LwM2MBootstrapClientCredentials.java | 2 +- .../credentials/lwm2m/LwM2MClientCredential.java | 2 +- .../lwm2m/LwM2MDeviceCredentials.java | 2 +- .../credentials/lwm2m/LwM2MSecurityMode.java | 2 +- .../lwm2m/NoSecBootstrapClientCredential.java | 2 +- .../credentials/lwm2m/NoSecClientCredential.java | 2 +- .../lwm2m/PSKBootstrapClientCredential.java | 2 +- .../credentials/lwm2m/PSKClientCredential.java | 2 +- .../lwm2m/RPKBootstrapClientCredential.java | 2 +- .../credentials/lwm2m/RPKClientCredential.java | 2 +- .../lwm2m/X509BootstrapClientCredential.java | 2 +- .../credentials/lwm2m/X509ClientCredential.java | 2 +- .../data/CoapDeviceTransportConfiguration.java | 2 +- .../device/data/DefaultDeviceConfiguration.java | 2 +- .../DefaultDeviceTransportConfiguration.java | 2 +- .../data/device/data/DeviceConfiguration.java | 2 +- .../common/data/device/data/DeviceData.java | 2 +- .../data/DeviceTransportConfiguration.java | 2 +- .../data/Lwm2mDeviceTransportConfiguration.java | 2 +- .../data/MqttDeviceTransportConfiguration.java | 2 +- .../common/data/device/data/PowerMode.java | 2 +- .../device/data/PowerSavingConfiguration.java | 2 +- .../data/SnmpDeviceTransportConfiguration.java | 2 +- .../data/device/profile/AlarmCondition.java | 2 +- .../device/profile/AlarmConditionFilter.java | 2 +- .../device/profile/AlarmConditionFilterKey.java | 2 +- .../device/profile/AlarmConditionKeyType.java | 2 +- .../data/device/profile/AlarmConditionSpec.java | 2 +- .../device/profile/AlarmConditionSpecType.java | 2 +- .../common/data/device/profile/AlarmRule.java | 2 +- .../data/device/profile/AlarmSchedule.java | 2 +- .../data/device/profile/AlarmScheduleType.java | 2 +- ...vicesDeviceProfileProvisionConfiguration.java | 2 +- .../data/device/profile/AnyTimeSchedule.java | 2 +- ...vicesDeviceProfileProvisionConfiguration.java | 2 +- .../CoapDeviceProfileTransportConfiguration.java | 2 +- .../profile/CoapDeviceTypeConfiguration.java | 2 +- .../data/device/profile/CustomTimeSchedule.java | 2 +- .../device/profile/CustomTimeScheduleItem.java | 2 +- .../DefaultCoapDeviceTypeConfiguration.java | 2 +- .../DefaultDeviceProfileConfiguration.java | 2 +- ...faultDeviceProfileTransportConfiguration.java | 2 +- .../data/device/profile/DeviceProfileAlarm.java | 2 +- .../profile/DeviceProfileConfiguration.java | 2 +- .../data/device/profile/DeviceProfileData.java | 2 +- .../DeviceProfileProvisionConfiguration.java | 2 +- .../DeviceProfileTransportConfiguration.java | 2 +- ...abledDeviceProfileProvisionConfiguration.java | 2 +- .../profile/DurationAlarmConditionSpec.java | 2 +- .../EfentoCoapDeviceTypeConfiguration.java | 2 +- .../JsonTransportPayloadConfiguration.java | 2 +- ...Lwm2mDeviceProfileTransportConfiguration.java | 2 +- .../MqttDeviceProfileTransportConfiguration.java | 2 +- .../common/data/device/profile/MqttTopics.java | 2 +- .../ProtoTransportPayloadConfiguration.java | 2 +- .../ProvisionDeviceProfileCredentials.java | 2 +- .../profile/RepeatingAlarmConditionSpec.java | 2 +- .../device/profile/SimpleAlarmConditionSpec.java | 2 +- .../SnmpDeviceProfileTransportConfiguration.java | 2 +- .../device/profile/SpecificTimeSchedule.java | 2 +- .../TransportPayloadTypeConfiguration.java | 2 +- ...09CertificateChainProvisionConfiguration.java | 3 +-- .../device/profile/lwm2m/ObjectAttributes.java | 2 +- .../device/profile/lwm2m/OtherConfiguration.java | 2 +- .../lwm2m/TelemetryMappingConfiguration.java | 2 +- .../AbstractLwM2MBootstrapServerCredential.java | 2 +- .../LwM2MBootstrapServerCredential.java | 2 +- .../bootstrap/LwM2MServerSecurityConfig.java | 2 +- .../LwM2MServerSecurityConfigDefault.java | 2 +- .../NoSecLwM2MBootstrapServerCredential.java | 2 +- .../PSKLwM2MBootstrapServerCredential.java | 2 +- .../RPKLwM2MBootstrapServerCredential.java | 2 +- .../X509LwM2MBootstrapServerCredential.java | 2 +- .../server/common/data/edge/Edge.java | 2 +- .../server/common/data/edge/EdgeEvent.java | 2 +- .../common/data/edge/EdgeEventActionType.java | 2 +- .../server/common/data/edge/EdgeEventType.java | 2 +- .../server/common/data/edge/EdgeInfo.java | 2 +- .../common/data/edge/EdgeInstructions.java | 2 +- .../server/common/data/edge/EdgeSearchQuery.java | 2 +- .../data/entityview/EntityViewSearchQuery.java | 2 +- .../common/data/event/DebugEventFilter.java | 2 +- .../server/common/data/event/ErrorEvent.java | 2 +- .../common/data/event/ErrorEventFilter.java | 2 +- .../server/common/data/event/Event.java | 2 +- .../server/common/data/event/EventFilter.java | 2 +- .../server/common/data/event/EventType.java | 2 +- .../common/data/event/LifeCycleEventFilter.java | 2 +- .../server/common/data/event/LifecycleEvent.java | 2 +- .../common/data/event/RuleChainDebugEvent.java | 2 +- .../data/event/RuleChainDebugEventFilter.java | 2 +- .../common/data/event/RuleNodeDebugEvent.java | 2 +- .../data/event/RuleNodeDebugEventFilter.java | 2 +- .../common/data/event/StatisticsEvent.java | 2 +- .../common/data/event/StatisticsEventFilter.java | 2 +- .../exception/AbstractRateLimitException.java | 2 +- .../ApiUsageLimitsExceededException.java | 2 +- .../data/exception/TenantNotFoundException.java | 2 +- .../TenantProfileNotFoundException.java | 2 +- .../data/exception/ThingsboardErrorCode.java | 2 +- .../data/exception/ThingsboardException.java | 2 +- .../exception/ThingsboardKafkaClientError.java | 2 +- .../server/common/data/id/AdminSettingsId.java | 2 +- .../server/common/data/id/AlarmCommentId.java | 2 +- .../server/common/data/id/AlarmId.java | 2 +- .../server/common/data/id/ApiUsageStateId.java | 2 +- .../server/common/data/id/AssetId.java | 2 +- .../server/common/data/id/AssetProfileId.java | 2 +- .../server/common/data/id/AuditLogId.java | 2 +- .../common/data/id/ComponentDescriptorId.java | 2 +- .../server/common/data/id/CustomerId.java | 2 +- .../server/common/data/id/DashboardId.java | 2 +- .../common/data/id/DeviceCredentialsId.java | 2 +- .../server/common/data/id/DeviceId.java | 2 +- .../server/common/data/id/DeviceProfileId.java | 2 +- .../server/common/data/id/EdgeEventId.java | 2 +- .../server/common/data/id/EdgeId.java | 2 +- .../server/common/data/id/EntityId.java | 2 +- .../common/data/id/EntityIdDeserializer.java | 2 +- .../server/common/data/id/EntityIdFactory.java | 2 +- .../common/data/id/EntityIdSerializer.java | 2 +- .../server/common/data/id/EntityViewId.java | 2 +- .../server/common/data/id/EventId.java | 2 +- .../thingsboard/server/common/data/id/HasId.java | 2 +- .../server/common/data/id/HasUUID.java | 2 +- .../server/common/data/id/IdBased.java | 2 +- .../data/id/NameLabelAndCustomerDetails.java | 2 +- .../server/common/data/id/NodeId.java | 2 +- .../server/common/data/id/NotificationId.java | 2 +- .../common/data/id/NotificationRequestId.java | 2 +- .../common/data/id/NotificationRuleId.java | 2 +- .../common/data/id/NotificationTargetId.java | 2 +- .../common/data/id/NotificationTemplateId.java | 2 +- .../id/OAuth2ClientRegistrationTemplateId.java | 2 +- .../server/common/data/id/OAuth2DomainId.java | 2 +- .../server/common/data/id/OAuth2MobileId.java | 2 +- .../server/common/data/id/OAuth2ParamsId.java | 2 +- .../common/data/id/OAuth2RegistrationId.java | 2 +- .../server/common/data/id/OtaPackageId.java | 2 +- .../server/common/data/id/QueueId.java | 2 +- .../thingsboard/server/common/data/id/RpcId.java | 2 +- .../server/common/data/id/RuleChainId.java | 2 +- .../server/common/data/id/RuleNodeId.java | 2 +- .../server/common/data/id/RuleNodeStateId.java | 2 +- .../server/common/data/id/TbResourceId.java | 2 +- .../server/common/data/id/TenantId.java | 2 +- .../server/common/data/id/TenantProfileId.java | 2 +- .../server/common/data/id/UUIDBased.java | 2 +- .../common/data/id/UserAuthSettingsId.java | 2 +- .../server/common/data/id/UserCredentialsId.java | 2 +- .../server/common/data/id/UserId.java | 2 +- .../server/common/data/id/WidgetTypeId.java | 2 +- .../server/common/data/id/WidgetsBundleId.java | 2 +- .../server/common/data/kv/AggTsKvEntry.java | 2 +- .../server/common/data/kv/Aggregation.java | 2 +- .../server/common/data/kv/AttributeKey.java | 2 +- .../server/common/data/kv/AttributeKvEntry.java | 2 +- .../common/data/kv/BaseAttributeKvEntry.java | 2 +- .../common/data/kv/BaseDeleteTsKvQuery.java | 2 +- .../server/common/data/kv/BaseReadTsKvQuery.java | 2 +- .../server/common/data/kv/BaseTsKvQuery.java | 2 +- .../server/common/data/kv/BasicKvEntry.java | 2 +- .../server/common/data/kv/BasicTsKvEntry.java | 2 +- .../server/common/data/kv/BooleanDataEntry.java | 2 +- .../server/common/data/kv/DataType.java | 2 +- .../server/common/data/kv/DeleteTsKvQuery.java | 2 +- .../server/common/data/kv/DoubleDataEntry.java | 2 +- .../server/common/data/kv/JsonDataEntry.java | 2 +- .../server/common/data/kv/KvEntry.java | 2 +- .../server/common/data/kv/LongDataEntry.java | 2 +- .../server/common/data/kv/ReadTsKvQuery.java | 2 +- .../common/data/kv/ReadTsKvQueryResult.java | 2 +- .../server/common/data/kv/StringDataEntry.java | 2 +- .../server/common/data/kv/TsKvEntry.java | 2 +- .../common/data/kv/TsKvEntryAggWrapper.java | 2 +- .../common/data/kv/TsKvLatestRemovingResult.java | 2 +- .../server/common/data/kv/TsKvQuery.java | 2 +- .../server/common/data/limit/LimitedApi.java | 2 +- .../server/common/data/lwm2m/LwM2mConstants.java | 2 +- .../server/common/data/lwm2m/LwM2mInstance.java | 2 +- .../server/common/data/lwm2m/LwM2mObject.java | 2 +- .../common/data/lwm2m/LwM2mResourceObserve.java | 2 +- .../common/data/mail/MailOauth2Provider.java | 2 +- .../server/common/data/msg/TbMsgType.java | 2 +- .../common/data/msg/TbNodeConnectionType.java | 2 +- .../data/notification/AlreadySentException.java | 2 +- .../common/data/notification/Notification.java | 2 +- .../notification/NotificationDeliveryMethod.java | 2 +- .../data/notification/NotificationRequest.java | 2 +- .../notification/NotificationRequestConfig.java | 2 +- .../notification/NotificationRequestInfo.java | 2 +- .../notification/NotificationRequestPreview.java | 2 +- .../notification/NotificationRequestStats.java | 2 +- .../notification/NotificationRequestStatus.java | 2 +- .../data/notification/NotificationStatus.java | 2 +- .../data/notification/NotificationType.java | 2 +- .../info/AlarmAssignmentNotificationInfo.java | 2 +- .../info/AlarmCommentNotificationInfo.java | 2 +- .../notification/info/AlarmNotificationInfo.java | 2 +- .../info/ApiUsageLimitNotificationInfo.java | 2 +- .../info/DeviceActivityNotificationInfo.java | 2 +- .../info/EntitiesLimitNotificationInfo.java | 2 +- .../info/EntityActionNotificationInfo.java | 2 +- .../info/NewPlatformVersionNotificationInfo.java | 2 +- .../data/notification/info/NotificationInfo.java | 2 +- .../info/RateLimitsNotificationInfo.java | 2 +- ...eComponentLifecycleEventNotificationInfo.java | 2 +- .../RuleEngineOriginatedNotificationInfo.java | 2 +- .../info/RuleOriginatedNotificationInfo.java | 2 +- .../DefaultNotificationRuleRecipientsConfig.java | 2 +- ...scalatedNotificationRuleRecipientsConfig.java | 2 +- .../data/notification/rule/NotificationRule.java | 2 +- .../rule/NotificationRuleConfig.java | 2 +- .../notification/rule/NotificationRuleInfo.java | 2 +- .../rule/NotificationRuleRecipientsConfig.java | 2 +- .../rule/trigger/AlarmAssignmentTrigger.java | 2 +- .../rule/trigger/AlarmCommentTrigger.java | 2 +- .../notification/rule/trigger/AlarmTrigger.java | 2 +- .../rule/trigger/ApiUsageLimitTrigger.java | 2 +- .../rule/trigger/DeviceActivityTrigger.java | 2 +- .../rule/trigger/EntitiesLimitTrigger.java | 2 +- .../rule/trigger/EntityActionTrigger.java | 2 +- .../rule/trigger/NewPlatformVersionTrigger.java | 2 +- .../rule/trigger/NotificationRuleTrigger.java | 2 +- .../rule/trigger/RateLimitsTrigger.java | 2 +- ...RuleEngineComponentLifecycleEventTrigger.java | 2 +- ...mAssignmentNotificationRuleTriggerConfig.java | 2 +- ...larmCommentNotificationRuleTriggerConfig.java | 2 +- .../AlarmNotificationRuleTriggerConfig.java | 2 +- ...iUsageLimitNotificationRuleTriggerConfig.java | 2 +- ...iceActivityNotificationRuleTriggerConfig.java | 2 +- ...titiesLimitNotificationRuleTriggerConfig.java | 2 +- ...ntityActionNotificationRuleTriggerConfig.java | 2 +- ...formVersionNotificationRuleTriggerConfig.java | 2 +- .../config/NotificationRuleTriggerConfig.java | 2 +- .../config/NotificationRuleTriggerType.java | 2 +- .../RateLimitsNotificationRuleTriggerConfig.java | 2 +- ...ecycleEventNotificationRuleTriggerConfig.java | 2 +- .../settings/AccountNotificationSettings.java | 2 +- .../NotificationDeliveryMethodConfig.java | 2 +- .../settings/NotificationSettings.java | 2 +- .../SlackNotificationDeliveryMethodConfig.java | 2 +- .../settings/UserNotificationSettings.java | 2 +- .../MicrosoftTeamsNotificationTargetConfig.java | 2 +- .../targets/NotificationRecipient.java | 2 +- .../notification/targets/NotificationTarget.java | 2 +- .../targets/NotificationTargetConfig.java | 2 +- .../targets/NotificationTargetType.java | 2 +- .../AffectedTenantAdministratorsFilter.java | 2 +- .../targets/platform/AffectedUserFilter.java | 2 +- .../targets/platform/AllUsersFilter.java | 2 +- .../targets/platform/CustomerUsersFilter.java | 2 +- .../OriginatorEntityOwnerUsersFilter.java | 2 +- .../PlatformUsersNotificationTargetConfig.java | 2 +- .../platform/SystemAdministratorsFilter.java | 2 +- .../platform/TenantAdministratorsFilter.java | 2 +- .../targets/platform/UserListFilter.java | 2 +- .../targets/platform/UsersFilter.java | 2 +- .../targets/platform/UsersFilterType.java | 2 +- .../targets/slack/SlackConversation.java | 2 +- .../targets/slack/SlackConversationType.java | 2 +- .../slack/SlackNotificationTargetConfig.java | 2 +- .../DeliveryMethodNotificationTemplate.java | 2 +- .../EmailDeliveryMethodNotificationTemplate.java | 2 +- .../data/notification/template/HasSubject.java | 2 +- ...tTeamsDeliveryMethodNotificationTemplate.java | 2 +- .../template/NotificationTemplate.java | 2 +- .../template/NotificationTemplateConfig.java | 2 +- .../SlackDeliveryMethodNotificationTemplate.java | 2 +- .../SmsDeliveryMethodNotificationTemplate.java | 2 +- .../notification/template/TemplatableValue.java | 2 +- .../WebDeliveryMethodNotificationTemplate.java | 2 +- .../server/common/data/oauth2/MapperType.java | 2 +- .../data/oauth2/OAuth2BasicMapperConfig.java | 2 +- .../common/data/oauth2/OAuth2ClientInfo.java | 2 +- .../oauth2/OAuth2ClientRegistrationTemplate.java | 2 +- .../data/oauth2/OAuth2CustomMapperConfig.java | 2 +- .../server/common/data/oauth2/OAuth2Domain.java | 2 +- .../common/data/oauth2/OAuth2DomainInfo.java | 2 +- .../server/common/data/oauth2/OAuth2Info.java | 2 +- .../common/data/oauth2/OAuth2MapperConfig.java | 2 +- .../server/common/data/oauth2/OAuth2Mobile.java | 2 +- .../common/data/oauth2/OAuth2MobileInfo.java | 2 +- .../server/common/data/oauth2/OAuth2Params.java | 2 +- .../common/data/oauth2/OAuth2ParamsInfo.java | 2 +- .../common/data/oauth2/OAuth2Registration.java | 2 +- .../data/oauth2/OAuth2RegistrationInfo.java | 2 +- .../server/common/data/oauth2/PlatformType.java | 2 +- .../server/common/data/oauth2/SchemeType.java | 2 +- .../data/oauth2/TenantNameStrategyType.java | 2 +- .../data/objects/AttributesEntityView.java | 2 +- .../common/data/objects/TelemetryEntityView.java | 2 +- .../common/data/ota/ChecksumAlgorithm.java | 2 +- .../server/common/data/ota/OtaPackageKey.java | 2 +- .../server/common/data/ota/OtaPackageType.java | 2 +- .../common/data/ota/OtaPackageUpdateStatus.java | 2 +- .../server/common/data/ota/OtaPackageUtil.java | 2 +- .../common/data/page/BasePageDataIterable.java | 2 +- .../server/common/data/page/PageData.java | 2 +- .../common/data/page/PageDataIterable.java | 2 +- .../data/page/PageDataIterableByTenant.java | 2 +- .../page/PageDataIterableByTenantIdEntityId.java | 2 +- .../server/common/data/page/PageLink.java | 2 +- .../server/common/data/page/SortOrder.java | 2 +- .../server/common/data/page/TimePageLink.java | 2 +- .../data/plugin/ComponentClusteringMode.java | 2 +- .../common/data/plugin/ComponentDescriptor.java | 2 +- .../data/plugin/ComponentLifecycleEvent.java | 2 +- .../data/plugin/ComponentLifecycleState.java | 2 +- .../common/data/plugin/ComponentScope.java | 2 +- .../server/common/data/plugin/ComponentType.java | 2 +- .../common/data/query/AbstractDataQuery.java | 2 +- .../common/data/query/AlarmCountQuery.java | 2 +- .../server/common/data/query/AlarmData.java | 2 +- .../common/data/query/AlarmDataPageLink.java | 2 +- .../server/common/data/query/AlarmDataQuery.java | 2 +- .../common/data/query/ApiUsageStateFilter.java | 2 +- .../data/query/AssetSearchQueryFilter.java | 2 +- .../common/data/query/AssetTypeFilter.java | 2 +- .../data/query/BooleanFilterPredicate.java | 2 +- .../common/data/query/ComparisonTsValue.java | 2 +- .../data/query/ComplexFilterPredicate.java | 2 +- .../data/query/DeviceSearchQueryFilter.java | 2 +- .../common/data/query/DeviceTypeFilter.java | 2 +- .../server/common/data/query/DynamicValue.java | 2 +- .../data/query/DynamicValueSourceType.java | 2 +- .../common/data/query/EdgeSearchQueryFilter.java | 2 +- .../server/common/data/query/EdgeTypeFilter.java | 2 +- .../common/data/query/EntityCountQuery.java | 2 +- .../server/common/data/query/EntityData.java | 2 +- .../common/data/query/EntityDataPageLink.java | 2 +- .../common/data/query/EntityDataQuery.java | 2 +- .../common/data/query/EntityDataSortOrder.java | 2 +- .../server/common/data/query/EntityFilter.java | 2 +- .../common/data/query/EntityFilterType.java | 2 +- .../server/common/data/query/EntityKey.java | 2 +- .../server/common/data/query/EntityKeyType.java | 2 +- .../common/data/query/EntityKeyValueType.java | 2 +- .../common/data/query/EntityListFilter.java | 2 +- .../common/data/query/EntityNameFilter.java | 2 +- .../data/query/EntitySearchQueryFilter.java | 2 +- .../common/data/query/EntityTypeFilter.java | 2 +- .../data/query/EntityViewSearchQueryFilter.java | 2 +- .../common/data/query/EntityViewTypeFilter.java | 2 +- .../common/data/query/FilterPredicateType.java | 2 +- .../common/data/query/FilterPredicateValue.java | 2 +- .../server/common/data/query/KeyFilter.java | 2 +- .../common/data/query/KeyFilterPredicate.java | 2 +- .../data/query/NumericFilterPredicate.java | 2 +- .../common/data/query/RelationsQueryFilter.java | 2 +- .../data/query/SimpleKeyFilterPredicate.java | 2 +- .../common/data/query/SingleEntityFilter.java | 2 +- .../common/data/query/StringFilterPredicate.java | 2 +- .../server/common/data/query/TsValue.java | 2 +- .../common/data/queue/ProcessingStrategy.java | 2 +- .../data/queue/ProcessingStrategyType.java | 2 +- .../server/common/data/queue/Queue.java | 2 +- .../server/common/data/queue/SubmitStrategy.java | 2 +- .../common/data/queue/SubmitStrategyType.java | 2 +- .../common/data/relation/EntityRelation.java | 2 +- .../common/data/relation/EntityRelationInfo.java | 2 +- .../data/relation/EntityRelationsQuery.java | 2 +- .../data/relation/EntitySearchDirection.java | 2 +- .../data/relation/RelationEntityTypeFilter.java | 2 +- .../common/data/relation/RelationTypeGroup.java | 2 +- .../data/relation/RelationsSearchParameters.java | 2 +- .../thingsboard/server/common/data/rpc/Rpc.java | 2 +- .../server/common/data/rpc/RpcError.java | 2 +- .../server/common/data/rpc/RpcStatus.java | 2 +- .../common/data/rpc/ToDeviceRpcRequestBody.java | 2 +- .../data/rule/DefaultRuleChainCreateRequest.java | 2 +- .../common/data/rule/NodeConnectionInfo.java | 2 +- .../server/common/data/rule/RuleChain.java | 2 +- .../data/rule/RuleChainConnectionInfo.java | 2 +- .../server/common/data/rule/RuleChainData.java | 2 +- .../common/data/rule/RuleChainImportResult.java | 2 +- .../common/data/rule/RuleChainMetaData.java | 2 +- .../data/rule/RuleChainOutputLabelsUsage.java | 2 +- .../server/common/data/rule/RuleChainType.java | 2 +- .../common/data/rule/RuleChainUpdateResult.java | 2 +- .../server/common/data/rule/RuleNode.java | 2 +- .../server/common/data/rule/RuleNodeState.java | 2 +- .../common/data/rule/RuleNodeUpdateResult.java | 2 +- .../server/common/data/rule/RuleType.java | 2 +- .../server/common/data/rule/Scope.java | 2 +- .../common/data/script/ScriptLanguage.java | 2 +- .../server/common/data/security/Authority.java | 2 +- .../common/data/security/DeviceCredentials.java | 2 +- .../data/security/DeviceCredentialsFilter.java | 2 +- .../data/security/DeviceCredentialsType.java | 2 +- .../data/security/DeviceTokenCredentials.java | 2 +- .../data/security/DeviceX509Credentials.java | 2 +- .../common/data/security/UserAuthSettings.java | 2 +- .../common/data/security/UserCredentials.java | 2 +- .../security/event/UserAuthDataChangedEvent.java | 2 +- .../event/UserCredentialsInvalidationEvent.java | 2 +- .../event/UserSessionInvalidationEvent.java | 2 +- .../common/data/security/model/JwtPair.java | 2 +- .../common/data/security/model/JwtSettings.java | 2 +- .../common/data/security/model/JwtToken.java | 2 +- .../data/security/model/SecuritySettings.java | 2 +- .../data/security/model/UserPasswordPolicy.java | 2 +- .../model/mfa/PlatformTwoFaSettings.java | 2 +- .../model/mfa/account/AccountTwoFaSettings.java | 2 +- .../account/BackupCodeTwoFaAccountConfig.java | 2 +- .../mfa/account/EmailTwoFaAccountConfig.java | 2 +- .../mfa/account/OtpBasedTwoFaAccountConfig.java | 2 +- .../model/mfa/account/SmsTwoFaAccountConfig.java | 2 +- .../mfa/account/TotpTwoFaAccountConfig.java | 2 +- .../model/mfa/account/TwoFaAccountConfig.java | 2 +- .../provider/BackupCodeTwoFaProviderConfig.java | 2 +- .../mfa/provider/EmailTwoFaProviderConfig.java | 2 +- .../provider/OtpBasedTwoFaProviderConfig.java | 2 +- .../mfa/provider/SmsTwoFaProviderConfig.java | 2 +- .../mfa/provider/TotpTwoFaProviderConfig.java | 2 +- .../model/mfa/provider/TwoFaProviderConfig.java | 2 +- .../model/mfa/provider/TwoFaProviderType.java | 2 +- .../data/settings/AbstractUserDashboardInfo.java | 2 +- .../data/settings/LastVisitedDashboardInfo.java | 2 +- .../data/settings/StarredDashboardInfo.java | 2 +- .../data/settings/UserDashboardAction.java | 2 +- .../common/data/settings/UserDashboardsInfo.java | 2 +- .../common/data/settings/UserSettings.java | 2 +- .../data/settings/UserSettingsCompositeKey.java | 2 +- .../common/data/settings/UserSettingsType.java | 2 +- .../config/AwsSnsSmsProviderConfiguration.java | 2 +- .../sms/config/SmppSmsProviderConfiguration.java | 2 +- .../sms/config/SmsProviderConfiguration.java | 2 +- .../common/data/sms/config/SmsProviderType.java | 2 +- .../common/data/sms/config/TestSmsRequest.java | 2 +- .../config/TwilioSmsProviderConfiguration.java | 2 +- .../server/common/data/sync/JsonTbEntity.java | 2 +- .../common/data/sync/ie/AttributeExportData.java | 2 +- .../common/data/sync/ie/DeviceExportData.java | 2 +- .../common/data/sync/ie/EntityExportData.java | 2 +- .../data/sync/ie/EntityExportSettings.java | 2 +- .../common/data/sync/ie/EntityImportResult.java | 2 +- .../data/sync/ie/EntityImportSettings.java | 2 +- .../common/data/sync/ie/RuleChainExportData.java | 2 +- .../data/sync/ie/WidgetTypeExportData.java | 2 +- .../data/sync/ie/WidgetsBundleExportData.java | 2 +- .../ie/importing/csv/BulkImportColumnType.java | 2 +- .../sync/ie/importing/csv/BulkImportRequest.java | 2 +- .../sync/ie/importing/csv/BulkImportResult.java | 2 +- .../common/data/sync/vc/AutoCommitSettings.java | 2 +- .../server/common/data/sync/vc/BranchInfo.java | 2 +- .../common/data/sync/vc/EntityDataDiff.java | 2 +- .../common/data/sync/vc/EntityDataInfo.java | 2 +- .../common/data/sync/vc/EntityLoadError.java | 2 +- .../data/sync/vc/EntityTypeLoadResult.java | 2 +- .../common/data/sync/vc/EntityVersion.java | 2 +- .../common/data/sync/vc/EntityVersionsDiff.java | 2 +- .../data/sync/vc/RepositoryAuthMethod.java | 2 +- .../common/data/sync/vc/RepositorySettings.java | 2 +- .../data/sync/vc/RepositorySettingsInfo.java | 2 +- .../server/common/data/sync/vc/VcUtils.java | 2 +- .../data/sync/vc/VersionCreationResult.java | 2 +- .../common/data/sync/vc/VersionLoadResult.java | 2 +- .../common/data/sync/vc/VersionedEntityInfo.java | 2 +- .../request/create/AutoVersionCreateConfig.java | 2 +- .../create/ComplexVersionCreateRequest.java | 2 +- .../create/EntityTypeVersionCreateConfig.java | 2 +- .../create/SingleEntityVersionCreateRequest.java | 2 +- .../sync/vc/request/create/SyncStrategy.java | 2 +- .../vc/request/create/VersionCreateConfig.java | 2 +- .../vc/request/create/VersionCreateRequest.java | 2 +- .../request/create/VersionCreateRequestType.java | 2 +- .../load/EntityTypeVersionLoadConfig.java | 2 +- .../load/EntityTypeVersionLoadRequest.java | 2 +- .../load/SingleEntityVersionLoadRequest.java | 2 +- .../sync/vc/request/load/VersionLoadConfig.java | 2 +- .../sync/vc/request/load/VersionLoadRequest.java | 2 +- .../vc/request/load/VersionLoadRequestType.java | 2 +- .../DefaultTenantProfileConfiguration.java | 2 +- .../profile/TenantProfileConfiguration.java | 2 +- .../data/tenant/profile/TenantProfileData.java | 2 +- .../profile/TenantProfileQueueConfiguration.java | 2 +- .../data/transport/resource/ResourceType.java | 2 +- .../transport/snmp/AuthenticationProtocol.java | 2 +- .../data/transport/snmp/PrivacyProtocol.java | 2 +- .../transport/snmp/SnmpCommunicationSpec.java | 2 +- .../common/data/transport/snmp/SnmpMapping.java | 2 +- .../common/data/transport/snmp/SnmpMethod.java | 2 +- .../data/transport/snmp/SnmpProtocolVersion.java | 2 +- .../MultipleMappingsSnmpCommunicationConfig.java | 2 +- ...RepeatingQueryingSnmpCommunicationConfig.java | 2 +- .../snmp/config/SnmpCommunicationConfig.java | 2 +- ...oServerRpcRequestSnmpCommunicationConfig.java | 2 +- ...ttributesQueryingSnmpCommunicationConfig.java | 2 +- ...AttributesSettingSnmpCommunicationConfig.java | 2 +- ...TelemetryQueryingSnmpCommunicationConfig.java | 2 +- ...oDeviceRpcRequestSnmpCommunicationConfig.java | 2 +- .../server/common/data/util/CollectionsUtil.java | 2 +- .../server/common/data/util/ReflectionUtils.java | 2 +- .../server/common/data/util/TbDDFFileParser.java | 2 +- .../server/common/data/util/TbPair.java | 2 +- .../server/common/data/util/TemplateUtils.java | 2 +- .../common/data/util/ThrowingBiFunction.java | 2 +- .../common/data/util/ThrowingRunnable.java | 2 +- .../common/data/util/ThrowingSupplier.java | 2 +- .../server/common/data/util/TypeCastUtil.java | 2 +- .../server/common/data/validation/Length.java | 2 +- .../server/common/data/validation/NoXss.java | 2 +- .../common/data/widget/BaseWidgetType.java | 2 +- .../common/data/widget/DeprecatedFilter.java | 2 +- .../server/common/data/widget/WidgetType.java | 2 +- .../common/data/widget/WidgetTypeDetails.java | 2 +- .../common/data/widget/WidgetTypeInfo.java | 2 +- .../server/common/data/widget/WidgetsBundle.java | 2 +- .../common/data/widget/WidgetsBundleWidget.java | 2 +- .../common/data/DynamicProtoUtilsTest.java | 2 +- .../server/common/data/EntityTypeTest.java | 2 +- .../server/common/data/StringUtilsTest.java | 2 +- .../server/common/data/UUIDConverterTest.java | 2 +- .../server/common/data/audit/ActionTypeTest.java | 2 +- .../server/common/data/id/EntityIdTest.java | 2 +- .../server/common/data/msg/TbMsgTypeTest.java | 2 +- .../server/common/data/rpc/RpcStatusTest.java | 2 +- common/edge-api/pom.xml | 2 +- .../edge/exception/EdgeConnectionException.java | 2 +- .../org/thingsboard/edge/rpc/EdgeGrpcClient.java | 2 +- .../org/thingsboard/edge/rpc/EdgeRpcClient.java | 2 +- common/edge-api/src/main/proto/edge.proto | 2 +- common/message/pom.xml | 2 +- .../server/common/msg/EncryptionUtil.java | 2 +- .../thingsboard/server/common/msg/MsgType.java | 2 +- .../server/common/msg/TbActorError.java | 2 +- .../server/common/msg/TbActorMsg.java | 2 +- .../server/common/msg/TbActorStopReason.java | 2 +- .../org/thingsboard/server/common/msg/TbMsg.java | 2 +- .../server/common/msg/TbMsgDataType.java | 2 +- .../server/common/msg/TbMsgMetaData.java | 2 +- .../server/common/msg/TbMsgProcessingCtx.java | 2 +- .../common/msg/TbMsgProcessingStackItem.java | 2 +- .../server/common/msg/TbRuleEngineActorMsg.java | 2 +- .../common/msg/ToDeviceActorNotificationMsg.java | 2 +- .../common/msg/aware/CustomerAwareMsg.java | 2 +- .../server/common/msg/aware/DeviceAwareMsg.java | 2 +- .../server/common/msg/aware/NodeAwareMsg.java | 2 +- .../common/msg/aware/RuleChainAwareMsg.java | 2 +- .../server/common/msg/aware/TenantAwareMsg.java | 2 +- .../server/common/msg/cluster/ToAllNodesMsg.java | 2 +- .../common/msg/edge/EdgeEventUpdateMsg.java | 2 +- .../server/common/msg/edge/EdgeSessionMsg.java | 2 +- .../common/msg/edge/FromEdgeSyncResponse.java | 2 +- .../common/msg/edge/ToEdgeSyncRequest.java | 2 +- .../notification/NotificationRuleProcessor.java | 2 +- .../msg/plugin/ComponentLifecycleListener.java | 2 +- .../common/msg/plugin/ComponentLifecycleMsg.java | 2 +- .../common/msg/plugin/RuleNodeUpdatedMsg.java | 2 +- .../common/msg/queue/PartitionChangeMsg.java | 2 +- .../common/msg/queue/QueueToRuleEngineMsg.java | 2 +- .../common/msg/queue/RuleEngineException.java | 2 +- .../common/msg/queue/RuleNodeException.java | 2 +- .../server/common/msg/queue/RuleNodeInfo.java | 2 +- .../server/common/msg/queue/ServiceType.java | 2 +- .../server/common/msg/queue/TbCallback.java | 2 +- .../server/common/msg/queue/TbMsgCallback.java | 2 +- .../common/msg/queue/TopicPartitionInfo.java | 2 +- .../common/msg/rpc/FromDeviceRpcResponse.java | 2 +- .../msg/rpc/FromDeviceRpcResponseActorMsg.java | 2 +- .../server/common/msg/rpc/RemoveRpcActorMsg.java | 2 +- .../common/msg/rpc/ToDeviceRpcRequest.java | 2 +- .../msg/rpc/ToDeviceRpcRequestActorMsg.java | 2 +- .../common/msg/rule/engine/DeviceAttributes.java | 2 +- .../DeviceAttributesEventNotificationMsg.java | 2 +- .../DeviceCredentialsUpdateNotificationMsg.java | 2 +- .../common/msg/rule/engine/DeviceDeleteMsg.java | 2 +- .../msg/rule/engine/DeviceEdgeUpdateMsg.java | 2 +- .../common/msg/rule/engine/DeviceMetaData.java | 2 +- .../rule/engine/DeviceNameOrTypeUpdateMsg.java | 2 +- .../server/common/msg/session/FeatureType.java | 2 +- .../common/msg/session/SessionMsgType.java | 2 +- .../session/ex/ProcessingTimeoutException.java | 2 +- .../msg/session/ex/SessionAuthException.java | 2 +- .../common/msg/session/ex/SessionException.java | 2 +- .../DeviceActorServerSideRpcTimeoutMsg.java | 2 +- .../server/common/msg/timeout/TimeoutMsg.java | 2 +- .../server/common/msg/tools/SchedulerUtils.java | 2 +- .../server/common/msg/tools/TbRateLimits.java | 2 +- .../common/msg/tools/TbRateLimitsException.java | 2 +- common/message/src/main/proto/tbmsg.proto | 2 +- .../server/common/msg/TbMsgMetaDataTest.java | 2 +- .../common/msg/TbMsgProcessingStackItemTest.java | 2 +- .../common/msg/queue/TopicPartitionInfoTest.java | 2 +- .../server/common/msg/tools/RateLimitsTest.java | 2 +- common/pom.xml | 2 +- common/proto/pom.xml | 2 +- .../server/common/adaptor/AdaptorException.java | 2 +- .../server/common/adaptor/JsonConverter.java | 2 +- .../common/adaptor/JsonConverterConfig.java | 2 +- .../server/common/adaptor/ProtoConverter.java | 2 +- .../server/common/util/ProtoUtils.java | 2 +- common/proto/src/main/proto/jsinvoke.proto | 2 +- common/proto/src/main/proto/queue.proto | 2 +- common/proto/src/main/proto/transport.proto | 2 +- .../server/common/adaptor/JsonConverterTest.java | 2 +- .../server/common/util/ProtoUtilsTest.java | 2 +- common/queue/pom.xml | 2 +- .../queue/RuleEngineTbQueueAdminFactory.java | 2 +- .../azure/servicebus/TbServiceBusAdmin.java | 2 +- .../servicebus/TbServiceBusConsumerTemplate.java | 2 +- .../servicebus/TbServiceBusProducerTemplate.java | 2 +- .../servicebus/TbServiceBusQueueConfigs.java | 2 +- .../azure/servicebus/TbServiceBusSettings.java | 2 +- .../AbstractParallelTbQueueConsumerTemplate.java | 2 +- .../common/AbstractTbQueueConsumerTemplate.java | 2 +- .../queue/common/AbstractTbQueueTemplate.java | 2 +- .../queue/common/AsyncCallbackTemplate.java | 2 +- .../server/queue/common/DefaultTbQueueMsg.java | 2 +- .../queue/common/DefaultTbQueueMsgHeaders.java | 2 +- .../common/DefaultTbQueueRequestTemplate.java | 2 +- .../common/DefaultTbQueueResponseTemplate.java | 2 +- .../common/MultipleTbQueueCallbackWrapper.java | 2 +- .../MultipleTbQueueTbMsgCallbackWrapper.java | 2 +- .../server/queue/common/TbProtoJsQueueMsg.java | 2 +- .../server/queue/common/TbProtoQueueMsg.java | 2 +- .../common/TbQueueTbMsgCallbackWrapper.java | 2 +- .../queue/discovery/ConsistentHashCircle.java | 2 +- .../discovery/DefaultTbServiceInfoProvider.java | 2 +- .../server/queue/discovery/DiscoveryService.java | 2 +- .../queue/discovery/DummyDiscoveryService.java | 2 +- .../queue/discovery/HashPartitionService.java | 2 +- .../server/queue/discovery/PartitionService.java | 2 +- .../server/queue/discovery/QueueKey.java | 2 +- .../server/queue/discovery/QueueRoutingInfo.java | 2 +- .../queue/discovery/QueueRoutingInfoService.java | 2 +- .../discovery/TbApplicationEventListener.java | 2 +- .../queue/discovery/TbServiceInfoProvider.java | 2 +- .../queue/discovery/TenantRoutingInfo.java | 2 +- .../discovery/TenantRoutingInfoService.java | 2 +- .../server/queue/discovery/TopicService.java | 2 +- .../queue/discovery/ZkDiscoveryService.java | 2 +- .../event/ClusterTopologyChangeEvent.java | 2 +- .../event/OtherServiceShutdownEvent.java | 2 +- .../discovery/event/PartitionChangeEvent.java | 2 +- .../discovery/event/ServiceListChangedEvent.java | 2 +- .../discovery/event/TbApplicationEvent.java | 2 +- .../queue/environment/EnvironmentLogService.java | 2 +- .../server/queue/kafka/KafkaTbQueueMsg.java | 2 +- .../queue/kafka/KafkaTbQueueMsgMetadata.java | 2 +- .../server/queue/kafka/TbKafkaAdmin.java | 2 +- .../kafka/TbKafkaConsumerStatisticConfig.java | 2 +- .../queue/kafka/TbKafkaConsumerStatsService.java | 2 +- .../queue/kafka/TbKafkaConsumerTemplate.java | 2 +- .../server/queue/kafka/TbKafkaDecoder.java | 2 +- .../server/queue/kafka/TbKafkaEncoder.java | 2 +- .../queue/kafka/TbKafkaProducerTemplate.java | 2 +- .../server/queue/kafka/TbKafkaSettings.java | 2 +- .../server/queue/kafka/TbKafkaTopicConfigs.java | 2 +- .../queue/memory/DefaultInMemoryStorage.java | 2 +- .../server/queue/memory/InMemoryStorage.java | 2 +- .../queue/memory/InMemoryTbQueueConsumer.java | 2 +- .../queue/memory/InMemoryTbQueueProducer.java | 2 +- .../DefaultNotificationDeduplicationService.java | 2 +- .../NotificationDeduplicationService.java | 2 +- .../RemoteNotificationRuleProcessor.java | 2 +- .../provider/AwsSqsMonolithQueueFactory.java | 2 +- .../queue/provider/AwsSqsTbCoreQueueFactory.java | 2 +- .../provider/AwsSqsTbRuleEngineQueueFactory.java | 2 +- .../AwsSqsTbVersionControlQueueFactory.java | 2 +- .../provider/AwsSqsTransportQueueFactory.java | 2 +- .../provider/InMemoryMonolithQueueFactory.java | 2 +- .../InMemoryTbTransportQueueFactory.java | 2 +- .../provider/KafkaMonolithQueueFactory.java | 2 +- .../queue/provider/KafkaTbCoreQueueFactory.java | 2 +- .../provider/KafkaTbRuleEngineQueueFactory.java | 2 +- .../provider/KafkaTbTransportQueueFactory.java | 2 +- .../KafkaTbVersionControlQueueFactory.java | 2 +- .../provider/PubSubMonolithQueueFactory.java | 2 +- .../queue/provider/PubSubTbCoreQueueFactory.java | 2 +- .../provider/PubSubTbRuleEngineQueueFactory.java | 2 +- .../PubSubTbVersionControlQueueFactory.java | 2 +- .../provider/PubSubTransportQueueFactory.java | 2 +- .../provider/RabbitMqMonolithQueueFactory.java | 2 +- .../provider/RabbitMqTbCoreQueueFactory.java | 2 +- .../RabbitMqTbRuleEngineQueueFactory.java | 2 +- .../RabbitMqTbVersionControlQueueFactory.java | 2 +- .../provider/RabbitMqTransportQueueFactory.java | 2 +- .../provider/ServiceBusMonolithQueueFactory.java | 2 +- .../provider/ServiceBusTbCoreQueueFactory.java | 2 +- .../ServiceBusTbRuleEngineQueueFactory.java | 2 +- .../ServiceBusTbVersionControlQueueFactory.java | 2 +- .../ServiceBusTransportQueueFactory.java | 2 +- .../queue/provider/TbCoreQueueFactory.java | 2 +- .../provider/TbCoreQueueProducerProvider.java | 2 +- .../queue/provider/TbQueueProducerProvider.java | 2 +- .../provider/TbRuleEngineProducerProvider.java | 2 +- .../queue/provider/TbRuleEngineQueueFactory.java | 2 +- .../queue/provider/TbTransportQueueFactory.java | 2 +- .../TbTransportQueueProducerProvider.java | 2 +- .../provider/TbUsageStatsClientQueueFactory.java | 2 +- .../TbVersionControlProducerProvider.java | 2 +- .../provider/TbVersionControlQueueFactory.java | 2 +- .../server/queue/pubsub/TbPubSubAdmin.java | 2 +- .../queue/pubsub/TbPubSubConsumerTemplate.java | 2 +- .../queue/pubsub/TbPubSubProducerTemplate.java | 2 +- .../server/queue/pubsub/TbPubSubSettings.java | 2 +- .../pubsub/TbPubSubSubscriptionSettings.java | 2 +- .../server/queue/rabbitmq/TbRabbitMqAdmin.java | 2 +- .../rabbitmq/TbRabbitMqConsumerTemplate.java | 2 +- .../rabbitmq/TbRabbitMqProducerTemplate.java | 2 +- .../queue/rabbitmq/TbRabbitMqQueueArguments.java | 2 +- .../queue/rabbitmq/TbRabbitMqSettings.java | 2 +- .../scheduler/DefaultSchedulerComponent.java | 2 +- .../queue/scheduler/SchedulerComponent.java | 2 +- .../queue/settings/TbQueueCoreSettings.java | 2 +- .../settings/TbQueueRemoteJsInvokeSettings.java | 2 +- .../settings/TbQueueRuleEngineSettings.java | 2 +- .../settings/TbQueueTransportApiSettings.java | 2 +- .../TbQueueTransportNotificationSettings.java | 2 +- .../settings/TbQueueVersionControlSettings.java | 2 +- ...bRuleEngineQueueAckStrategyConfiguration.java | 2 +- .../settings/TbRuleEngineQueueConfiguration.java | 2 +- ...leEngineQueueSubmitStrategyConfiguration.java | 2 +- .../queue/sqs/AwsSqsTbQueueMsgMetadata.java | 2 +- .../server/queue/sqs/TbAwsSqsAdmin.java | 2 +- .../queue/sqs/TbAwsSqsConsumerTemplate.java | 2 +- .../queue/sqs/TbAwsSqsProducerTemplate.java | 2 +- .../queue/sqs/TbAwsSqsQueueAttributes.java | 2 +- .../server/queue/sqs/TbAwsSqsSettings.java | 2 +- .../DefaultTbApiUsageReportClient.java | 2 +- .../server/queue/util/AfterContextReady.java | 2 +- .../server/queue/util/AfterStartUp.java | 2 +- .../queue/util/DataDecodingEncodingService.java | 2 +- .../server/queue/util/PropertyUtils.java | 2 +- .../server/queue/util/ProtoWithFSTService.java | 2 +- .../server/queue/util/TbCoreComponent.java | 2 +- .../util/TbLwM2mBootstrapTransportComponent.java | 2 +- .../queue/util/TbLwM2mTransportComponent.java | 2 +- .../server/queue/util/TbRuleEngineComponent.java | 2 +- .../queue/util/TbSnmpTransportComponent.java | 2 +- .../server/queue/util/TbTransportComponent.java | 2 +- .../queue/util/TbVersionControlComponent.java | 2 +- .../DefaultTbQueueRequestTemplateTest.java | 2 +- .../server/queue/discovery/QueueKeyTest.java | 2 +- .../queue/discovery/ZkDiscoveryServiceTest.java | 2 +- .../queue/kafka/TbKafkaProducerTemplateTest.java | 2 +- .../server/queue/kafka/TbKafkaSettingsTest.java | 2 +- .../queue/memory/DefaultInMemoryStorageTest.java | 2 +- .../server/queue/util/PropertyUtilsTest.java | 2 +- common/script/pom.xml | 2 +- common/script/remote-js-client/pom.xml | 2 +- .../server/service/script/JsExecutorService.java | 2 +- .../service/script/RemoteJsInvokeService.java | 2 +- .../service/script/RemoteJsRequestEncoder.java | 2 +- .../service/script/RemoteJsResponseDecoder.java | 2 +- common/script/script-api/pom.xml | 2 +- .../script/api/AbstractScriptInvokeService.java | 2 +- .../script/api/BlockedScriptInfo.java | 2 +- .../script/api/RuleNodeScriptFactory.java | 2 +- .../script/api/ScriptInvokeService.java | 2 +- .../script/api/ScriptStatCallback.java | 2 +- .../org/thingsboard/script/api/ScriptType.java | 2 +- .../script/api/TbScriptException.java | 2 +- .../script/api/TbScriptExecutionTask.java | 2 +- .../script/api/js/AbstractJsInvokeService.java | 2 +- .../script/api/js/JsInvokeService.java | 2 +- .../script/api/js/JsScriptExecutionTask.java | 2 +- .../thingsboard/script/api/js/JsScriptInfo.java | 2 +- .../script/api/js/NashornJsInvokeService.java | 2 +- .../script/api/tbel/DateTimeFormatOptions.java | 2 +- .../api/tbel/DefaultTbelInvokeService.java | 2 +- .../org/thingsboard/script/api/tbel/TbDate.java | 2 +- .../org/thingsboard/script/api/tbel/TbJson.java | 2 +- .../org/thingsboard/script/api/tbel/TbUtils.java | 2 +- .../script/api/tbel/TbelInvokeService.java | 2 +- .../thingsboard/script/api/tbel/TbelScript.java | 2 +- .../script/api/tbel/TbelScriptExecutionTask.java | 2 +- .../script/api/tbel/TbDateConstructorTest.java | 2 +- .../thingsboard/script/api/tbel/TbDateTest.java | 2 +- .../script/api/tbel/TbDateTestEntity.java | 2 +- .../thingsboard/script/api/tbel/TbUtilsTest.java | 2 +- common/stats/pom.xml | 2 +- .../server/common/stats/DefaultCounter.java | 2 +- .../common/stats/DefaultMessagesStats.java | 2 +- .../server/common/stats/DefaultStatsFactory.java | 2 +- .../server/common/stats/FstStatsServiceImpl.java | 2 +- .../server/common/stats/MessagesStats.java | 2 +- .../server/common/stats/StatsCounter.java | 2 +- .../server/common/stats/StatsFactory.java | 2 +- .../server/common/stats/StatsType.java | 2 +- .../common/stats/TbApiUsageReportClient.java | 2 +- .../common/stats/TbApiUsageStateClient.java | 2 +- common/transport/coap/pom.xml | 2 +- .../coap/AbstractCoapTransportResource.java | 2 +- .../transport/coap/CoapSessionMsgType.java | 2 +- .../transport/coap/CoapTransportContext.java | 2 +- .../transport/coap/CoapTransportResource.java | 2 +- .../transport/coap/CoapTransportService.java | 2 +- .../coap/OtaPackageTransportResource.java | 2 +- .../transport/coap/TbCoapMessageObserver.java | 2 +- .../coap/TransportConfigurationContainer.java | 2 +- .../coap/adaptors/CoapAdaptorUtils.java | 2 +- .../coap/adaptors/CoapTransportAdaptor.java | 2 +- .../transport/coap/adaptors/JsonCoapAdaptor.java | 2 +- .../coap/adaptors/ProtoCoapAdaptor.java | 2 +- .../callback/AbstractSyncSessionCallback.java | 2 +- .../coap/callback/CoapDeviceAuthCallback.java | 2 +- .../coap/callback/CoapEfentoCallback.java | 2 +- .../coap/callback/CoapNoOpCallback.java | 2 +- .../transport/coap/callback/CoapOkCallback.java | 2 +- .../GetAttributesSyncSessionCallback.java | 2 +- .../callback/ToServerRpcSyncSessionCallback.java | 2 +- .../transport/coap/client/CoapClientContext.java | 2 +- .../coap/client/DefaultCoapClientContext.java | 2 +- .../transport/coap/client/NoSecClient.java | 2 +- .../coap/client/NoSecObserveClient.java | 2 +- .../coap/client/SecureClientNoAuth.java | 2 +- .../transport/coap/client/SecureClientX509.java | 2 +- .../transport/coap/client/TbCoapClientState.java | 2 +- .../coap/client/TbCoapContentFormatUtil.java | 2 +- .../coap/client/TbCoapObservationState.java | 2 +- .../coap/efento/CoapEfentoTransportResource.java | 2 +- .../coap/efento/adaptor/EfentoCoapAdaptor.java | 2 +- .../coap/efento/utils/CoapEfentoUtils.java | 2 +- .../src/main/proto/efento/proto_config.proto | 2 +- .../main/proto/efento/proto_device_info.proto | 2 +- .../proto/efento/proto_measurement_types.proto | 2 +- .../main/proto/efento/proto_measurements.proto | 2 +- .../coap/src/main/proto/efento/proto_rule.proto | 2 +- .../coap/CoapTransportResourceTest.java | 2 +- common/transport/http/pom.xml | 2 +- .../transport/http/DeviceApiController.java | 2 +- .../transport/http/HttpTransportContext.java | 2 +- common/transport/lwm2m/pom.xml | 2 +- .../LwM2MTransportBootstrapService.java | 2 +- .../bootstrap/secure/LwM2MBootstrapConfig.java | 2 +- .../bootstrap/secure/LwM2MBootstrapServers.java | 2 +- .../bootstrap/secure/LwM2MServerBootstrap.java | 2 +- .../LwM2mDefaultBootstrapSessionManager.java | 2 +- .../TbLwM2MDtlsBootstrapCertificateVerifier.java | 2 +- .../store/LwM2MBootstrapClientInstanceIds.java | 2 +- .../LwM2MBootstrapConfigStoreTaskProvider.java | 2 +- .../store/LwM2MBootstrapSecurityStore.java | 2 +- .../store/LwM2MBootstrapTaskProvider.java | 2 +- .../store/LwM2MConfigurationChecker.java | 2 +- .../store/LwM2MInMemoryBootstrapConfigStore.java | 2 +- .../lwm2m/config/LwM2MSecureServerConfig.java | 2 +- .../config/LwM2MTransportBootstrapConfig.java | 2 +- .../lwm2m/config/LwM2MTransportServerConfig.java | 2 +- .../transport/lwm2m/config/TbLwM2mVersion.java | 2 +- .../LwM2mCredentialsSecurityInfoValidator.java | 2 +- .../lwm2m/secure/LwM2mRPkCredentials.java | 2 +- .../lwm2m/secure/TbLwM2MAuthorizer.java | 2 +- .../secure/TbLwM2MDtlsCertificateVerifier.java | 2 +- .../lwm2m/secure/TbLwM2MSecurityInfo.java | 2 +- .../lwm2m/secure/TbX509DtlsSessionInfo.java | 2 +- .../credentials/LwM2MClientCredentials.java | 2 +- .../server/AbstractLwM2mTransportResource.java | 2 +- .../server/DefaultLwM2mTransportService.java | 2 +- .../lwm2m/server/LwM2MNetworkConfig.java | 2 +- .../lwm2m/server/LwM2MOperationType.java | 2 +- .../lwm2m/server/LwM2MTransportService.java | 2 +- .../transport/lwm2m/server/LwM2mOtaConvert.java | 2 +- .../lwm2m/server/LwM2mQueuedRequest.java | 2 +- .../lwm2m/server/LwM2mServerListener.java | 2 +- .../lwm2m/server/LwM2mSessionMsgListener.java | 2 +- .../lwm2m/server/LwM2mTransportCoapResource.java | 2 +- .../lwm2m/server/LwM2mTransportContext.java | 2 +- .../lwm2m/server/LwM2mTransportServerHelper.java | 2 +- .../server/LwM2mVersionedModelProvider.java | 2 +- .../lwm2m/server/adaptors/LwM2MJsonAdaptor.java | 2 +- .../server/adaptors/LwM2MTransportAdaptor.java | 2 +- .../DefaultLwM2MAttributesService.java | 2 +- .../attributes/LwM2MAttributesService.java | 2 +- .../lwm2m/server/client/LwM2MAuthException.java | 2 +- .../lwm2m/server/client/LwM2MClientState.java | 2 +- .../server/client/LwM2MClientStateException.java | 2 +- .../lwm2m/server/client/LwM2mClient.java | 2 +- .../lwm2m/server/client/LwM2mClientContext.java | 2 +- .../server/client/LwM2mClientContextImpl.java | 2 +- .../lwm2m/server/client/ModelObject.java | 2 +- .../server/client/ParametersAnalyzeResult.java | 2 +- .../lwm2m/server/client/ResourceValue.java | 2 +- .../server/client/ResultsAddKeyValueProto.java | 2 +- .../server/common/LwM2MExecutorAwareService.java | 2 +- .../downlink/AbstractTbLwM2MRequestCallback.java | 2 +- .../AbstractTbLwM2MTargetedDownlinkRequest.java | 2 +- .../downlink/DefaultLwM2mDownlinkMsgHandler.java | 2 +- .../server/downlink/DownlinkRequestCallback.java | 2 +- .../lwm2m/server/downlink/HasContentFormat.java | 2 +- .../lwm2m/server/downlink/HasVersionedId.java | 2 +- .../lwm2m/server/downlink/HasVersionedIds.java | 2 +- .../server/downlink/LwM2mDownlinkMsgHandler.java | 2 +- .../TbLwM2MCancelAllObserveCallback.java | 2 +- .../server/downlink/TbLwM2MCancelAllRequest.java | 2 +- .../downlink/TbLwM2MCancelObserveCallback.java | 2 +- .../downlink/TbLwM2MCancelObserveRequest.java | 2 +- .../server/downlink/TbLwM2MCreateRequest.java | 2 +- .../downlink/TbLwM2MCreateResponseCallback.java | 2 +- .../server/downlink/TbLwM2MDeleteCallback.java | 2 +- .../server/downlink/TbLwM2MDeleteRequest.java | 2 +- .../downlink/TbLwM2MDiscoverAllRequest.java | 2 +- .../server/downlink/TbLwM2MDiscoverCallback.java | 2 +- .../server/downlink/TbLwM2MDiscoverRequest.java | 2 +- .../server/downlink/TbLwM2MDownlinkRequest.java | 2 +- .../server/downlink/TbLwM2MExecuteCallback.java | 2 +- .../server/downlink/TbLwM2MExecuteRequest.java | 2 +- .../server/downlink/TbLwM2MLatchCallback.java | 2 +- .../downlink/TbLwM2MObserveAllRequest.java | 2 +- .../server/downlink/TbLwM2MObserveCallback.java | 2 +- .../server/downlink/TbLwM2MObserveRequest.java | 2 +- .../server/downlink/TbLwM2MReadCallback.java | 2 +- .../server/downlink/TbLwM2MReadRequest.java | 2 +- .../server/downlink/TbLwM2MTargetedCallback.java | 2 +- .../downlink/TbLwM2MUplinkTargetedCallback.java | 2 +- .../downlink/TbLwM2MWriteAttributesCallback.java | 2 +- .../downlink/TbLwM2MWriteAttributesRequest.java | 2 +- .../downlink/TbLwM2MWriteReplaceRequest.java | 2 +- .../downlink/TbLwM2MWriteResponseCallback.java | 2 +- .../downlink/TbLwM2MWriteUpdateRequest.java | 2 +- ...tTbLwM2MTargetedDownlinkCompositeRequest.java | 2 +- .../composite/TbLwM2MReadCompositeCallback.java | 2 +- .../composite/TbLwM2MReadCompositeRequest.java | 2 +- .../composite/TbLwM2MWriteCompositeRequest.java | 2 +- .../TbLwM2MWriteResponseCompositeCallback.java | 2 +- .../log/DefaultLwM2MTelemetryLogService.java | 2 +- .../server/log/LwM2MTelemetryLogService.java | 2 +- .../lwm2m/server/model/LwM2MModelConfig.java | 2 +- .../server/model/LwM2MModelConfigService.java | 2 +- .../model/LwM2MModelConfigServiceImpl.java | 2 +- .../server/ota/DefaultLwM2MOtaUpdateService.java | 2 +- .../lwm2m/server/ota/LwM2MClientOtaInfo.java | 2 +- .../lwm2m/server/ota/LwM2MClientOtaState.java | 2 +- .../lwm2m/server/ota/LwM2MOtaUpdateService.java | 2 +- .../ota/firmware/FirmwareDeliveryMethod.java | 2 +- .../ota/firmware/FirmwareUpdateResult.java | 2 +- .../server/ota/firmware/FirmwareUpdateState.java | 2 +- .../ota/firmware/LwM2MClientFwOtaInfo.java | 2 +- .../firmware/LwM2MFirmwareUpdateStrategy.java | 2 +- .../ota/software/LwM2MClientSwOtaInfo.java | 2 +- .../software/LwM2MSoftwareUpdateStrategy.java | 2 +- .../ota/software/SoftwareUpdateResult.java | 2 +- .../server/ota/software/SoftwareUpdateState.java | 2 +- .../rpc/DefaultLwM2MRpcRequestHandler.java | 2 +- .../lwm2m/server/rpc/LwM2MRpcRequestHandler.java | 2 +- .../lwm2m/server/rpc/LwM2MRpcRequestHeader.java | 2 +- .../lwm2m/server/rpc/LwM2MRpcResponseBody.java | 2 +- .../server/rpc/RpcCancelAllObserveCallback.java | 2 +- .../server/rpc/RpcCancelObserveCallback.java | 2 +- .../lwm2m/server/rpc/RpcCreateRequest.java | 2 +- .../server/rpc/RpcCreateResponseCallback.java | 2 +- .../lwm2m/server/rpc/RpcDiscoverCallback.java | 2 +- .../rpc/RpcDownlinkRequestCallbackProxy.java | 2 +- .../server/rpc/RpcEmptyResponseCallback.java | 2 +- .../lwm2m/server/rpc/RpcLinkSetCallback.java | 2 +- .../server/rpc/RpcLwM2MDownlinkCallback.java | 2 +- .../server/rpc/RpcReadResponseCallback.java | 2 +- .../server/rpc/RpcWriteAttributesRequest.java | 2 +- .../lwm2m/server/rpc/RpcWriteReplaceRequest.java | 2 +- .../lwm2m/server/rpc/RpcWriteUpdateRequest.java | 2 +- .../rpc/composite/RpcReadCompositeRequest.java | 2 +- .../RpcReadResponseCompositeCallback.java | 2 +- .../rpc/composite/RpcWriteCompositeRequest.java | 2 +- .../session/DefaultLwM2MSessionManager.java | 2 +- .../server/session/LwM2MSessionManager.java | 2 +- .../store/TbDummyLwM2MClientOtaInfoStore.java | 2 +- .../server/store/TbDummyLwM2MClientStore.java | 2 +- .../store/TbDummyLwM2MModelConfigStore.java | 2 +- .../server/store/TbEditableSecurityStore.java | 2 +- .../server/store/TbInMemorySecurityStore.java | 2 +- .../store/TbL2M2MDtlsSessionInMemoryStore.java | 2 +- .../server/store/TbLwM2MClientOtaInfoStore.java | 2 +- .../lwm2m/server/store/TbLwM2MClientStore.java | 2 +- .../store/TbLwM2MDtlsSessionRedisStore.java | 2 +- .../server/store/TbLwM2MDtlsSessionStore.java | 2 +- .../server/store/TbLwM2MModelConfigStore.java | 2 +- .../store/TbLwM2mRedisClientOtaInfoStore.java | 2 +- .../store/TbLwM2mRedisRegistrationStore.java | 2 +- .../server/store/TbLwM2mRedisSecurityStore.java | 2 +- .../lwm2m/server/store/TbLwM2mSecurityStore.java | 2 +- .../lwm2m/server/store/TbLwM2mStoreFactory.java | 2 +- .../lwm2m/server/store/TbMainSecurityStore.java | 2 +- .../server/store/TbRedisLwM2MClientStore.java | 2 +- .../store/TbRedisLwM2MModelConfigStore.java | 2 +- .../lwm2m/server/store/TbSecurityStore.java | 2 +- .../server/store/util/LwM2MClientSerDes.java | 2 +- .../uplink/DefaultLwM2mUplinkMsgHandler.java | 2 +- .../lwm2m/server/uplink/LwM2mTypeServer.java | 2 +- .../server/uplink/LwM2mUplinkMsgHandler.java | 2 +- .../lwm2m/utils/LwM2MTransportUtil.java | 2 +- .../lwm2m/utils/LwM2mValueConverterImpl.java | 2 +- .../model/LwM2MModelConfigServiceImplTest.java | 2 +- .../lwm2m/server/client/LwM2mClientTest.java | 2 +- .../server/store/util/LwM2MClientSerDesTest.java | 2 +- common/transport/mqtt/pom.xml | 2 +- .../transport/mqtt/MqttSslHandlerProvider.java | 2 +- .../transport/mqtt/MqttTransportContext.java | 2 +- .../transport/mqtt/MqttTransportHandler.java | 2 +- .../mqtt/MqttTransportServerInitializer.java | 2 +- .../transport/mqtt/MqttTransportService.java | 2 +- .../server/transport/mqtt/TopicType.java | 2 +- .../adaptors/BackwardCompatibilityAdaptor.java | 2 +- .../transport/mqtt/adaptors/JsonMqttAdaptor.java | 2 +- .../mqtt/adaptors/MqttTransportAdaptor.java | 2 +- .../mqtt/adaptors/ProtoMqttAdaptor.java | 2 +- .../server/transport/mqtt/limits/IpFilter.java | 2 +- .../transport/mqtt/limits/ProxyIpFilter.java | 2 +- .../AbstractGatewayDeviceSessionContext.java | 2 +- .../session/AbstractGatewaySessionHandler.java | 2 +- .../transport/mqtt/session/DeviceSessionCtx.java | 2 +- .../session/GatewayDeviceSessionContext.java | 2 +- .../mqtt/session/GatewaySessionHandler.java | 2 +- .../session/MqttDeviceAwareSessionContext.java | 2 +- .../transport/mqtt/session/MqttTopicMatcher.java | 2 +- .../session/SparkplugDeviceSessionContext.java | 2 +- .../session/SparkplugNodeSessionHandler.java | 2 +- .../mqtt/util/AlwaysTrueTopicFilter.java | 2 +- .../transport/mqtt/util/EqualsTopicFilter.java | 2 +- .../transport/mqtt/util/MqttTopicFilter.java | 2 +- .../mqtt/util/MqttTopicFilterFactory.java | 2 +- .../transport/mqtt/util/RegexTopicFilter.java | 2 +- .../server/transport/mqtt/util/ReturnCode.java | 2 +- .../transport/mqtt/util/ReturnCodeResolver.java | 2 +- .../mqtt/util/sparkplug/MetricDataType.java | 2 +- .../util/sparkplug/SparkplugConnectionState.java | 2 +- .../util/sparkplug/SparkplugMessageType.java | 2 +- .../mqtt/util/sparkplug/SparkplugMetricUtil.java | 2 +- .../sparkplug/SparkplugRpcRequestHeader.java | 2 +- .../util/sparkplug/SparkplugRpcResponseBody.java | 2 +- .../mqtt/util/sparkplug/SparkplugTopic.java | 2 +- .../mqtt/util/sparkplug/SparkplugTopicUtil.java | 2 +- .../mqtt/src/main/proto/sparkplug.proto | 2 +- .../transport/mqtt/MqttTransportHandlerTest.java | 2 +- .../mqtt/session/GatewaySessionHandlerTest.java | 2 +- .../mqtt/util/MqttTopicFilterFactoryTest.java | 2 +- common/transport/pom.xml | 2 +- common/transport/snmp/pom.xml | 2 +- .../transport/snmp/SnmpTransportContext.java | 2 +- .../event/ServiceListChangedEventListener.java | 2 +- .../event/SnmpTransportListChangedEvent.java | 2 +- .../SnmpTransportListChangedEventListener.java | 2 +- .../transport/snmp/service/PduService.java | 2 +- .../service/ProtoTransportEntityService.java | 2 +- .../transport/snmp/service/SnmpAuthService.java | 2 +- .../service/SnmpTransportBalancingService.java | 2 +- .../snmp/service/SnmpTransportService.java | 2 +- .../snmp/session/DeviceSessionContext.java | 2 +- .../transport/snmp/SnmpDeviceSimulatorV2.java | 2 +- .../transport/snmp/SnmpDeviceSimulatorV3.java | 2 +- .../server/transport/snmp/SnmpTestV2.java | 2 +- .../server/transport/snmp/SnmpTestV3.java | 2 +- common/transport/transport-api/pom.xml | 2 +- .../common/transport/DeviceDeletedEvent.java | 2 +- .../transport/DeviceProfileUpdatedEvent.java | 2 +- .../common/transport/DeviceUpdatedEvent.java | 2 +- .../common/transport/SessionMsgListener.java | 2 +- .../common/transport/TransportAdaptor.java | 2 +- .../common/transport/TransportContext.java | 2 +- .../transport/TransportDeviceProfileCache.java | 2 +- .../common/transport/TransportResourceCache.java | 2 +- .../common/transport/TransportService.java | 2 +- .../transport/TransportServiceCallback.java | 2 +- .../transport/TransportTenantProfileCache.java | 2 +- .../common/transport/auth/DeviceAuthResult.java | 2 +- .../common/transport/auth/DeviceAuthService.java | 2 +- .../transport/auth/DeviceProfileAware.java | 2 +- .../GetOrCreateDeviceFromGatewayResponse.java | 2 +- .../transport/auth/SessionInfoCreator.java | 2 +- .../transport/auth/TransportDeviceInfo.java | 2 +- .../auth/ValidateDeviceCredentialsResponse.java | 2 +- .../config/ssl/AbstractSslCredentials.java | 2 +- .../config/ssl/KeystoreSslCredentials.java | 2 +- .../transport/config/ssl/PemSslCredentials.java | 2 +- .../transport/config/ssl/SslCredentials.java | 2 +- .../config/ssl/SslCredentialsConfig.java | 2 +- .../transport/config/ssl/SslCredentialsType.java | 2 +- .../ssl/SslCredentialsWebServerCustomizer.java | 2 +- .../limits/DefaultEntityLimitsCache.java | 2 +- .../limits/DefaultTransportRateLimitService.java | 2 +- .../limits/DummyTransportRateLimit.java | 2 +- .../common/transport/limits/EntityLimitKey.java | 2 +- .../transport/limits/EntityLimitsCache.java | 2 +- .../limits/EntityTransportRateLimits.java | 2 +- .../limits/InetAddressRateLimitStats.java | 2 +- .../limits/SimpleTransportRateLimit.java | 2 +- .../transport/limits/TransportRateLimit.java | 2 +- .../limits/TransportRateLimitService.java | 2 +- .../profile/TenantProfileUpdateResult.java | 2 +- .../DefaultTransportDeviceProfileCache.java | 2 +- .../service/DefaultTransportResourceCache.java | 2 +- .../service/DefaultTransportService.java | 2 +- .../DefaultTransportTenantProfileCache.java | 2 +- .../transport/service/RpcRequestMetadata.java | 2 +- .../transport/service/SessionActivityData.java | 2 +- .../transport/service/SessionMetaData.java | 2 +- .../service/ToRuleEngineMsgEncoder.java | 2 +- .../service/ToTransportMsgResponseDecoder.java | 2 +- .../service/TransportApiRequestEncoder.java | 2 +- .../service/TransportApiResponseDecoder.java | 2 +- .../TransportQueueRoutingInfoService.java | 2 +- .../TransportTenantRoutingInfoService.java | 2 +- .../session/DeviceAwareSessionContext.java | 2 +- .../common/transport/session/SessionContext.java | 2 +- .../server/common/transport/util/JsonUtils.java | 2 +- .../server/common/transport/util/SslUtil.java | 2 +- common/util/pom.xml | 2 +- .../common/util/AbstractListeningExecutor.java | 2 +- .../thingsboard/common/util/AzureIotHubUtil.java | 2 +- .../thingsboard/common/util/DonAsynchron.java | 2 +- .../thingsboard/common/util/ExceptionUtil.java | 2 +- .../common/util/ExecutorProvider.java | 2 +- .../org/thingsboard/common/util/JacksonUtil.java | 2 +- .../java/org/thingsboard/common/util/KvUtil.java | 2 +- .../common/util/LinkedHashMapRemoveEldest.java | 2 +- .../common/util/ListeningExecutor.java | 2 +- .../org/thingsboard/common/util/RegexUtils.java | 2 +- .../org/thingsboard/common/util/SslUtil.java | 2 +- .../org/thingsboard/common/util/SystemUtil.java | 2 +- .../org/thingsboard/common/util/TbStopWatch.java | 2 +- .../common/util/ThingsBoardExecutors.java | 2 +- .../ThingsBoardForkJoinWorkerThreadFactory.java | 2 +- .../common/util/ThingsBoardThreadFactory.java | 2 +- .../common/util/ExceptionUtilTest.java | 2 +- .../thingsboard/common/util/JacksonUtilTest.java | 2 +- .../util/LinkedHashMapRemoveEldestTest.java | 2 +- common/version-control/pom.xml | 2 +- .../sync/vc/ClusterVersionControlService.java | 2 +- .../vc/DefaultClusterVersionControlService.java | 2 +- .../sync/vc/DefaultGitRepositoryService.java | 2 +- .../server/service/sync/vc/GitRepository.java | 2 +- .../service/sync/vc/GitRepositoryService.java | 2 +- .../server/service/sync/vc/PendingCommit.java | 2 +- .../sync/vc/VersionControlRequestCtx.java | 2 +- dao/pom.xml | 2 +- .../java/org/thingsboard/server/dao/Dao.java | 2 +- .../java/org/thingsboard/server/dao/DaoUtil.java | 2 +- .../server/dao/ExportableEntityDao.java | 2 +- .../server/dao/ExportableEntityRepository.java | 2 +- .../server/dao/ImageContainerDao.java | 2 +- .../org/thingsboard/server/dao/JpaDaoConfig.java | 2 +- .../server/dao/SqlTimeseriesDaoConfig.java | 2 +- .../thingsboard/server/dao/SqlTsDaoConfig.java | 2 +- .../server/dao/SqlTsLatestDaoConfig.java | 2 +- .../thingsboard/server/dao/TenantEntityDao.java | 2 +- .../server/dao/TenantEntityWithDataDao.java | 2 +- .../server/dao/ThingsboardPostgreSQLDialect.java | 2 +- .../server/dao/TimescaleDaoConfig.java | 2 +- .../server/dao/TimescaleTsLatestDaoConfig.java | 2 +- .../server/dao/alarm/AlarmCommentDao.java | 2 +- .../thingsboard/server/dao/alarm/AlarmDao.java | 2 +- .../dao/alarm/AlarmTypesCacheEvictEvent.java | 2 +- .../dao/alarm/AlarmTypesCaffeineCache.java | 2 +- .../server/dao/alarm/AlarmTypesRedisCache.java | 2 +- .../dao/alarm/BaseAlarmCommentService.java | 2 +- .../server/dao/alarm/BaseAlarmService.java | 2 +- .../server/dao/aspect/DbCallStats.java | 2 +- .../server/dao/aspect/DbCallStatsSnapshot.java | 2 +- .../server/dao/aspect/MethodCallStats.java | 2 +- .../dao/aspect/MethodCallStatsSnapshot.java | 2 +- .../server/dao/aspect/SqlDaoCallsAspect.java | 2 +- .../server/dao/asset/AssetCacheEvictEvent.java | 2 +- .../server/dao/asset/AssetCacheKey.java | 2 +- .../server/dao/asset/AssetCaffeineCache.java | 2 +- .../thingsboard/server/dao/asset/AssetDao.java | 2 +- .../server/dao/asset/AssetProfileCacheKey.java | 2 +- .../dao/asset/AssetProfileCaffeineCache.java | 2 +- .../server/dao/asset/AssetProfileDao.java | 2 +- .../server/dao/asset/AssetProfileEvictEvent.java | 2 +- .../server/dao/asset/AssetProfileRedisCache.java | 2 +- .../dao/asset/AssetProfileServiceImpl.java | 2 +- .../server/dao/asset/AssetRedisCache.java | 2 +- .../server/dao/asset/AssetTypeFilter.java | 2 +- .../server/dao/asset/BaseAssetService.java | 2 +- .../server/dao/attributes/AttributeCacheKey.java | 2 +- .../dao/attributes/AttributeCaffeineCache.java | 2 +- .../dao/attributes/AttributeRedisCache.java | 2 +- .../server/dao/attributes/AttributeUtils.java | 2 +- .../server/dao/attributes/AttributesDao.java | 2 +- .../dao/attributes/BaseAttributesService.java | 2 +- .../dao/attributes/CachedAttributesService.java | 2 +- .../server/dao/audit/AuditLogDao.java | 2 +- .../server/dao/audit/AuditLogLevelFilter.java | 2 +- .../server/dao/audit/AuditLogLevelMask.java | 2 +- .../dao/audit/AuditLogLevelProperties.java | 2 +- .../server/dao/audit/AuditLogServiceImpl.java | 2 +- .../dao/audit/DummyAuditLogServiceImpl.java | 2 +- .../server/dao/audit/sink/AuditLogSink.java | 2 +- .../server/dao/audit/sink/DummyAuditLogSink.java | 2 +- .../audit/sink/ElasticsearchAuditLogSink.java | 2 +- .../server/dao/cache/CacheExecutorService.java | 2 +- .../BaseComponentDescriptorService.java | 2 +- .../dao/component/ComponentDescriptorDao.java | 2 +- .../server/dao/customer/CustomerDao.java | 2 +- .../server/dao/customer/CustomerServiceImpl.java | 2 +- .../server/dao/dashboard/DashboardDao.java | 2 +- .../server/dao/dashboard/DashboardInfoDao.java | 2 +- .../dao/dashboard/DashboardServiceImpl.java | 2 +- .../dao/dashboard/DashboardTitleEvictEvent.java | 2 +- .../dashboard/DashboardTitlesCaffeineCache.java | 2 +- .../dao/dashboard/DashboardTitlesRedisCache.java | 2 +- .../server/dao/device/ClaimDataInfo.java | 2 +- .../device/DeviceConnectivityConfiguration.java | 2 +- .../dao/device/DeviceConnectivityInfo.java | 2 +- .../device/DeviceConnectivityServiceImpl.java | 2 +- .../device/DeviceCredentialsCaffeineCache.java | 2 +- .../server/dao/device/DeviceCredentialsDao.java | 2 +- .../dao/device/DeviceCredentialsEvictEvent.java | 2 +- .../dao/device/DeviceCredentialsRedisCache.java | 2 +- .../dao/device/DeviceCredentialsServiceImpl.java | 2 +- .../thingsboard/server/dao/device/DeviceDao.java | 2 +- .../server/dao/device/DeviceProfileCacheKey.java | 2 +- .../dao/device/DeviceProfileCaffeineCache.java | 2 +- .../server/dao/device/DeviceProfileDao.java | 2 +- .../dao/device/DeviceProfileEvictEvent.java | 2 +- .../dao/device/DeviceProfileRedisCache.java | 2 +- .../dao/device/DeviceProfileServiceImpl.java | 2 +- .../server/dao/device/DeviceServiceImpl.java | 2 +- .../server/dao/edge/BaseEdgeEventService.java | 2 +- .../edge/DefaultEdgeSynchronizationManager.java | 2 +- .../server/dao/edge/EdgeCacheEvictEvent.java | 2 +- .../server/dao/edge/EdgeCacheKey.java | 2 +- .../server/dao/edge/EdgeCaffeineCache.java | 2 +- .../org/thingsboard/server/dao/edge/EdgeDao.java | 2 +- .../server/dao/edge/EdgeEventDao.java | 2 +- .../server/dao/edge/EdgeRedisCache.java | 2 +- .../server/dao/edge/EdgeServiceImpl.java | 2 +- .../dao/entity/AbstractCachedEntityService.java | 2 +- .../server/dao/entity/AbstractCachedService.java | 2 +- .../server/dao/entity/AbstractEntityService.java | 2 +- .../dao/entity/BaseEntityCountService.java | 2 +- .../server/dao/entity/BaseEntityService.java | 2 +- .../dao/entity/DefaultEntityServiceRegistry.java | 2 +- .../dao/entity/EntityCountCacheEvictEvent.java | 2 +- .../server/dao/entity/EntityCountCacheKey.java | 2 +- .../server/dao/entity/EntityQueryDao.java | 2 +- .../entity/count/EntityCountCaffeineCache.java | 2 +- .../dao/entity/count/EntityCountRedisCache.java | 2 +- .../dao/entityview/EntityViewCacheKey.java | 2 +- .../dao/entityview/EntityViewCacheValue.java | 2 +- .../dao/entityview/EntityViewCaffeineCache.java | 2 +- .../server/dao/entityview/EntityViewDao.java | 2 +- .../dao/entityview/EntityViewEvictEvent.java | 2 +- .../dao/entityview/EntityViewRedisCache.java | 2 +- .../dao/entityview/EntityViewServiceImpl.java | 2 +- .../server/dao/event/BaseEventService.java | 2 +- .../thingsboard/server/dao/event/EventDao.java | 2 +- .../dao/eventsourcing/ActionEntityEvent.java | 2 +- .../dao/eventsourcing/DeleteEntityEvent.java | 2 +- .../dao/eventsourcing/RelationActionEvent.java | 2 +- .../dao/eventsourcing/SaveEntityEvent.java | 2 +- .../dao/exception/BufferLimitException.java | 2 +- .../dao/exception/DataValidationException.java | 2 +- .../server/dao/exception/DatabaseException.java | 2 +- .../DeviceCredentialsValidationException.java | 2 +- .../dao/exception/EntitiesLimitException.java | 2 +- .../exception/IncorrectParameterException.java | 2 +- .../thingsboard/server/dao/model/BaseEntity.java | 2 +- .../server/dao/model/BaseSqlEntity.java | 2 +- .../server/dao/model/ModelConstants.java | 2 +- .../org/thingsboard/server/dao/model/ToData.java | 2 +- .../model/sql/AbstractAlarmCommentEntity.java | 2 +- .../dao/model/sql/AbstractAlarmEntity.java | 2 +- .../dao/model/sql/AbstractAssetEntity.java | 2 +- .../dao/model/sql/AbstractDeviceEntity.java | 2 +- .../server/dao/model/sql/AbstractEdgeEntity.java | 2 +- .../dao/model/sql/AbstractEntityViewEntity.java | 2 +- .../dao/model/sql/AbstractTenantEntity.java | 2 +- .../server/dao/model/sql/AbstractTsKvEntity.java | 2 +- .../dao/model/sql/AbstractWidgetTypeEntity.java | 2 +- .../dao/model/sql/AdminSettingsEntity.java | 2 +- .../server/dao/model/sql/AlarmCommentEntity.java | 2 +- .../dao/model/sql/AlarmCommentInfoEntity.java | 2 +- .../server/dao/model/sql/AlarmEntity.java | 2 +- .../server/dao/model/sql/AlarmInfoEntity.java | 2 +- .../dao/model/sql/ApiUsageStateEntity.java | 2 +- .../server/dao/model/sql/AssetEntity.java | 2 +- .../server/dao/model/sql/AssetInfoEntity.java | 2 +- .../server/dao/model/sql/AssetProfileEntity.java | 2 +- .../dao/model/sql/AttributeKvCompositeKey.java | 2 +- .../server/dao/model/sql/AttributeKvEntity.java | 2 +- .../server/dao/model/sql/AuditLogEntity.java | 2 +- .../dao/model/sql/ComponentDescriptorEntity.java | 2 +- .../server/dao/model/sql/CustomerEntity.java | 2 +- .../server/dao/model/sql/DashboardEntity.java | 2 +- .../dao/model/sql/DashboardInfoEntity.java | 2 +- .../dao/model/sql/DeviceCredentialsEntity.java | 2 +- .../server/dao/model/sql/DeviceEntity.java | 2 +- .../server/dao/model/sql/DeviceInfoEntity.java | 2 +- .../dao/model/sql/DeviceProfileEntity.java | 2 +- .../server/dao/model/sql/EdgeEntity.java | 2 +- .../server/dao/model/sql/EdgeEventEntity.java | 2 +- .../server/dao/model/sql/EdgeInfoEntity.java | 2 +- .../dao/model/sql/EntityAlarmCompositeKey.java | 2 +- .../server/dao/model/sql/EntityAlarmEntity.java | 2 +- .../server/dao/model/sql/EntityViewEntity.java | 2 +- .../dao/model/sql/EntityViewInfoEntity.java | 2 +- .../server/dao/model/sql/ErrorEventEntity.java | 2 +- .../server/dao/model/sql/EventEntity.java | 2 +- .../dao/model/sql/LifecycleEventEntity.java | 2 +- .../server/dao/model/sql/NotificationEntity.java | 2 +- .../dao/model/sql/NotificationRequestEntity.java | 2 +- .../model/sql/NotificationRequestInfoEntity.java | 2 +- .../dao/model/sql/NotificationRuleEntity.java | 2 +- .../model/sql/NotificationRuleInfoEntity.java | 2 +- .../dao/model/sql/NotificationTargetEntity.java | 2 +- .../model/sql/NotificationTemplateEntity.java | 2 +- .../OAuth2ClientRegistrationTemplateEntity.java | 2 +- .../server/dao/model/sql/OAuth2DomainEntity.java | 2 +- .../server/dao/model/sql/OAuth2MobileEntity.java | 2 +- .../server/dao/model/sql/OAuth2ParamsEntity.java | 2 +- .../dao/model/sql/OAuth2RegistrationEntity.java | 2 +- .../server/dao/model/sql/OtaPackageEntity.java | 2 +- .../dao/model/sql/OtaPackageInfoEntity.java | 2 +- .../server/dao/model/sql/QueueEntity.java | 2 +- .../dao/model/sql/RelationCompositeKey.java | 2 +- .../server/dao/model/sql/RelationEntity.java | 2 +- .../server/dao/model/sql/RpcEntity.java | 2 +- .../dao/model/sql/RuleChainDebugEventEntity.java | 2 +- .../server/dao/model/sql/RuleChainEntity.java | 2 +- .../dao/model/sql/RuleNodeDebugEventEntity.java | 2 +- .../server/dao/model/sql/RuleNodeEntity.java | 2 +- .../dao/model/sql/RuleNodeStateEntity.java | 2 +- .../dao/model/sql/StatisticsEventEntity.java | 2 +- .../server/dao/model/sql/TbResourceEntity.java | 2 +- .../dao/model/sql/TbResourceInfoEntity.java | 2 +- .../server/dao/model/sql/TenantEntity.java | 2 +- .../server/dao/model/sql/TenantInfoEntity.java | 2 +- .../dao/model/sql/TenantProfileEntity.java | 2 +- .../dao/model/sql/UserAuthSettingsEntity.java | 2 +- .../dao/model/sql/UserCredentialsEntity.java | 2 +- .../server/dao/model/sql/UserEntity.java | 2 +- .../server/dao/model/sql/UserSettingsEntity.java | 2 +- .../dao/model/sql/WidgetTypeDetailsEntity.java | 2 +- .../server/dao/model/sql/WidgetTypeEntity.java | 2 +- .../dao/model/sql/WidgetTypeIdFqnEntity.java | 2 +- .../dao/model/sql/WidgetTypeInfoEntity.java | 2 +- .../dao/model/sql/WidgetsBundleEntity.java | 2 +- .../sql/WidgetsBundleWidgetCompositeKey.java | 2 +- .../dao/model/sql/WidgetsBundleWidgetEntity.java | 2 +- .../model/sqlts/dictionary/TsKvDictionary.java | 2 +- .../dictionary/TsKvDictionaryCompositeKey.java | 2 +- .../sqlts/latest/TsKvLatestCompositeKey.java | 2 +- .../dao/model/sqlts/latest/TsKvLatestEntity.java | 2 +- .../timescale/ts/TimescaleTsKvCompositeKey.java | 2 +- .../sqlts/timescale/ts/TimescaleTsKvEntity.java | 2 +- .../dao/model/sqlts/ts/TsKvCompositeKey.java | 2 +- .../server/dao/model/sqlts/ts/TsKvEntity.java | 2 +- .../dao/nosql/CassandraAbstractAsyncDao.java | 2 +- .../server/dao/nosql/CassandraAbstractDao.java | 2 +- .../nosql/CassandraBufferedRateReadExecutor.java | 2 +- .../CassandraBufferedRateWriteExecutor.java | 2 +- .../DefaultNotificationRequestService.java | 2 +- .../DefaultNotificationRuleService.java | 2 +- .../notification/DefaultNotificationService.java | 2 +- .../DefaultNotificationSettingsService.java | 2 +- .../DefaultNotificationTargetService.java | 2 +- .../DefaultNotificationTemplateService.java | 2 +- .../dao/notification/DefaultNotifications.java | 2 +- .../server/dao/notification/NotificationDao.java | 2 +- .../dao/notification/NotificationRequestDao.java | 2 +- .../dao/notification/NotificationRuleDao.java | 2 +- .../dao/notification/NotificationTargetDao.java | 2 +- .../notification/NotificationTemplateDao.java | 2 +- .../HybridClientRegistrationRepository.java | 2 +- .../OAuth2ClientRegistrationTemplateDao.java | 2 +- .../oauth2/OAuth2ConfigTemplateServiceImpl.java | 2 +- .../server/dao/oauth2/OAuth2Configuration.java | 2 +- .../server/dao/oauth2/OAuth2DomainDao.java | 2 +- .../server/dao/oauth2/OAuth2MobileDao.java | 2 +- .../server/dao/oauth2/OAuth2ParamsDao.java | 2 +- .../server/dao/oauth2/OAuth2RegistrationDao.java | 2 +- .../server/dao/oauth2/OAuth2ServiceImpl.java | 2 +- .../server/dao/oauth2/OAuth2Utils.java | 2 +- .../server/dao/ota/BaseOtaPackageService.java | 2 +- .../dao/ota/OtaPackageCacheEvictEvent.java | 2 +- .../server/dao/ota/OtaPackageCacheKey.java | 2 +- .../server/dao/ota/OtaPackageCaffeineCache.java | 2 +- .../server/dao/ota/OtaPackageDao.java | 2 +- .../server/dao/ota/OtaPackageInfoDao.java | 2 +- .../server/dao/ota/OtaPackageRedisCache.java | 2 +- .../server/dao/queue/BaseQueueService.java | 2 +- .../thingsboard/server/dao/queue/QueueDao.java | 2 +- .../server/dao/relation/BaseRelationService.java | 2 +- .../server/dao/relation/EntityRelationEvent.java | 2 +- .../server/dao/relation/RelationCacheKey.java | 2 +- .../server/dao/relation/RelationCacheValue.java | 2 +- .../dao/relation/RelationCaffeineCache.java | 2 +- .../server/dao/relation/RelationDao.java | 2 +- .../server/dao/relation/RelationRedisCache.java | 2 +- .../server/dao/resource/BaseImageService.java | 2 +- .../server/dao/resource/BaseResourceService.java | 2 +- .../server/dao/resource/ImageCacheKey.java | 2 +- .../server/dao/resource/TbResourceDao.java | 2 +- .../server/dao/resource/TbResourceInfoDao.java | 2 +- .../server/dao/rpc/BaseRpcService.java | 2 +- .../org/thingsboard/server/dao/rpc/RpcDao.java | 2 +- .../server/dao/rule/BaseRuleChainService.java | 2 +- .../dao/rule/BaseRuleNodeStateService.java | 2 +- .../server/dao/rule/RuleChainDao.java | 2 +- .../thingsboard/server/dao/rule/RuleNodeDao.java | 2 +- .../server/dao/rule/RuleNodeStateDao.java | 2 +- .../server/dao/service/ConstraintValidator.java | 2 +- .../server/dao/service/DataValidator.java | 2 +- .../server/dao/service/NoXssValidator.java | 2 +- .../server/dao/service/PaginatedRemover.java | 2 +- .../dao/service/StringLengthValidator.java | 2 +- .../server/dao/service/TimePaginatedRemover.java | 2 +- .../server/dao/service/Validator.java | 2 +- .../AbstractHasOtaPackageValidator.java | 2 +- .../validator/AdminSettingsDataValidator.java | 2 +- .../validator/AlarmCommentDataValidator.java | 2 +- .../service/validator/AlarmDataValidator.java | 2 +- .../service/validator/ApiUsageDataValidator.java | 2 +- .../service/validator/AssetDataValidator.java | 2 +- .../validator/AssetProfileDataValidator.java | 2 +- .../service/validator/AuditLogDataValidator.java | 2 +- .../validator/BaseOtaPackageDataValidator.java | 2 +- .../ClientRegistrationTemplateDataValidator.java | 2 +- .../ComponentDescriptorDataValidator.java | 2 +- .../service/validator/CustomerDataValidator.java | 2 +- .../validator/DashboardDataValidator.java | 2 +- .../DeviceCredentialsDataValidator.java | 2 +- .../service/validator/DeviceDataValidator.java | 2 +- .../validator/DeviceProfileDataValidator.java | 2 +- .../dao/service/validator/EdgeDataValidator.java | 2 +- .../validator/EdgeEventDataValidator.java | 2 +- .../validator/EntityViewDataValidator.java | 2 +- .../service/validator/EventDataValidator.java | 2 +- .../validator/OtaPackageDataValidator.java | 2 +- .../validator/OtaPackageInfoDataValidator.java | 2 +- .../dao/service/validator/QueueValidator.java | 2 +- .../service/validator/ResourceDataValidator.java | 2 +- .../validator/RuleChainDataValidator.java | 2 +- .../service/validator/TenantDataValidator.java | 2 +- .../validator/TenantProfileDataValidator.java | 2 +- .../validator/UserCredentialsDataValidator.java | 2 +- .../dao/service/validator/UserDataValidator.java | 2 +- .../validator/WidgetTypeDataValidator.java | 2 +- .../validator/WidgetsBundleDataValidator.java | 2 +- .../server/dao/settings/AdminSettingsDao.java | 2 +- .../dao/settings/AdminSettingsServiceImpl.java | 2 +- .../server/dao/sql/JpaAbstractDao.java | 2 +- .../JpaAbstractDaoListeningExecutorService.java | 2 +- .../server/dao/sql/JpaExecutorService.java | 2 +- .../dao/sql/ScheduledLogExecutorComponent.java | 2 +- .../server/dao/sql/TbSqlBlockingQueue.java | 2 +- .../server/dao/sql/TbSqlBlockingQueueParams.java | 2 +- .../dao/sql/TbSqlBlockingQueueWrapper.java | 2 +- .../thingsboard/server/dao/sql/TbSqlQueue.java | 2 +- .../server/dao/sql/TbSqlQueueElement.java | 2 +- .../dao/sql/alarm/AlarmCommentRepository.java | 2 +- .../server/dao/sql/alarm/AlarmRepository.java | 2 +- .../dao/sql/alarm/EntityAlarmRepository.java | 2 +- .../server/dao/sql/alarm/JpaAlarmCommentDao.java | 2 +- .../server/dao/sql/alarm/JpaAlarmDao.java | 2 +- .../dao/sql/asset/AssetProfileRepository.java | 2 +- .../server/dao/sql/asset/AssetRepository.java | 2 +- .../server/dao/sql/asset/JpaAssetDao.java | 2 +- .../server/dao/sql/asset/JpaAssetProfileDao.java | 2 +- .../attributes/AttributeKvInsertRepository.java | 2 +- .../sql/attributes/AttributeKvRepository.java | 2 +- .../dao/sql/attributes/JpaAttributeDao.java | 2 +- .../SqlAttributesInsertRepository.java | 2 +- .../server/dao/sql/audit/AuditLogRepository.java | 2 +- .../server/dao/sql/audit/JpaAuditLogDao.java | 2 +- ...tractComponentDescriptorInsertRepository.java | 2 +- .../ComponentDescriptorInsertRepository.java | 2 +- .../component/ComponentDescriptorRepository.java | 2 +- .../component/JpaBaseComponentDescriptorDao.java | 2 +- .../SqlComponentDescriptorInsertRepository.java | 2 +- .../dao/sql/customer/CustomerRepository.java | 2 +- .../server/dao/sql/customer/JpaCustomerDao.java | 2 +- .../sql/dashboard/DashboardInfoRepository.java | 2 +- .../dao/sql/dashboard/DashboardRepository.java | 2 +- .../dao/sql/dashboard/JpaDashboardDao.java | 2 +- .../dao/sql/dashboard/JpaDashboardInfoDao.java | 2 +- .../device/DefaultNativeDeviceRepository.java | 2 +- .../sql/device/DeviceCredentialsRepository.java | 2 +- .../dao/sql/device/DeviceProfileRepository.java | 2 +- .../server/dao/sql/device/DeviceRepository.java | 2 +- .../dao/sql/device/JpaDeviceCredentialsDao.java | 2 +- .../server/dao/sql/device/JpaDeviceDao.java | 2 +- .../dao/sql/device/JpaDeviceProfileDao.java | 2 +- .../dao/sql/device/NativeDeviceRepository.java | 2 +- .../dao/sql/edge/EdgeEventInsertRepository.java | 2 +- .../server/dao/sql/edge/EdgeEventRepository.java | 2 +- .../server/dao/sql/edge/EdgeRepository.java | 2 +- .../server/dao/sql/edge/JpaBaseEdgeEventDao.java | 2 +- .../server/dao/sql/edge/JpaEdgeDao.java | 2 +- .../dao/sql/entityview/EntityViewRepository.java | 2 +- .../dao/sql/entityview/JpaEntityViewDao.java | 2 +- .../dao/sql/event/ErrorEventRepository.java | 2 +- .../dao/sql/event/EventCleanupRepository.java | 2 +- .../dao/sql/event/EventInsertRepository.java | 2 +- .../sql/event/EventPartitionConfiguration.java | 2 +- .../server/dao/sql/event/EventRepository.java | 2 +- .../server/dao/sql/event/JpaBaseEventDao.java | 2 +- .../dao/sql/event/LifecycleEventRepository.java | 2 +- .../sql/event/RuleChainDebugEventRepository.java | 2 +- .../sql/event/RuleNodeDebugEventRepository.java | 2 +- .../dao/sql/event/SqlEventCleanupRepository.java | 2 +- .../dao/sql/event/StatisticsEventRepository.java | 2 +- .../dao/sql/notification/JpaNotificationDao.java | 2 +- .../notification/JpaNotificationRequestDao.java | 2 +- .../sql/notification/JpaNotificationRuleDao.java | 2 +- .../notification/JpaNotificationTargetDao.java | 2 +- .../notification/JpaNotificationTemplateDao.java | 2 +- .../sql/notification/NotificationRepository.java | 2 +- .../NotificationRequestRepository.java | 2 +- .../notification/NotificationRuleRepository.java | 2 +- .../NotificationTargetRepository.java | 2 +- .../NotificationTemplateRepository.java | 2 +- .../JpaOAuth2ClientRegistrationTemplateDao.java | 2 +- .../dao/sql/oauth2/JpaOAuth2DomainDao.java | 2 +- .../dao/sql/oauth2/JpaOAuth2MobileDao.java | 2 +- .../dao/sql/oauth2/JpaOAuth2ParamsDao.java | 2 +- .../dao/sql/oauth2/JpaOAuth2RegistrationDao.java | 2 +- ...uth2ClientRegistrationTemplateRepository.java | 2 +- .../dao/sql/oauth2/OAuth2DomainRepository.java | 2 +- .../dao/sql/oauth2/OAuth2MobileRepository.java | 2 +- .../dao/sql/oauth2/OAuth2ParamsRepository.java | 2 +- .../sql/oauth2/OAuth2RegistrationRepository.java | 2 +- .../server/dao/sql/ota/JpaOtaPackageDao.java | 2 +- .../server/dao/sql/ota/JpaOtaPackageInfoDao.java | 2 +- .../dao/sql/ota/OtaPackageInfoRepository.java | 2 +- .../server/dao/sql/ota/OtaPackageRepository.java | 2 +- .../server/dao/sql/query/AlarmDataAdapter.java | 2 +- .../dao/sql/query/AlarmQueryRepository.java | 2 +- .../sql/query/DefaultAlarmQueryRepository.java | 2 +- .../sql/query/DefaultEntityQueryRepository.java | 2 +- .../dao/sql/query/DefaultQueryLogComponent.java | 2 +- .../server/dao/sql/query/EntityDataAdapter.java | 2 +- .../server/dao/sql/query/EntityKeyMapping.java | 2 +- .../dao/sql/query/EntityQueryRepository.java | 2 +- .../server/dao/sql/query/JpaEntityQueryDao.java | 2 +- .../server/dao/sql/query/QueryContext.java | 2 +- .../server/dao/sql/query/QueryLogComponent.java | 2 +- .../dao/sql/query/QuerySecurityContext.java | 2 +- .../server/dao/sql/queue/JpaQueueDao.java | 2 +- .../server/dao/sql/queue/QueueRepository.java | 2 +- .../server/dao/sql/relation/JpaRelationDao.java | 2 +- .../JpaRelationQueryExecutorService.java | 2 +- .../sql/relation/RelationInsertRepository.java | 2 +- .../dao/sql/relation/RelationRepository.java | 2 +- .../relation/SqlRelationInsertRepository.java | 2 +- .../dao/sql/resource/JpaTbResourceDao.java | 2 +- .../dao/sql/resource/JpaTbResourceInfoDao.java | 2 +- .../sql/resource/TbResourceInfoRepository.java | 2 +- .../dao/sql/resource/TbResourceRepository.java | 2 +- .../server/dao/sql/rpc/JpaRpcDao.java | 2 +- .../server/dao/sql/rpc/RpcRepository.java | 2 +- .../server/dao/sql/rule/JpaRuleChainDao.java | 2 +- .../server/dao/sql/rule/JpaRuleNodeDao.java | 2 +- .../server/dao/sql/rule/JpaRuleNodeStateDao.java | 2 +- .../server/dao/sql/rule/RuleChainRepository.java | 2 +- .../server/dao/sql/rule/RuleNodeRepository.java | 2 +- .../dao/sql/rule/RuleNodeStateRepository.java | 2 +- .../sql/settings/AdminSettingsRepository.java | 2 +- .../dao/sql/settings/JpaAdminSettingsDao.java | 2 +- .../server/dao/sql/tenant/JpaTenantDao.java | 2 +- .../dao/sql/tenant/JpaTenantProfileDao.java | 2 +- .../dao/sql/tenant/TenantProfileRepository.java | 2 +- .../server/dao/sql/tenant/TenantRepository.java | 2 +- .../sql/usagerecord/ApiUsageStateRepository.java | 2 +- .../dao/sql/usagerecord/JpaApiUsageStateDao.java | 2 +- .../dao/sql/user/JpaUserAuthSettingsDao.java | 2 +- .../dao/sql/user/JpaUserCredentialsDao.java | 2 +- .../server/dao/sql/user/JpaUserDao.java | 2 +- .../server/dao/sql/user/JpaUserSettingsDao.java | 2 +- .../dao/sql/user/UserAuthSettingsRepository.java | 2 +- .../dao/sql/user/UserCredentialsRepository.java | 2 +- .../server/dao/sql/user/UserRepository.java | 2 +- .../dao/sql/user/UserSettingsRepository.java | 2 +- .../server/dao/sql/widget/JpaWidgetTypeDao.java | 2 +- .../dao/sql/widget/JpaWidgetsBundleDao.java | 2 +- .../dao/sql/widget/WidgetTypeInfoRepository.java | 2 +- .../dao/sql/widget/WidgetTypeRepository.java | 2 +- .../dao/sql/widget/WidgetsBundleRepository.java | 2 +- .../widget/WidgetsBundleWidgetRepository.java | 2 +- .../AbstractChunkedAggregationTimeseriesDao.java | 2 +- .../dao/sqlts/AbstractSqlTimeseriesDao.java | 2 +- .../dao/sqlts/AggregationTimeseriesDao.java | 2 +- .../dao/sqlts/BaseAbstractSqlTimeseriesDao.java | 2 +- .../server/dao/sqlts/EntityContainer.java | 2 +- .../server/dao/sqlts/SqlTimeseriesLatestDao.java | 2 +- .../org/thingsboard/server/dao/sqlts/TsKey.java | 2 +- .../dictionary/TsKvDictionaryRepository.java | 2 +- .../sqlts/insert/AbstractInsertRepository.java | 2 +- .../dao/sqlts/insert/InsertTsRepository.java | 2 +- .../insert/latest/InsertLatestTsRepository.java | 2 +- .../latest/sql/SqlLatestInsertTsRepository.java | 2 +- .../sqlts/insert/sql/SqlInsertTsRepository.java | 2 +- .../insert/sql/SqlPartitioningRepository.java | 2 +- .../timescale/TimescaleInsertTsRepository.java | 2 +- .../sqlts/latest/SearchTsKvLatestRepository.java | 2 +- .../dao/sqlts/latest/TsKvLatestRepository.java | 2 +- .../dao/sqlts/sql/JpaSqlTimeseriesDao.java | 2 +- .../sqlts/timescale/AggregationRepository.java | 2 +- .../sqlts/timescale/TimescaleTimeseriesDao.java | 2 +- .../sqlts/timescale/TsKvTimescaleRepository.java | 2 +- .../server/dao/sqlts/ts/TsKvRepository.java | 2 +- .../dao/tenant/DefaultTbTenantProfileCache.java | 2 +- .../server/dao/tenant/TenantCaffeineCache.java | 2 +- .../thingsboard/server/dao/tenant/TenantDao.java | 2 +- .../server/dao/tenant/TenantEvictEvent.java | 2 +- .../dao/tenant/TenantExistsCaffeineCache.java | 2 +- .../dao/tenant/TenantExistsRedisCache.java | 2 +- .../server/dao/tenant/TenantProfileCacheKey.java | 2 +- .../dao/tenant/TenantProfileCaffeineCache.java | 2 +- .../server/dao/tenant/TenantProfileDao.java | 2 +- .../dao/tenant/TenantProfileEvictEvent.java | 2 +- .../dao/tenant/TenantProfileRedisCache.java | 2 +- .../dao/tenant/TenantProfileServiceImpl.java | 2 +- .../server/dao/tenant/TenantRedisCache.java | 2 +- .../server/dao/tenant/TenantServiceImpl.java | 2 +- .../AbstractCassandraBaseTimeseriesDao.java | 2 +- .../timeseries/AggregatePartitionsFunction.java | 2 +- .../dao/timeseries/BaseTimeseriesService.java | 2 +- .../timeseries/CassandraBaseTimeseriesDao.java | 2 +- .../CassandraBaseTimeseriesLatestDao.java | 2 +- .../timeseries/CassandraPartitionCacheKey.java | 2 +- .../timeseries/CassandraTsPartitionsCache.java | 2 +- .../dao/timeseries/NoSqlTsPartitionDate.java | 2 +- .../server/dao/timeseries/QueryCursor.java | 2 +- .../dao/timeseries/SimpleListenableFuture.java | 2 +- .../server/dao/timeseries/SqlPartition.java | 2 +- .../dao/timeseries/SqlTsPartitionDate.java | 2 +- .../server/dao/timeseries/TimeseriesDao.java | 2 +- .../dao/timeseries/TimeseriesLatestDao.java | 2 +- .../dao/timeseries/TsInsertExecutorType.java | 2 +- .../server/dao/timeseries/TsKvQueryCursor.java | 2 +- .../server/dao/usage/BasicUsageInfoService.java | 2 +- .../server/dao/usagerecord/ApiUsageStateDao.java | 2 +- .../usagerecord/ApiUsageStateServiceImpl.java | 2 +- .../dao/usagerecord/DefaultApiLimitService.java | 2 +- .../server/dao/user/UserAuthSettingsDao.java | 2 +- .../server/dao/user/UserCredentialsDao.java | 2 +- .../org/thingsboard/server/dao/user/UserDao.java | 2 +- .../server/dao/user/UserServiceImpl.java | 2 +- .../dao/user/UserSettingsCaffeineCache.java | 2 +- .../server/dao/user/UserSettingsDao.java | 2 +- .../server/dao/user/UserSettingsEvictEvent.java | 2 +- .../server/dao/user/UserSettingsRedisCache.java | 2 +- .../server/dao/user/UserSettingsServiceImpl.java | 2 +- .../dao/util/AbstractBufferedRateExecutor.java | 2 +- .../server/dao/util/AsyncRateLimiter.java | 2 +- .../server/dao/util/AsyncTaskContext.java | 2 +- .../server/dao/util/BufferedRateExecutor.java | 2 +- .../dao/util/BufferedRateExecutorStats.java | 2 +- .../server/dao/util/DeviceConnectivityUtil.java | 2 +- .../thingsboard/server/dao/util/ImageUtils.java | 2 +- .../server/dao/util/JsonNodeProcessingTask.java | 2 +- .../server/dao/util/JsonPathProcessingTask.java | 2 +- .../org/thingsboard/server/dao/util/KvUtils.java | 2 +- .../dao/util/TenantRateLimitException.java | 2 +- .../dao/util/limits/DefaultRateLimitService.java | 2 +- .../server/dao/util/limits/RateLimitService.java | 2 +- .../mapping/AbstractJsonSqlTypeDescriptor.java | 2 +- .../mapping/JsonBinarySqlTypeDescriptor.java | 2 +- .../server/dao/util/mapping/JsonBinaryType.java | 2 +- .../mapping/JsonStringSqlTypeDescriptor.java | 2 +- .../server/dao/util/mapping/JsonStringType.java | 2 +- .../dao/util/mapping/JsonTypeDescriptor.java | 2 +- .../server/dao/widget/WidgetTypeDao.java | 2 +- .../server/dao/widget/WidgetTypeServiceImpl.java | 2 +- .../server/dao/widget/WidgetsBundleDao.java | 2 +- .../dao/widget/WidgetsBundleServiceImpl.java | 2 +- .../main/resources/cassandra/schema-keyspace.cql | 2 +- .../resources/cassandra/schema-ts-latest.cql | 2 +- dao/src/main/resources/cassandra/schema-ts.cql | 2 +- .../sql/schema-entities-idx-psql-addon.sql | 2 +- .../main/resources/sql/schema-entities-idx.sql | 2 +- dao/src/main/resources/sql/schema-entities.sql | 2 +- dao/src/main/resources/sql/schema-timescale.sql | 2 +- dao/src/main/resources/sql/schema-ts-psql.sql | 2 +- .../resources/sql/schema-views-and-functions.sql | 2 +- dao/src/main/resources/xss-policy.xml | 2 +- .../server/dao/AbstractDaoServiceTest.java | 2 +- .../server/dao/AbstractJpaDaoTest.java | 2 +- .../server/dao/AbstractNoSqlContainer.java | 3 +-- .../server/dao/AbstractRedisContainer.java | 2 +- .../server/dao/NoSqlDaoServiceTestSuite.java | 2 +- .../server/dao/PostgreSqlInitializer.java | 2 +- .../server/dao/RedisSqlTestSuite.java | 2 +- .../server/dao/TimescaleDaoServiceTestSuite.java | 2 +- .../server/dao/TimescaleSqlInitializer.java | 2 +- .../dao/eventsourcing/DeleteEntityEventTest.java | 2 +- .../dao/nosql/CassandraPartitionsCacheTest.java | 2 +- .../server/dao/service/AbstractServiceTest.java | 2 +- .../dao/service/AdminSettingsServiceTest.java | 2 +- .../dao/service/AlarmCommentServiceTest.java | 2 +- .../server/dao/service/AlarmServiceTest.java | 2 +- .../dao/service/ApiUsageStateServiceTest.java | 2 +- .../dao/service/AssetProfileServiceTest.java | 2 +- .../server/dao/service/AssetServiceTest.java | 2 +- .../dao/service/ConstraintValidatorTest.java | 2 +- .../server/dao/service/CustomerServiceTest.java | 2 +- .../server/dao/service/DaoNoSqlTest.java | 2 +- .../server/dao/service/DaoSqlTest.java | 2 +- .../server/dao/service/DaoTimescaleTest.java | 2 +- .../server/dao/service/DashboardServiceTest.java | 2 +- .../server/dao/service/DataValidatorTest.java | 2 +- .../dao/service/DeviceCredentialsCacheTest.java | 2 +- .../service/DeviceCredentialsServiceTest.java | 2 +- .../dao/service/DeviceProfileServiceTest.java | 2 +- .../server/dao/service/DeviceServiceTest.java | 2 +- .../server/dao/service/EdgeEventServiceTest.java | 2 +- .../server/dao/service/EdgeServiceTest.java | 2 +- .../dao/service/EntityServiceRegistryTest.java | 2 +- .../server/dao/service/EntityServiceTest.java | 2 +- .../server/dao/service/NoXssValidatorTest.java | 2 +- .../service/OAuth2ConfigTemplateServiceTest.java | 2 +- .../server/dao/service/OAuth2ServiceTest.java | 2 +- .../dao/service/OtaPackageServiceTest.java | 2 +- .../server/dao/service/QueueServiceTest.java | 2 +- .../server/dao/service/RelationCacheTest.java | 2 +- .../server/dao/service/RelationServiceTest.java | 2 +- .../server/dao/service/RuleChainServiceTest.java | 2 +- .../dao/service/TbCacheSerializationTest.java | 2 +- .../dao/service/TenantProfileServiceTest.java | 2 +- .../server/dao/service/TenantServiceTest.java | 2 +- .../server/dao/service/UserServiceTest.java | 2 +- .../dao/service/WidgetTypeServiceTest.java | 2 +- .../dao/service/WidgetsBundleServiceTest.java | 2 +- .../attributes/BaseAttributesServiceTest.java | 2 +- .../attributes/sql/AttributesServiceSqlTest.java | 2 +- .../dao/service/event/BaseEventServiceTest.java | 2 +- .../service/event/sql/EventServiceSqlTest.java | 2 +- .../install/sql/EntitiesSchemaSqlTest.java | 2 +- .../timeseries/BaseTimeseriesServiceTest.java | 2 +- .../nosql/TimeseriesServiceNoSqlTest.java | 2 +- .../nosql/TimeseriesServiceTimescaleTest.java | 2 +- .../timeseries/sql/TimeseriesServiceSqlTest.java | 2 +- .../AdminSettingsDataValidatorTest.java | 2 +- .../validator/AlarmDataValidatorTest.java | 2 +- .../validator/AssetDataValidatorTest.java | 2 +- .../validator/AssetProfileDataValidatorTest.java | 2 +- .../BaseOtaPackageDataValidatorTest.java | 2 +- .../ComponentDescriptorDataValidatorTest.java | 2 +- .../validator/CustomerDataValidatorTest.java | 2 +- .../validator/DashboardDataValidatorTest.java | 2 +- .../validator/DeviceDataValidatorTest.java | 2 +- .../DeviceProfileDataValidatorTest.java | 2 +- .../service/validator/EdgeDataValidatorTest.java | 2 +- .../validator/EntityViewDataValidatorTest.java | 2 +- .../validator/ResourceDataValidatorTest.java | 2 +- .../validator/RuleChainDataValidatorTest.java | 2 +- .../validator/TenantDataValidatorTest.java | 2 +- .../TenantProfileDataValidatorTest.java | 2 +- .../validator/WidgetTypeDataValidatorTest.java | 2 +- .../WidgetsBundleDataValidatorTest.java | 2 +- .../dao/sql/alarm/JpaAlarmCommentDaoTest.java | 2 +- .../server/dao/sql/alarm/JpaAlarmDaoTest.java | 2 +- .../server/dao/sql/asset/JpaAssetDaoTest.java | 2 +- .../server/dao/sql/audit/JpaAuditLogDaoTest.java | 2 +- .../JpaBaseComponentDescriptorDaoTest.java | 2 +- .../dao/sql/customer/JpaCustomerDaoTest.java | 2 +- .../sql/dashboard/JpaDashboardInfoDaoTest.java | 2 +- .../sql/device/JpaDeviceCredentialsDaoTest.java | 2 +- .../server/dao/sql/device/JpaDeviceDaoTest.java | 2 +- .../dao/sql/event/JpaBaseEventDaoTest.java | 2 +- .../query/DefaultEntityQueryRepositoryTest.java | 2 +- .../sql/query/DefaultQueryLogComponentTest.java | 2 +- .../dao/sql/query/EntityDataAdapterTest.java | 2 +- .../dao/sql/query/EntityKeyMappingTest.java | 2 +- .../server/dao/sql/rule/JpaRuleNodeDaoTest.java | 2 +- .../server/dao/sql/tenant/JpaTenantDaoTest.java | 2 +- .../dao/sql/user/JpaUserCredentialsDaoTest.java | 2 +- .../server/dao/sql/user/JpaUserDaoTest.java | 2 +- .../dao/sql/user/JpaUserSettingsDaoTest.java | 2 +- .../dao/sql/widget/JpaWidgetTypeDaoTest.java | 2 +- .../dao/sql/widget/JpaWidgetsBundleDaoTest.java | 2 +- ...tractChunkedAggregationTimeseriesDaoTest.java | 2 +- ...eriesDaoPartitioningDaysAlwaysExistsTest.java | 2 +- ...riesDaoPartitioningHoursAlwaysExistsTest.java | 2 +- ...aoPartitioningIndefiniteAlwaysExistsTest.java | 2 +- ...esDaoPartitioningMinutesAlwaysExistsTest.java | 2 +- ...iesDaoPartitioningMonthsAlwaysExistsTest.java | 2 +- ...riesDaoPartitioningYearsAlwaysExistsTest.java | 2 +- .../dao/util/DeviceConnectivityUtilTest.java | 2 +- docker/compose-utils.sh | 2 +- docker/docker-check-log-folders.sh | 2 +- docker/docker-compose.aws-sqs.yml | 2 +- docker/docker-compose.cassandra.volumes.yml | 2 +- docker/docker-compose.confluent.yml | 2 +- docker/docker-compose.hybrid.yml | 2 +- docker/docker-compose.kafka.yml | 2 +- docker/docker-compose.postgres.volumes.yml | 2 +- docker/docker-compose.postgres.yml | 2 +- docker/docker-compose.prometheus-grafana.yml | 2 +- docker/docker-compose.pubsub.yml | 2 +- docker/docker-compose.rabbitmq.yml | 2 +- docker/docker-compose.redis-cluster.volumes.yml | 2 +- docker/docker-compose.redis-cluster.yml | 2 +- docker/docker-compose.redis-sentinel.volumes.yml | 2 +- docker/docker-compose.redis-sentinel.yml | 2 +- docker/docker-compose.redis.volumes.yml | 2 +- docker/docker-compose.redis.yml | 2 +- docker/docker-compose.service-bus.yml | 2 +- docker/docker-compose.volumes.yml | 2 +- docker/docker-compose.yml | 2 +- docker/docker-create-log-folders.sh | 2 +- docker/docker-install-tb.sh | 2 +- docker/docker-remove-services.sh | 2 +- docker/docker-start-services.sh | 2 +- docker/docker-stop-services.sh | 2 +- docker/docker-update-service.sh | 2 +- docker/docker-upgrade-tb.sh | 2 +- .../provisioning/dashboards/dashboard.yml | 2 +- .../provisioning/datasources/datasource.yml | 2 +- docker/monitoring/prometheus/prometheus.yml | 2 +- docker/tb-transports/coap/conf/logback.xml | 2 +- .../coap/conf/tb-coap-transport.conf | 2 +- docker/tb-transports/http/conf/logback.xml | 2 +- .../http/conf/tb-http-transport.conf | 2 +- docker/tb-transports/lwm2m/conf/logback.xml | 2 +- .../lwm2m/conf/tb-lwm2m-transport.conf | 2 +- docker/tb-transports/mqtt/conf/logback.xml | 2 +- .../mqtt/conf/tb-mqtt-transport.conf | 2 +- docker/tb-transports/snmp/conf/logback.xml | 2 +- .../snmp/conf/tb-snmp-transport.conf | 2 +- docker/tb-vc-executor/conf/logback.xml | 2 +- docker/tb-vc-executor/conf/tb-vc-executor.conf | 2 +- license-header-template.txt | 2 +- monitoring/pom.xml | 2 +- monitoring/src/main/conf/logback.xml | 2 +- monitoring/src/main/conf/tb-monitoring.conf | 2 +- .../ThingsboardMonitoringApplication.java | 2 +- .../monitoring/client/Lwm2mClient.java | 2 +- .../thingsboard/monitoring/client/TbClient.java | 2 +- .../thingsboard/monitoring/client/WsClient.java | 2 +- .../monitoring/client/WsClientFactory.java | 2 +- .../monitoring/config/MonitoringConfig.java | 2 +- .../monitoring/config/MonitoringTarget.java | 2 +- .../transport/CoapTransportMonitoringConfig.java | 2 +- .../config/transport/DeviceConfig.java | 2 +- .../transport/HttpTransportMonitoringConfig.java | 2 +- .../Lwm2mTransportMonitoringConfig.java | 2 +- .../transport/MqttTransportMonitoringConfig.java | 2 +- .../config/transport/TransportInfo.java | 2 +- .../transport/TransportMonitoringConfig.java | 2 +- .../transport/TransportMonitoringTarget.java | 2 +- .../config/transport/TransportType.java | 2 +- .../thingsboard/monitoring/data/Latencies.java | 2 +- .../org/thingsboard/monitoring/data/Latency.java | 2 +- .../monitoring/data/MonitoredServiceKey.java | 2 +- .../monitoring/data/ServiceFailureException.java | 2 +- .../monitoring/data/cmd/CmdsWrapper.java | 2 +- .../monitoring/data/cmd/EntityDataCmd.java | 2 +- .../monitoring/data/cmd/EntityDataUpdate.java | 2 +- .../monitoring/data/cmd/LatestValueCmd.java | 2 +- .../notification/HighLatencyNotification.java | 2 +- .../data/notification/Notification.java | 2 +- .../notification/ServiceFailureNotification.java | 2 +- .../ServiceRecoveryNotification.java | 2 +- .../notification/NotificationService.java | 2 +- .../channels/NotificationChannel.java | 2 +- .../channels/impl/SlackNotificationChannel.java | 2 +- .../monitoring/service/BaseHealthChecker.java | 2 +- .../service/BaseMonitoringService.java | 2 +- .../monitoring/service/MonitoringReporter.java | 2 +- .../transport/TransportHealthChecker.java | 2 +- .../transport/TransportsMonitoringService.java | 2 +- .../impl/CoapTransportHealthChecker.java | 2 +- .../impl/HttpTransportHealthChecker.java | 2 +- .../impl/Lwm2mTransportHealthChecker.java | 2 +- .../impl/MqttTransportHealthChecker.java | 2 +- .../monitoring/util/ResourceUtils.java | 2 +- .../thingsboard/monitoring/util/TbStopWatch.java | 2 +- monitoring/src/main/resources/logback.xml | 2 +- monitoring/src/main/resources/lwm2m/models/0.xml | 2 +- monitoring/src/main/resources/lwm2m/models/1.xml | 2 +- monitoring/src/main/resources/lwm2m/models/2.xml | 2 +- .../main/resources/lwm2m/models/test-model.xml | 2 +- monitoring/src/main/resources/tb-monitoring.yml | 2 +- msa/black-box-tests/pom.xml | 2 +- .../server/msa/AbstractContainerTest.java | 2 +- .../server/msa/ContainerTestSuite.java | 2 +- .../server/msa/DisableUIListeners.java | 2 +- .../server/msa/DockerComposeExecutor.java | 2 +- .../server/msa/SeleniumRemoteWebDriverTest.java | 2 +- .../thingsboard/server/msa/TestCoapClient.java | 2 +- .../server/msa/TestCoapClientCallback.java | 2 +- .../org/thingsboard/server/msa/TestListener.java | 2 +- .../thingsboard/server/msa/TestProperties.java | 2 +- .../thingsboard/server/msa/TestRestClient.java | 2 +- .../server/msa/ThingsBoardDbInstaller.java | 2 +- .../org/thingsboard/server/msa/WsClient.java | 2 +- .../server/msa/connectivity/CoapClientTest.java | 2 +- .../server/msa/connectivity/HttpClientTest.java | 2 +- .../server/msa/connectivity/MqttClientTest.java | 2 +- .../msa/connectivity/MqttGatewayClientTest.java | 2 +- .../server/msa/mapper/AttributesResponse.java | 2 +- .../server/msa/mapper/WsTelemetryResponse.java | 2 +- .../server/msa/prototypes/DevicePrototypes.java | 2 +- .../server/msa/ui/base/AbstractBasePage.java | 2 +- .../msa/ui/base/AbstractDriverBaseTest.java | 2 +- .../server/msa/ui/listeners/RetryAnalyzer.java | 2 +- .../msa/ui/listeners/RetryTestListener.java | 2 +- .../ui/pages/AlarmDetailsEntityTabElements.java | 2 +- .../ui/pages/AlarmDetailsEntityTabHelper.java | 2 +- .../msa/ui/pages/AlarmDetailsViewElements.java | 2 +- .../msa/ui/pages/AlarmDetailsViewHelper.java | 2 +- .../server/msa/ui/pages/AlarmWidgetElements.java | 2 +- .../server/msa/ui/pages/AssetPageElements.java | 2 +- .../server/msa/ui/pages/AssetPageHelper.java | 2 +- .../msa/ui/pages/CreateWidgetPopupElements.java | 2 +- .../msa/ui/pages/CreateWidgetPopupHelper.java | 2 +- .../msa/ui/pages/CustomerPageElements.java | 2 +- .../server/msa/ui/pages/CustomerPageHelper.java | 2 +- .../msa/ui/pages/DashboardPageElements.java | 2 +- .../server/msa/ui/pages/DashboardPageHelper.java | 2 +- .../server/msa/ui/pages/DevicePageElements.java | 2 +- .../server/msa/ui/pages/DevicePageHelper.java | 2 +- .../msa/ui/pages/EntityViewPageElements.java | 2 +- .../msa/ui/pages/EntityViewPageHelper.java | 2 +- .../server/msa/ui/pages/LoginPageElements.java | 2 +- .../server/msa/ui/pages/LoginPageHelper.java | 2 +- .../msa/ui/pages/OpenRuleChainPageElements.java | 2 +- .../msa/ui/pages/OpenRuleChainPageHelper.java | 2 +- .../server/msa/ui/pages/OtherPageElements.java | 2 +- .../msa/ui/pages/OtherPageElementsHelper.java | 2 +- .../msa/ui/pages/ProfilesPageElements.java | 2 +- .../server/msa/ui/pages/ProfilesPageHelper.java | 2 +- .../msa/ui/pages/RuleChainsPageElements.java | 2 +- .../msa/ui/pages/RuleChainsPageHelper.java | 2 +- .../msa/ui/pages/SideBarMenuViewElements.java | 2 +- .../msa/ui/pages/SideBarMenuViewHelper.java | 2 +- .../msa/ui/tabs/AssignDeviceTabElements.java | 2 +- .../msa/ui/tabs/AssignDeviceTabHelper.java | 2 +- .../msa/ui/tabs/CreateDeviceTabElements.java | 2 +- .../msa/ui/tabs/CreateDeviceTabHelper.java | 2 +- .../tests/alarmassignee/AbstractAssignTest.java | 2 +- .../AssignDetailsTabAssignTest.java | 2 +- .../AssignDetailsTabFromCustomerAssignTest.java | 2 +- .../alarmassignee/AssignFromAlarmWidgetTest.java | 2 +- .../AssetProfileEditMenuTest.java | 2 +- .../CreateAssetProfileImportTest.java | 2 +- .../CreateAssetProfileTest.java | 2 +- .../DeleteAssetProfileTest.java | 2 +- .../DeleteSeveralAssetProfilesTest.java | 2 +- .../MakeAssetProfileDefaultTest.java | 2 +- .../SearchAssetProfileTest.java | 2 +- .../tests/assetProfileSmoke/SortByNameTest.java | 2 +- .../tests/customerSmoke/CreateCustomerTest.java | 2 +- .../customerSmoke/CustomerEditMenuTest.java | 2 +- .../tests/customerSmoke/DeleteCustomerTest.java | 2 +- .../customerSmoke/DeleteSeveralCustomerTest.java | 2 +- .../customerSmoke/ManageCustomersAssetsTest.java | 2 +- .../ManageCustomersDashboardsTest.java | 2 +- .../ManageCustomersDevicesTest.java | 2 +- .../customerSmoke/ManageCustomersEdgesTest.java | 2 +- .../customerSmoke/ManageCustomersUsersTest.java | 2 +- .../tests/customerSmoke/SearchCustomerTest.java | 2 +- .../ui/tests/customerSmoke/SortByNameTest.java | 2 +- .../CreateDeviceProfileImportTest.java | 2 +- .../CreateDeviceProfileTest.java | 2 +- .../DeleteDeviceProfileTest.java | 2 +- .../DeleteSeveralDeviceProfilesTest.java | 2 +- .../DeviceProfileEditMenuTest.java | 2 +- .../MakeDeviceProfileDefaultTest.java | 2 +- .../SearchDeviceProfileTest.java | 2 +- .../tests/deviceProfileSmoke/SortByNameTest.java | 2 +- .../tests/devicessmoke/AbstractDeviceTest.java | 2 +- .../tests/devicessmoke/AssignToCustomerTest.java | 2 +- .../ui/tests/devicessmoke/CreateDeviceTest.java | 2 +- .../ui/tests/devicessmoke/DeleteDeviceTest.java | 2 +- .../devicessmoke/DeleteSeveralDevicesTest.java | 2 +- .../ui/tests/devicessmoke/DeviceFilterTest.java | 2 +- .../ui/tests/devicessmoke/EditDeviceTest.java | 2 +- .../devicessmoke/MakeDevicePrivateTest.java | 2 +- .../tests/devicessmoke/MakeDevicePublicTest.java | 2 +- .../rulechainssmoke/AbstractRuleChainTest.java | 2 +- .../CreateRuleChainImportTest.java | 2 +- .../rulechainssmoke/CreateRuleChainTest.java | 2 +- .../rulechainssmoke/DeleteRuleChainTest.java | 2 +- .../DeleteSeveralRuleChainsTest.java | 2 +- .../rulechainssmoke/MakeRuleChainRootTest.java | 2 +- .../tests/rulechainssmoke/OpenRuleChainTest.java | 2 +- .../rulechainssmoke/RuleChainEditMenuTest.java | 2 +- .../rulechainssmoke/SearchRuleChainTest.java | 2 +- .../ui/tests/rulechainssmoke/SortByNameTest.java | 2 +- .../ui/tests/rulechainssmoke/SortByTimeTest.java | 2 +- .../thingsboard/server/msa/ui/utils/Const.java | 2 +- .../msa/ui/utils/DataProviderCredential.java | 2 +- .../server/msa/ui/utils/EntityPrototypes.java | 2 +- .../src/test/resources/alarmAssignee.xml | 2 +- msa/black-box-tests/src/test/resources/all.xml | 2 +- .../src/test/resources/connectivity.xml | 2 +- .../docker-compose.hybrid-test-extras.yml | 2 +- .../docker-compose.postgres-test-extras.yml | 2 +- .../resources/docker-compose.rabbitmq-server.yml | 2 +- .../src/test/resources/docker-selenium.yml | 2 +- .../src/test/resources/forImport.txt | 2 +- .../src/test/resources/logback.xml | 2 +- .../src/test/resources/smokeDevices.xml | 2 +- .../src/test/resources/smokesCustomer.xml | 2 +- .../src/test/resources/smokesProfiles.xml | 2 +- .../src/test/resources/smokesRuleChain.xml | 2 +- .../src/test/resources/tb-node/conf/logback.xml | 2 +- .../tb-transports/coap/conf/logback.xml | 2 +- .../tb-transports/http/conf/logback.xml | 2 +- .../tb-transports/mqtt/conf/logback.xml | 2 +- .../src/test/resources/uiTests.xml | 2 +- msa/js-executor/api/httpServer.ts | 2 +- msa/js-executor/api/jsExecutor.models.ts | 2 +- msa/js-executor/api/jsExecutor.ts | 2 +- msa/js-executor/api/jsInvokeMessageProcessor.ts | 2 +- msa/js-executor/api/utils.ts | 2 +- .../config/custom-environment-variables.yml | 2 +- msa/js-executor/config/default.yml | 2 +- msa/js-executor/config/logger.ts | 2 +- msa/js-executor/config/tb-js-executor.conf | 2 +- msa/js-executor/docker/Dockerfile | 2 +- msa/js-executor/docker/start-js-executor.sh | 2 +- msa/js-executor/install.js | 2 +- msa/js-executor/pom.xml | 2 +- msa/js-executor/queue/awsSqsTemplate.ts | 2 +- msa/js-executor/queue/kafkaTemplate.ts | 2 +- msa/js-executor/queue/pubSubTemplate.ts | 2 +- msa/js-executor/queue/queue.models.ts | 2 +- msa/js-executor/queue/rabbitmqTemplate.ts | 2 +- msa/js-executor/queue/serviceBusTemplate.ts | 2 +- msa/js-executor/server.ts | 2 +- msa/monitoring/docker/Dockerfile | 2 +- msa/monitoring/docker/start-tb-monitoring.sh | 2 +- msa/monitoring/pom.xml | 2 +- msa/pom.xml | 2 +- msa/tb-node/docker/Dockerfile | 2 +- msa/tb-node/docker/start-tb-node.sh | 2 +- msa/tb-node/pom.xml | 2 +- msa/tb/docker-cassandra/Dockerfile | 2 +- msa/tb/docker-cassandra/start-db.sh | 2 +- msa/tb/docker-cassandra/stop-db.sh | 2 +- msa/tb/docker-postgres/Dockerfile | 2 +- msa/tb/docker-postgres/start-db.sh | 2 +- msa/tb/docker-postgres/stop-db.sh | 2 +- msa/tb/docker/install-tb.sh | 2 +- msa/tb/docker/logback.xml | 2 +- msa/tb/docker/start-tb.sh | 2 +- msa/tb/docker/thingsboard.conf | 2 +- msa/tb/docker/upgrade-tb.sh | 2 +- msa/tb/pom.xml | 2 +- msa/transport/coap/docker/Dockerfile | 2 +- .../coap/docker/start-tb-coap-transport.sh | 2 +- msa/transport/coap/pom.xml | 2 +- msa/transport/http/docker/Dockerfile | 2 +- .../http/docker/start-tb-http-transport.sh | 2 +- msa/transport/http/pom.xml | 2 +- msa/transport/lwm2m/docker/Dockerfile | 2 +- .../lwm2m/docker/start-tb-lwm2m-transport.sh | 2 +- msa/transport/lwm2m/pom.xml | 2 +- msa/transport/mqtt/docker/Dockerfile | 2 +- .../mqtt/docker/start-tb-mqtt-transport.sh | 2 +- msa/transport/mqtt/pom.xml | 2 +- msa/transport/pom.xml | 2 +- msa/transport/snmp/docker/Dockerfile | 2 +- .../snmp/docker/start-tb-snmp-transport.sh | 2 +- msa/transport/snmp/pom.xml | 2 +- msa/vc-executor-docker/docker/Dockerfile | 2 +- .../docker/start-tb-vc-executor.sh | 2 +- msa/vc-executor-docker/pom.xml | 2 +- msa/vc-executor/pom.xml | 2 +- msa/vc-executor/src/main/conf/logback.xml | 2 +- .../src/main/conf/tb-vc-executor.conf | 2 +- ...gsboardVersionControlExecutorApplication.java | 2 +- .../VersionControlQueueRoutingInfoService.java | 2 +- .../VersionControlTenantRoutingInfoService.java | 2 +- msa/vc-executor/src/main/resources/logback.xml | 2 +- .../src/main/resources/tb-vc-executor.yml | 2 +- .../config/custom-environment-variables.yml | 2 +- msa/web-ui/config/default.yml | 2 +- msa/web-ui/config/logger.ts | 2 +- msa/web-ui/config/tb-web-ui.conf | 2 +- msa/web-ui/docker/Dockerfile | 2 +- msa/web-ui/docker/start-web-ui.sh | 2 +- msa/web-ui/install.js | 2 +- msa/web-ui/pom.xml | 2 +- msa/web-ui/server.ts | 2 +- netty-mqtt/pom.xml | 2 +- .../thingsboard/mqtt/ChannelClosedException.java | 2 +- .../org/thingsboard/mqtt/MqttChannelHandler.java | 2 +- .../java/org/thingsboard/mqtt/MqttClient.java | 2 +- .../org/thingsboard/mqtt/MqttClientCallback.java | 2 +- .../org/thingsboard/mqtt/MqttClientConfig.java | 2 +- .../org/thingsboard/mqtt/MqttClientImpl.java | 2 +- .../org/thingsboard/mqtt/MqttConnectResult.java | 2 +- .../java/org/thingsboard/mqtt/MqttHandler.java | 2 +- .../mqtt/MqttIncomingQos2Publish.java | 2 +- .../java/org/thingsboard/mqtt/MqttLastWill.java | 2 +- .../org/thingsboard/mqtt/MqttPendingPublish.java | 2 +- .../mqtt/MqttPendingSubscription.java | 2 +- .../mqtt/MqttPendingUnsubscription.java | 2 +- .../org/thingsboard/mqtt/MqttPingHandler.java | 2 +- .../org/thingsboard/mqtt/MqttSubscription.java | 2 +- .../org/thingsboard/mqtt/PendingOperation.java | 2 +- .../thingsboard/mqtt/RetransmissionHandler.java | 2 +- .../thingsboard/mqtt/MqttPingHandlerTest.java | 2 +- .../mqtt/integration/IntegrationTestSuite.java | 2 +- .../mqtt/integration/MqttIntegrationTest.java | 2 +- .../mqtt/integration/server/MqttServer.java | 2 +- .../integration/server/MqttTransportHandler.java | 2 +- packaging/java/assembly/windows.xml | 2 +- packaging/java/build.gradle | 2 +- packaging/java/scripts/install/install.sh | 2 +- packaging/java/scripts/install/install_dev_db.sh | 2 +- packaging/java/scripts/install/logback.xml | 2 +- packaging/java/scripts/install/upgrade.sh | 2 +- packaging/java/scripts/install/upgrade_dev_db.sh | 2 +- packaging/js/assembly/windows.xml | 2 +- packaging/js/build.gradle | 2 +- pom.xml | 2 +- rest-client/pom.xml | 2 +- .../org/thingsboard/rest/client/RestClient.java | 2 +- .../rest/client/utils/RestJsonConverter.java | 2 +- rest-client/src/main/resources/logback.xml | 2 +- rule-engine/pom.xml | 2 +- rule-engine/rule-engine-api/pom.xml | 2 +- .../rule/engine/api/EmptyNodeConfiguration.java | 2 +- .../thingsboard/rule/engine/api/MailService.java | 2 +- .../rule/engine/api/NodeConfiguration.java | 2 +- .../rule/engine/api/NodeDefinition.java | 2 +- .../rule/engine/api/NotificationCenter.java | 2 +- .../rule/engine/api/RuleEngineAlarmService.java | 2 +- .../api/RuleEngineApiUsageStateService.java | 2 +- .../engine/api/RuleEngineAssetProfileCache.java | 2 +- .../engine/api/RuleEngineDeviceProfileCache.java | 2 +- .../engine/api/RuleEngineDeviceRpcRequest.java | 2 +- .../engine/api/RuleEngineDeviceRpcResponse.java | 2 +- .../rule/engine/api/RuleEngineRpcService.java | 2 +- .../engine/api/RuleEngineTelemetryService.java | 2 +- .../thingsboard/rule/engine/api/RuleNode.java | 2 +- .../rule/engine/api/ScriptEngine.java | 2 +- .../thingsboard/rule/engine/api/SmsService.java | 2 +- .../thingsboard/rule/engine/api/TbContext.java | 2 +- .../org/thingsboard/rule/engine/api/TbEmail.java | 2 +- .../org/thingsboard/rule/engine/api/TbNode.java | 2 +- .../rule/engine/api/TbNodeConfiguration.java | 2 +- .../rule/engine/api/TbNodeException.java | 2 +- .../thingsboard/rule/engine/api/TbNodeState.java | 2 +- .../rule/engine/api/slack/SlackService.java | 2 +- .../rule/engine/api/sms/SmsSender.java | 2 +- .../rule/engine/api/sms/SmsSenderFactory.java | 2 +- .../engine/api/sms/exception/SmsException.java | 2 +- .../api/sms/exception/SmsParseException.java | 2 +- .../api/sms/exception/SmsSendException.java | 2 +- .../rule/engine/api/util/TbNodeUtils.java | 2 +- .../rule/engine/api/util/TbNodeUtilsTest.java | 2 +- rule-engine/rule-engine-components/pom.xml | 2 +- .../rule/engine/action/TbAbstractAlarmNode.java | 2 +- .../action/TbAbstractAlarmNodeConfiguration.java | 2 +- .../action/TbAbstractCustomerActionNode.java | 2 +- ...bAbstractCustomerActionNodeConfiguration.java | 2 +- .../action/TbAbstractRelationActionNode.java | 2 +- ...bAbstractRelationActionNodeConfiguration.java | 2 +- .../rule/engine/action/TbAlarmResult.java | 2 +- .../engine/action/TbAssignToCustomerNode.java | 2 +- .../TbAssignToCustomerNodeConfiguration.java | 2 +- .../rule/engine/action/TbClearAlarmNode.java | 2 +- .../action/TbClearAlarmNodeConfiguration.java | 2 +- .../action/TbCopyAttributesToEntityViewNode.java | 2 +- .../rule/engine/action/TbCreateAlarmNode.java | 2 +- .../action/TbCreateAlarmNodeConfiguration.java | 2 +- .../rule/engine/action/TbCreateRelationNode.java | 2 +- .../TbCreateRelationNodeConfiguration.java | 2 +- .../rule/engine/action/TbDeleteRelationNode.java | 2 +- .../TbDeleteRelationNodeConfiguration.java | 2 +- .../rule/engine/action/TbLogNode.java | 2 +- .../engine/action/TbLogNodeConfiguration.java | 2 +- .../rule/engine/action/TbMsgCountNode.java | 2 +- .../action/TbMsgCountNodeConfiguration.java | 2 +- .../action/TbSaveToCustomCassandraTableNode.java | 2 +- ...eToCustomCassandraTableNodeConfiguration.java | 2 +- .../action/TbUnassignFromCustomerNode.java | 2 +- .../TbUnassignFromCustomerNodeConfiguration.java | 2 +- .../rule/engine/aws/sns/TbSnsNode.java | 2 +- .../engine/aws/sns/TbSnsNodeConfiguration.java | 2 +- .../rule/engine/aws/sqs/TbSqsNode.java | 2 +- .../engine/aws/sqs/TbSqsNodeConfiguration.java | 2 +- .../engine/credentials/AnonymousCredentials.java | 2 +- .../engine/credentials/BasicCredentials.java | 2 +- .../engine/credentials/CertPemCredentials.java | 2 +- .../engine/credentials/ClientCredentials.java | 2 +- .../rule/engine/credentials/CredentialsType.java | 2 +- .../rule/engine/data/DeviceRelationsQuery.java | 2 +- .../rule/engine/data/RelationsQuery.java | 2 +- .../rule/engine/debug/TbMsgGeneratorNode.java | 2 +- .../debug/TbMsgGeneratorNodeConfiguration.java | 2 +- .../engine/deduplication/DeduplicationData.java | 2 +- .../engine/deduplication/DeduplicationId.java | 2 +- .../deduplication/DeduplicationStrategy.java | 2 +- .../deduplication/TbMsgDeduplicationNode.java | 2 +- .../TbMsgDeduplicationNodeConfiguration.java | 2 +- .../rule/engine/delay/TbMsgDelayNode.java | 2 +- .../delay/TbMsgDelayNodeConfiguration.java | 2 +- .../rule/engine/edge/AbstractTbMsgPushNode.java | 2 +- .../edge/BaseTbMsgPushNodeConfiguration.java | 2 +- .../rule/engine/edge/TbMsgPushToCloudNode.java | 2 +- .../edge/TbMsgPushToCloudNodeConfiguration.java | 2 +- .../rule/engine/edge/TbMsgPushToEdgeNode.java | 2 +- .../edge/TbMsgPushToEdgeNodeConfiguration.java | 2 +- .../engine/external/TbAbstractExternalNode.java | 2 +- .../engine/filter/TbAbstractTypeSwitchNode.java | 2 +- .../engine/filter/TbAssetTypeSwitchNode.java | 2 +- .../engine/filter/TbCheckAlarmStatusNode.java | 2 +- .../filter/TbCheckAlarmStatusNodeConfig.java | 2 +- .../rule/engine/filter/TbCheckMessageNode.java | 2 +- .../filter/TbCheckMessageNodeConfiguration.java | 2 +- .../rule/engine/filter/TbCheckRelationNode.java | 2 +- .../filter/TbCheckRelationNodeConfiguration.java | 2 +- .../engine/filter/TbDeviceTypeSwitchNode.java | 2 +- .../rule/engine/filter/TbJsFilterNode.java | 2 +- .../filter/TbJsFilterNodeConfiguration.java | 2 +- .../rule/engine/filter/TbJsSwitchNode.java | 2 +- .../filter/TbJsSwitchNodeConfiguration.java | 2 +- .../rule/engine/filter/TbMsgTypeFilterNode.java | 2 +- .../filter/TbMsgTypeFilterNodeConfiguration.java | 2 +- .../rule/engine/filter/TbMsgTypeSwitchNode.java | 2 +- .../filter/TbOriginatorTypeFilterNode.java | 2 +- .../TbOriginatorTypeFilterNodeConfiguration.java | 2 +- .../filter/TbOriginatorTypeSwitchNode.java | 2 +- .../thingsboard/rule/engine/flow/TbAckNode.java | 2 +- .../rule/engine/flow/TbCheckpointNode.java | 2 +- .../flow/TbCheckpointNodeConfiguration.java | 2 +- .../rule/engine/flow/TbRuleChainInputNode.java | 2 +- .../flow/TbRuleChainInputNodeConfiguration.java | 2 +- .../rule/engine/flow/TbRuleChainOutputNode.java | 2 +- .../rule/engine/gcp/pubsub/TbPubSubNode.java | 2 +- .../gcp/pubsub/TbPubSubNodeConfiguration.java | 2 +- .../rule/engine/geo/AbstractGeofencingNode.java | 2 +- .../thingsboard/rule/engine/geo/Coordinates.java | 2 +- .../rule/engine/geo/EntityGeofencingState.java | 2 +- .../org/thingsboard/rule/engine/geo/GeoUtil.java | 2 +- .../thingsboard/rule/engine/geo/Perimeter.java | 2 +- .../rule/engine/geo/PerimeterType.java | 2 +- .../thingsboard/rule/engine/geo/RangeUnit.java | 2 +- .../engine/geo/TbGpsGeofencingActionNode.java | 2 +- .../TbGpsGeofencingActionNodeConfiguration.java | 2 +- .../engine/geo/TbGpsGeofencingFilterNode.java | 2 +- .../TbGpsGeofencingFilterNodeConfiguration.java | 2 +- .../rule/engine/kafka/TbKafkaNode.java | 2 +- .../engine/kafka/TbKafkaNodeConfiguration.java | 2 +- .../rule/engine/mail/TbMsgToEmailNode.java | 2 +- .../mail/TbMsgToEmailNodeConfiguration.java | 2 +- .../rule/engine/mail/TbSendEmailNode.java | 2 +- .../mail/TbSendEmailNodeConfiguration.java | 2 +- .../rule/engine/math/TbMathArgument.java | 2 +- .../rule/engine/math/TbMathArgumentType.java | 2 +- .../rule/engine/math/TbMathArgumentValue.java | 2 +- .../thingsboard/rule/engine/math/TbMathNode.java | 2 +- .../engine/math/TbMathNodeConfiguration.java | 2 +- .../rule/engine/math/TbMathResult.java | 2 +- .../engine/math/TbRuleNodeMathFunctionType.java | 2 +- .../rule/engine/metadata/CalculateDeltaNode.java | 2 +- .../CalculateDeltaNodeConfiguration.java | 2 +- .../rule/engine/metadata/DataToFetch.java | 2 +- .../TbAbstractFetchToNodeConfiguration.java | 2 +- .../metadata/TbAbstractGetAttributesNode.java | 2 +- .../metadata/TbAbstractGetEntityDataNode.java | 2 +- .../metadata/TbAbstractGetEntityDetailsNode.java | 2 +- ...bstractGetEntityDetailsNodeConfiguration.java | 2 +- .../metadata/TbAbstractGetMappedDataNode.java | 2 +- .../metadata/TbAbstractNodeWithFetchTo.java | 2 +- .../metadata/TbFetchDeviceCredentialsNode.java | 2 +- ...bFetchDeviceCredentialsNodeConfiguration.java | 2 +- .../engine/metadata/TbGetAttributesNode.java | 2 +- .../TbGetAttributesNodeConfiguration.java | 2 +- .../metadata/TbGetCustomerAttributeNode.java | 2 +- .../metadata/TbGetCustomerDetailsNode.java | 2 +- .../TbGetCustomerDetailsNodeConfiguration.java | 2 +- .../engine/metadata/TbGetDeviceAttrNode.java | 2 +- .../TbGetDeviceAttrNodeConfiguration.java | 2 +- .../TbGetEntityDataNodeConfiguration.java | 2 +- .../TbGetMappedDataNodeConfiguration.java | 2 +- .../TbGetOriginatorFieldsConfiguration.java | 2 +- .../metadata/TbGetOriginatorFieldsNode.java | 2 +- .../metadata/TbGetRelatedAttributeNode.java | 2 +- .../TbGetRelatedDataNodeConfiguration.java | 2 +- .../rule/engine/metadata/TbGetTelemetryNode.java | 2 +- .../TbGetTelemetryNodeConfiguration.java | 2 +- .../metadata/TbGetTenantAttributeNode.java | 2 +- .../engine/metadata/TbGetTenantDetailsNode.java | 2 +- .../TbGetTenantDetailsNodeConfiguration.java | 2 +- .../thingsboard/rule/engine/mqtt/TbMqttNode.java | 2 +- .../engine/mqtt/TbMqttNodeConfiguration.java | 2 +- .../mqtt/azure/AzureIotHubSasCredentials.java | 2 +- .../engine/mqtt/azure/TbAzureIotHubNode.java | 2 +- .../azure/TbAzureIotHubNodeConfiguration.java | 2 +- .../engine/notification/TbNotificationNode.java | 2 +- .../TbNotificationNodeConfiguration.java | 2 +- .../rule/engine/notification/TbSlackNode.java | 2 +- .../notification/TbSlackNodeConfiguration.java | 2 +- .../rule/engine/profile/AlarmEvalResult.java | 2 +- .../rule/engine/profile/AlarmRuleState.java | 2 +- .../rule/engine/profile/AlarmState.java | 2 +- .../engine/profile/AlarmStateUpdateResult.java | 2 +- .../rule/engine/profile/DataSnapshot.java | 2 +- .../rule/engine/profile/DeviceState.java | 2 +- .../engine/profile/DynamicPredicateValueCtx.java | 2 +- .../profile/DynamicPredicateValueCtxImpl.java | 2 +- .../rule/engine/profile/EntityKeyValue.java | 2 +- .../engine/profile/NumericParseException.java | 2 +- .../rule/engine/profile/ProfileState.java | 2 +- .../rule/engine/profile/SnapshotUpdate.java | 2 +- .../rule/engine/profile/TbDeviceProfileNode.java | 2 +- .../TbDeviceProfileNodeConfiguration.java | 2 +- .../profile/state/PersistedAlarmRuleState.java | 2 +- .../profile/state/PersistedAlarmState.java | 2 +- .../profile/state/PersistedDeviceState.java | 2 +- .../rule/engine/rabbitmq/TbRabbitMqNode.java | 2 +- .../rabbitmq/TbRabbitMqNodeConfiguration.java | 2 +- .../rule/engine/rest/TbHttpClient.java | 2 +- .../rule/engine/rest/TbRestApiCallNode.java | 2 +- .../rest/TbRestApiCallNodeConfiguration.java | 2 +- .../rule/engine/rpc/TbSendRPCReplyNode.java | 2 +- .../rule/engine/rpc/TbSendRPCRequestNode.java | 2 +- .../rpc/TbSendRpcReplyNodeConfiguration.java | 2 +- .../rpc/TbSendRpcRequestNodeConfiguration.java | 2 +- .../rule/engine/sms/TbSendSmsNode.java | 2 +- .../engine/sms/TbSendSmsNodeConfiguration.java | 2 +- .../telemetry/AttributesDeleteNodeCallback.java | 2 +- .../telemetry/AttributesUpdateNodeCallback.java | 2 +- .../engine/telemetry/TbMsgAttributesNode.java | 2 +- .../TbMsgAttributesNodeConfiguration.java | 2 +- .../telemetry/TbMsgDeleteAttributesNode.java | 2 +- .../TbMsgDeleteAttributesNodeConfiguration.java | 2 +- .../engine/telemetry/TbMsgTimeseriesNode.java | 2 +- .../TbMsgTimeseriesNodeConfiguration.java | 2 +- .../engine/telemetry/TelemetryNodeCallback.java | 2 +- .../transaction/TbSynchronizationBeginNode.java | 2 +- .../transaction/TbSynchronizationEndNode.java | 2 +- .../transform/MultipleTbMsgsCallbackWrapper.java | 2 +- .../transform/TbAbstractTransformNode.java | 2 +- .../TbAbstractTransformNodeWithTbMsgSource.java | 2 +- .../engine/transform/TbChangeOriginatorNode.java | 2 +- .../TbChangeOriginatorNodeConfiguration.java | 2 +- .../rule/engine/transform/TbCopyKeysNode.java | 2 +- .../transform/TbCopyKeysNodeConfiguration.java | 2 +- .../rule/engine/transform/TbDeleteKeysNode.java | 2 +- .../transform/TbDeleteKeysNodeConfiguration.java | 2 +- .../rule/engine/transform/TbJsonPathNode.java | 2 +- .../transform/TbJsonPathNodeConfiguration.java | 2 +- .../engine/transform/TbMsgCallbackWrapper.java | 2 +- .../rule/engine/transform/TbRenameKeysNode.java | 2 +- .../transform/TbRenameKeysNodeConfiguration.java | 2 +- .../engine/transform/TbSplitArrayMsgNode.java | 2 +- .../engine/transform/TbTransformMsgNode.java | 2 +- .../TbTransformMsgNodeConfiguration.java | 2 +- .../engine/util/ContactBasedEntityDetails.java | 2 +- .../EntitiesAlarmOriginatorIdAsyncLoader.java | 2 +- .../engine/util/EntitiesByNameAndTypeLoader.java | 2 +- .../util/EntitiesCustomerIdAsyncLoader.java | 2 +- .../engine/util/EntitiesFieldsAsyncLoader.java | 2 +- .../util/EntitiesRelatedDeviceIdAsyncLoader.java | 2 +- .../util/EntitiesRelatedEntityIdAsyncLoader.java | 2 +- .../rule/engine/util/EntityContainer.java | 2 +- .../rule/engine/util/TbMsgSource.java | 2 +- .../rule/engine/util/TenantIdLoader.java | 2 +- .../rule/engine/TestDbCallbackExecutor.java | 2 +- .../rule/engine/action/TbAlarmNodeTest.java | 2 +- .../engine/action/TbCreateRelationNodeTest.java | 2 +- .../rule/engine/action/TbLogNodeTest.java | 2 +- .../credentials/CertPemCredentialsTest.java | 2 +- .../engine/edge/TbMsgPushToEdgeNodeTest.java | 2 +- .../engine/filter/TbAssetTypeSwitchNodeTest.java | 2 +- .../filter/TbCheckAlarmStatusNodeTest.java | 2 +- .../engine/filter/TbCheckMessageNodeTest.java | 2 +- .../engine/filter/TbCheckRelationNodeTest.java | 2 +- .../filter/TbDeviceTypeSwitchNodeTest.java | 2 +- .../rule/engine/filter/TbJsFilterNodeTest.java | 2 +- .../rule/engine/filter/TbJsSwitchNodeTest.java | 2 +- .../engine/filter/TbMsgTypeFilterNodeTest.java | 2 +- .../engine/filter/TbMsgTypeSwitchNodeTest.java | 2 +- .../filter/TbOriginatorTypeFilterNodeTest.java | 2 +- .../filter/TbOriginatorTypeSwitchNodeTest.java | 2 +- .../thingsboard/rule/engine/geo/GeoUtilTest.java | 2 +- .../geo/TbGpsGeofencingFilterNodeTest.java | 2 +- .../rule/engine/mail/TbMsgToEmailNodeTest.java | 2 +- .../engine/math/TbMathArgumentValueTest.java | 2 +- .../rule/engine/math/TbMathNodeTest.java | 2 +- .../engine/metadata/CalculateDeltaNodeTest.java | 2 +- .../TbFetchDeviceCredentialsNodeTest.java | 2 +- .../engine/metadata/TbGetAttributesNodeTest.java | 2 +- .../metadata/TbGetCustomerAttributeNodeTest.java | 2 +- .../metadata/TbGetCustomerDetailsNodeTest.java | 2 +- .../engine/metadata/TbGetDeviceAttrNodeTest.java | 2 +- .../metadata/TbGetOriginatorFieldsNodeTest.java | 2 +- .../metadata/TbGetRelatedAttributeNodeTest.java | 2 +- .../engine/metadata/TbGetTelemetryNodeTest.java | 2 +- .../metadata/TbGetTenantAttributeNodeTest.java | 2 +- .../metadata/TbGetTenantDetailsNodeTest.java | 2 +- .../rule/engine/profile/AlarmStateTest.java | 2 +- .../rule/engine/profile/DeviceStateTest.java | 2 +- .../engine/profile/TbDeviceProfileNodeTest.java | 2 +- .../rule/engine/rest/TbHttpClientTest.java | 2 +- .../rule/engine/rest/TbRestApiCallNodeTest.java | 2 +- .../rule/engine/rpc/TbSendRPCReplyNodeTest.java | 2 +- .../TbMsgAttributesNodeConfigurationTest.java | 2 +- .../telemetry/TbMsgAttributesNodeTest.java | 2 +- .../telemetry/TbMsgDeleteAttributesNodeTest.java | 2 +- .../transform/TbChangeOriginatorNodeTest.java | 2 +- .../engine/transform/TbCopyKeysNodeTest.java | 2 +- .../engine/transform/TbDeleteKeysNodeTest.java | 2 +- .../engine/transform/TbJsonPathNodeTest.java | 2 +- .../transform/TbMsgDeduplicationNodeTest.java | 2 +- .../engine/transform/TbRenameKeysNodeTest.java | 2 +- .../transform/TbSplitArrayMsgNodeTest.java | 2 +- .../engine/transform/TbTransformMsgNodeTest.java | 2 +- .../util/EntitiesCustomerIdAsyncLoaderTest.java | 2 +- .../util/EntitiesFieldsAsyncLoaderTest.java | 2 +- .../EntitiesRelatedDeviceIdAsyncLoaderTest.java | 2 +- .../EntitiesRelatedEntityIdAsyncLoaderTest.java | 2 +- .../rule/engine/util/TenantIdLoaderTest.java | 2 +- tools/pom.xml | 2 +- .../thingsboard/client/tools/MqttSslClient.java | 2 +- .../client/tools/migrator/DictionaryParser.java | 2 +- .../client/tools/migrator/MigratorTool.java | 2 +- .../client/tools/migrator/PgCaMigrator.java | 2 +- .../tools/migrator/RelatedEntitiesParser.java | 2 +- .../client/tools/migrator/WriterBuilder.java | 2 +- tools/src/main/python/check_yml_file.py | 2 +- tools/src/main/python/mqtt-send-telemetry.py | 2 +- tools/src/main/python/one-way-ssl-mqtt-client.py | 2 +- tools/src/main/python/simple-mqtt-client.py | 2 +- tools/src/main/python/two-way-ssl-mqtt-client.py | 2 +- tools/src/main/shell/client.keygen.sh | 2 +- .../lwm2m/lwM2M_cfssl_chain_clients_for_test.sh | 2 +- .../lwm2m/lwm2m_cfssl_chain_all_for_test.sh | 2 +- .../lwm2m/lwm2m_cfssl_chain_server_for_test.sh | 2 +- tools/src/main/shell/server.keygen.sh | 2 +- transport/coap/pom.xml | 2 +- transport/coap/src/main/conf/logback.xml | 2 +- .../coap/src/main/conf/tb-coap-transport.conf | 2 +- .../ThingsboardCoapTransportApplication.java | 2 +- transport/coap/src/main/resources/logback.xml | 2 +- .../src/main/resources/tb-coap-transport.yml | 2 +- transport/http/pom.xml | 2 +- transport/http/src/main/conf/logback.xml | 2 +- .../http/src/main/conf/tb-http-transport.conf | 2 +- .../ThingsboardHttpTransportApplication.java | 2 +- transport/http/src/main/resources/logback.xml | 2 +- .../src/main/resources/tb-http-transport.yml | 2 +- transport/lwm2m/pom.xml | 2 +- transport/lwm2m/src/main/conf/logback.xml | 2 +- .../lwm2m/src/main/conf/tb-lwm2m-transport.conf | 2 +- .../ThingsboardLwm2mTransportApplication.java | 2 +- transport/lwm2m/src/main/resources/logback.xml | 2 +- .../src/main/resources/tb-lwm2m-transport.yml | 2 +- transport/mqtt/pom.xml | 2 +- transport/mqtt/src/main/conf/logback.xml | 2 +- .../mqtt/src/main/conf/tb-mqtt-transport.conf | 2 +- .../ThingsboardMqttTransportApplication.java | 2 +- transport/mqtt/src/main/resources/logback.xml | 2 +- .../src/main/resources/tb-mqtt-transport.yml | 2 +- transport/pom.xml | 2 +- transport/snmp/pom.xml | 2 +- transport/snmp/src/main/conf/logback.xml | 2 +- .../snmp/src/main/conf/tb-snmp-transport.conf | 2 +- .../ThingsboardSnmpTransportApplication.java | 2 +- transport/snmp/src/main/resources/logback.xml | 2 +- .../src/main/resources/tb-snmp-transport.yml | 2 +- ui-ngx/.editorconfig | 2 +- ui-ngx/e2e/protractor.conf.js | 2 +- ui-ngx/e2e/src/app.e2e-spec.ts | 2 +- ui-ngx/e2e/src/app.po.ts | 2 +- ui-ngx/extra-webpack.config.js | 2 +- ui-ngx/generate-types.js | 2 +- ui-ngx/pom.xml | 2 +- ui-ngx/proxy.conf.js | 2 +- ui-ngx/src/app/app-routing.module.ts | 2 +- ui-ngx/src/app/app.component.html | 2 +- ui-ngx/src/app/app.component.scss | 2 +- ui-ngx/src/app/app.component.ts | 2 +- ui-ngx/src/app/app.module.ts | 2 +- .../src/app/core/api/alarm-data-subscription.ts | 2 +- ui-ngx/src/app/core/api/alarm-data.service.ts | 2 +- ui-ngx/src/app/core/api/alias-controller.ts | 2 +- ui-ngx/src/app/core/api/data-aggregator.ts | 2 +- .../src/app/core/api/entity-data-subscription.ts | 2 +- ui-ngx/src/app/core/api/entity-data.service.ts | 2 +- ui-ngx/src/app/core/api/public-api.ts | 2 +- ui-ngx/src/app/core/api/widget-api.models.ts | 2 +- ui-ngx/src/app/core/api/widget-subscription.ts | 2 +- ui-ngx/src/app/core/auth/auth.actions.ts | 2 +- ui-ngx/src/app/core/auth/auth.effects.ts | 2 +- ui-ngx/src/app/core/auth/auth.models.ts | 2 +- ui-ngx/src/app/core/auth/auth.reducer.ts | 2 +- ui-ngx/src/app/core/auth/auth.selectors.ts | 2 +- ui-ngx/src/app/core/auth/auth.service.spec.ts | 2 +- ui-ngx/src/app/core/auth/auth.service.ts | 2 +- ui-ngx/src/app/core/auth/public-api.ts | 2 +- ui-ngx/src/app/core/core.module.ts | 2 +- ui-ngx/src/app/core/core.state.ts | 2 +- ui-ngx/src/app/core/css/css.js | 2 +- ui-ngx/src/app/core/guards/auth.guard.ts | 2 +- .../src/app/core/guards/confirm-on-exit.guard.ts | 2 +- ui-ngx/src/app/core/http/admin.service.ts | 2 +- .../src/app/core/http/alarm-comment.service.ts | 2 +- ui-ngx/src/app/core/http/alarm.service.ts | 2 +- .../src/app/core/http/asset-profile.service.ts | 2 +- ui-ngx/src/app/core/http/asset.service.ts | 2 +- ui-ngx/src/app/core/http/attribute.service.ts | 2 +- ui-ngx/src/app/core/http/audit-log.service.ts | 2 +- .../core/http/component-descriptor.service.ts | 2 +- ui-ngx/src/app/core/http/customer.service.ts | 2 +- ui-ngx/src/app/core/http/dashboard.service.ts | 2 +- .../src/app/core/http/device-profile.service.ts | 2 +- ui-ngx/src/app/core/http/device.service.ts | 2 +- ui-ngx/src/app/core/http/edge.service.ts | 2 +- .../http/entities-version-control.service.ts | 2 +- .../src/app/core/http/entity-relation.service.ts | 2 +- ui-ngx/src/app/core/http/entity-view.service.ts | 2 +- ui-ngx/src/app/core/http/entity.service.ts | 2 +- ui-ngx/src/app/core/http/event.service.ts | 2 +- ui-ngx/src/app/core/http/http-utils.ts | 2 +- ui-ngx/src/app/core/http/image.service.ts | 2 +- ui-ngx/src/app/core/http/notification.service.ts | 2 +- ui-ngx/src/app/core/http/oauth2.service.ts | 2 +- ui-ngx/src/app/core/http/ota-package.service.ts | 2 +- ui-ngx/src/app/core/http/public-api.ts | 2 +- ui-ngx/src/app/core/http/queue.service.ts | 2 +- ui-ngx/src/app/core/http/resource.service.ts | 2 +- ui-ngx/src/app/core/http/rule-chain.service.ts | 2 +- .../src/app/core/http/tenant-profile.service.ts | 2 +- ui-ngx/src/app/core/http/tenant.service.ts | 2 +- .../http/two-factor-authentication.service.ts | 2 +- ui-ngx/src/app/core/http/ui-settings.service.ts | 2 +- ui-ngx/src/app/core/http/usage-info.service.ts | 2 +- .../src/app/core/http/user-settings.service.ts | 2 +- ui-ngx/src/app/core/http/user.service.ts | 2 +- ui-ngx/src/app/core/http/widget.service.ts | 2 +- .../core/interceptors/global-http-interceptor.ts | 2 +- .../app/core/interceptors/interceptor-config.ts | 2 +- .../core/interceptors/interceptor-http-params.ts | 2 +- ui-ngx/src/app/core/interceptors/load.actions.ts | 2 +- ui-ngx/src/app/core/interceptors/load.models.ts | 2 +- ui-ngx/src/app/core/interceptors/load.reducer.ts | 2 +- .../src/app/core/interceptors/load.selectors.ts | 2 +- .../core/local-storage/local-storage.service.ts | 2 +- .../src/app/core/meta-reducers/debug.reducer.ts | 2 +- .../init-state-from-local-storage.reducer.ts | 2 +- .../core/notification/notification.actions.ts | 2 +- .../core/notification/notification.effects.ts | 2 +- .../app/core/notification/notification.models.ts | 2 +- .../core/notification/notification.reducer.ts | 2 +- ui-ngx/src/app/core/operator/enterZone.ts | 2 +- ui-ngx/src/app/core/public-api.ts | 2 +- .../core/services/active-component.service.ts | 2 +- ui-ngx/src/app/core/services/broadcast.models.ts | 2 +- .../src/app/core/services/broadcast.service.ts | 2 +- .../app/core/services/dashboard-utils.service.ts | 2 +- ui-ngx/src/app/core/services/dialog.service.ts | 2 +- .../dynamic-component-factory.service.ts | 2 +- ui-ngx/src/app/core/services/help.service.ts | 2 +- .../src/app/core/services/item-buffer.service.ts | 2 +- ui-ngx/src/app/core/services/menu.models.ts | 2 +- ui-ngx/src/app/core/services/menu.service.ts | 2 +- ui-ngx/src/app/core/services/mobile.service.ts | 2 +- ui-ngx/src/app/core/services/public-api.ts | 2 +- ui-ngx/src/app/core/services/raf.service.ts | 2 +- .../src/app/core/services/resources.service.ts | 2 +- .../services/script/node-script-test.service.ts | 2 +- ui-ngx/src/app/core/services/time.service.ts | 2 +- ui-ngx/src/app/core/services/title.service.ts | 2 +- .../core/services/toast-notification.service.ts | 2 +- ui-ngx/src/app/core/services/utils.service.ts | 2 +- ui-ngx/src/app/core/services/window.service.ts | 2 +- ui-ngx/src/app/core/settings/settings.actions.ts | 2 +- ui-ngx/src/app/core/settings/settings.effects.ts | 2 +- ui-ngx/src/app/core/settings/settings.models.ts | 2 +- ui-ngx/src/app/core/settings/settings.reducer.ts | 2 +- .../src/app/core/settings/settings.selectors.ts | 2 +- ui-ngx/src/app/core/settings/settings.utils.ts | 2 +- .../core/translate/missing-translate-handler.ts | 2 +- .../core/translate/translate-default-compiler.ts | 2 +- .../core/translate/translate-default-parser.ts | 2 +- ui-ngx/src/app/core/utils.ts | 2 +- .../core/ws/notification-websocket.service.ts | 2 +- ui-ngx/src/app/core/ws/public-api.ts | 2 +- .../app/core/ws/telemetry-websocket.service.ts | 2 +- ui-ngx/src/app/core/ws/websocket.service.ts | 2 +- .../src/app/modules/common/modules-map.models.ts | 2 +- ui-ngx/src/app/modules/common/modules-map.ts | 2 +- .../modules/dashboard/dashboard-pages.module.ts | 2 +- .../dashboard/dashboard-pages.routing.module.ts | 2 +- .../dashboard/dashboard-routing.module.ts | 2 +- .../alarm/alarm-assignee-panel.component.html | 2 +- .../alarm/alarm-assignee-panel.component.scss | 3 +-- .../alarm/alarm-assignee-panel.component.ts | 2 +- .../alarm-assignee-select-panel.component.ts | 2 +- .../alarm/alarm-assignee-select.component.html | 2 +- .../alarm/alarm-assignee-select.component.ts | 2 +- .../alarm/alarm-assignee.component.html | 3 +-- .../alarm/alarm-assignee.component.scss | 3 +-- .../components/alarm/alarm-assignee.component.ts | 2 +- .../alarm/alarm-comment-dialog.component.html | 2 +- .../alarm/alarm-comment-dialog.component.ts | 2 +- .../alarm/alarm-comment.component.html | 3 +-- .../alarm/alarm-comment.component.scss | 2 +- .../components/alarm/alarm-comment.component.ts | 2 +- .../alarm/alarm-details-dialog.component.html | 2 +- .../alarm/alarm-details-dialog.component.scss | 3 +-- .../alarm/alarm-details-dialog.component.ts | 2 +- .../alarm/alarm-filter-config.component.html | 2 +- .../alarm/alarm-filter-config.component.scss | 2 +- .../alarm/alarm-filter-config.component.ts | 2 +- .../home/components/alarm/alarm-table-config.ts | 2 +- .../alarm/alarm-table-header.component.html | 2 +- .../alarm/alarm-table-header.component.scss | 2 +- .../alarm/alarm-table-header.component.ts | 2 +- .../components/alarm/alarm-table.component.html | 2 +- .../components/alarm/alarm-table.component.scss | 2 +- .../components/alarm/alarm-table.component.ts | 2 +- .../aliases-entity-autocomplete.component.html | 2 +- .../aliases-entity-autocomplete.component.ts | 2 +- .../aliases-entity-select-panel.component.html | 2 +- .../aliases-entity-select-panel.component.scss | 2 +- .../aliases-entity-select-panel.component.ts | 2 +- .../alias/aliases-entity-select.component.html | 2 +- .../alias/aliases-entity-select.component.scss | 2 +- .../alias/aliases-entity-select.component.ts | 2 +- .../alias/entity-alias-dialog.component.html | 2 +- .../alias/entity-alias-dialog.component.scss | 2 +- .../alias/entity-alias-dialog.component.ts | 2 +- .../alias/entity-alias-select.component.html | 2 +- .../entity-alias-select.component.models.ts | 2 +- .../alias/entity-alias-select.component.scss | 2 +- .../alias/entity-alias-select.component.ts | 2 +- .../alias/entity-aliases-dialog.component.html | 2 +- .../alias/entity-aliases-dialog.component.scss | 2 +- .../alias/entity-aliases-dialog.component.ts | 2 +- .../add-attribute-dialog.component.html | 2 +- .../attribute/add-attribute-dialog.component.ts | 2 +- ...add-widget-to-dashboard-dialog.component.html | 2 +- ...add-widget-to-dashboard-dialog.component.scss | 2 +- .../add-widget-to-dashboard-dialog.component.ts | 2 +- .../attribute/attribute-table.component.html | 2 +- .../attribute/attribute-table.component.scss | 2 +- .../attribute/attribute-table.component.ts | 2 +- .../delete-timeseries-panel.component.html | 3 +-- .../delete-timeseries-panel.component.scss | 2 +- .../delete-timeseries-panel.component.ts | 2 +- .../edit-attribute-value-panel.component.html | 2 +- .../edit-attribute-value-panel.component.scss | 2 +- .../edit-attribute-value-panel.component.ts | 2 +- .../audit-log-details-dialog.component.html | 2 +- .../audit-log-details-dialog.component.scss | 2 +- .../audit-log-details-dialog.component.ts | 2 +- .../audit-log/audit-log-table-config.ts | 2 +- .../audit-log/audit-log-table.component.html | 2 +- .../audit-log/audit-log-table.component.scss | 2 +- .../audit-log/audit-log-table.component.ts | 2 +- .../add-widget-dialog.component.html | 2 +- .../add-widget-dialog.component.scss | 2 +- .../add-widget-dialog.component.ts | 2 +- .../dashboard-image-dialog.component.html | 2 +- .../dashboard-image-dialog.component.scss | 2 +- .../dashboard-image-dialog.component.ts | 2 +- .../dashboard-page/dashboard-page.component.html | 2 +- .../dashboard-page/dashboard-page.component.scss | 2 +- .../dashboard-page/dashboard-page.component.ts | 2 +- .../dashboard-page/dashboard-page.models.ts | 2 +- .../dashboard-settings-dialog.component.html | 2 +- .../dashboard-settings-dialog.component.scss | 2 +- .../dashboard-settings-dialog.component.ts | 2 +- .../dashboard-state.component.html | 2 +- .../dashboard-state.component.scss | 2 +- .../dashboard-page/dashboard-state.component.ts | 2 +- .../dashboard-toolbar.component.html | 2 +- .../dashboard-toolbar.component.scss | 2 +- .../dashboard-toolbar.component.ts | 2 +- .../dashboard-widget-select.component.html | 2 +- .../dashboard-widget-select.component.scss | 3 +-- .../dashboard-widget-select.component.ts | 2 +- .../dashboard-page/edit-widget.component.html | 2 +- .../dashboard-page/edit-widget.component.scss | 2 +- .../dashboard-page/edit-widget.component.ts | 2 +- .../layout/dashboard-layout.component.html | 2 +- .../layout/dashboard-layout.component.scss | 2 +- .../layout/dashboard-layout.component.ts | 2 +- .../dashboard-page/layout/layout.models.ts | 2 +- ...anage-dashboard-layouts-dialog.component.html | 2 +- ...anage-dashboard-layouts-dialog.component.scss | 2 +- .../manage-dashboard-layouts-dialog.component.ts | 2 +- .../states/dashboard-state-dialog.component.html | 2 +- .../states/dashboard-state-dialog.component.ts | 2 +- .../default-state-controller.component.html | 2 +- .../default-state-controller.component.scss | 2 +- .../states/default-state-controller.component.ts | 2 +- .../entity-state-controller.component.html | 2 +- .../entity-state-controller.component.scss | 2 +- .../states/entity-state-controller.component.ts | 2 +- ...manage-dashboard-states-dialog.component.html | 2 +- ...e-dashboard-states-dialog.component.models.ts | 2 +- ...manage-dashboard-states-dialog.component.scss | 2 +- .../manage-dashboard-states-dialog.component.ts | 2 +- .../states/state-controller.component.ts | 2 +- .../states/state-controller.models.ts | 2 +- .../states/states-component.directive.ts | 2 +- .../states/states-controller.module.ts | 2 +- .../states/states-controller.service.ts | 2 +- .../widget-types-panel.component.html | 2 +- .../widget-types-panel.component.scss | 2 +- .../widget-types-panel.component.ts | 2 +- .../dashboard/dashboard.component.html | 2 +- .../dashboard/dashboard.component.scss | 2 +- .../components/dashboard/dashboard.component.ts | 2 +- .../home/components/dashboard/layout-button.scss | 2 +- .../select-target-layout-dialog.component.html | 2 +- .../select-target-layout-dialog.component.ts | 2 +- .../select-target-state-dialog.component.html | 2 +- .../select-target-state-dialog.component.ts | 2 +- .../home/components/details-panel.component.html | 2 +- .../home/components/details-panel.component.scss | 2 +- .../home/components/details-panel.component.ts | 2 +- .../copy-device-credentials.component.html | 2 +- .../device/copy-device-credentials.component.ts | 2 +- ...evice-credentials-lwm2m-server.component.html | 2 +- .../device-credentials-lwm2m-server.component.ts | 2 +- .../device-credentials-lwm2m.component.html | 2 +- .../device-credentials-lwm2m.component.scss | 2 +- .../device/device-credentials-lwm2m.component.ts | 2 +- .../device-credentials-mqtt-basic.component.html | 2 +- .../device-credentials-mqtt-basic.component.ts | 2 +- .../device/device-credentials.component.html | 2 +- .../device/device-credentials.component.scss | 2 +- .../device/device-credentials.component.ts | 2 +- .../device/device-credentials.module.ts | 2 +- .../device/device-info-filter.component.html | 2 +- .../device/device-info-filter.component.scss | 2 +- .../device/device-info-filter.component.ts | 2 +- .../edge/edge-downlink-table-config.ts | 2 +- .../edge-downlink-table-header.component.html | 2 +- .../edge-downlink-table-header.component.scss | 2 +- .../edge/edge-downlink-table-header.component.ts | 2 +- .../edge/edge-downlink-table.component.html | 2 +- .../edge/edge-downlink-table.component.scss | 2 +- .../edge/edge-downlink-table.component.ts | 2 +- .../entity/add-entity-dialog.component.html | 2 +- .../entity/add-entity-dialog.component.scss | 2 +- .../entity/add-entity-dialog.component.ts | 2 +- .../components/entity/contact-based.component.ts | 2 +- .../entity/entities-table.component.html | 2 +- .../entity/entities-table.component.scss | 2 +- .../entity/entities-table.component.ts | 2 +- .../entity/entity-details-page.component.html | 2 +- .../entity/entity-details-page.component.scss | 2 +- .../entity/entity-details-page.component.ts | 2 +- .../entity/entity-details-panel.component.html | 2 +- .../entity/entity-details-panel.component.scss | 2 +- .../entity/entity-details-panel.component.ts | 2 +- .../entity/entity-filter-view.component.html | 2 +- .../entity/entity-filter-view.component.scss | 2 +- .../entity/entity-filter-view.component.ts | 2 +- .../entity/entity-filter.component.html | 2 +- .../entity/entity-filter.component.scss | 2 +- .../components/entity/entity-filter.component.ts | 2 +- .../entity/entity-table-header.component.ts | 2 +- .../components/entity/entity-tabs.component.ts | 2 +- .../home/components/entity/entity.component.ts | 2 +- .../event/event-content-dialog.component.html | 2 +- .../event/event-content-dialog.component.scss | 2 +- .../event/event-content-dialog.component.ts | 2 +- .../event/event-filter-panel.component.html | 2 +- .../event/event-filter-panel.component.scss | 2 +- .../event/event-filter-panel.component.ts | 2 +- .../home/components/event/event-table-config.ts | 2 +- .../event/event-table-header.component.html | 2 +- .../event/event-table-header.component.scss | 2 +- .../event/event-table-header.component.ts | 2 +- .../components/event/event-table.component.html | 2 +- .../components/event/event-table.component.scss | 2 +- .../components/event/event-table.component.ts | 2 +- .../boolean-filter-predicate.component.html | 2 +- .../filter/boolean-filter-predicate.component.ts | 2 +- ...omplex-filter-predicate-dialog.component.html | 2 +- .../complex-filter-predicate-dialog.component.ts | 2 +- .../complex-filter-predicate.component.html | 2 +- .../filter/complex-filter-predicate.component.ts | 2 +- .../components/filter/filter-component.models.ts | 2 +- .../filter/filter-dialog.component.html | 2 +- .../filter/filter-dialog.component.scss | 2 +- .../components/filter/filter-dialog.component.ts | 2 +- .../filter/filter-predicate-list.component.html | 2 +- .../filter/filter-predicate-list.component.scss | 2 +- .../filter/filter-predicate-list.component.ts | 2 +- .../filter/filter-predicate-value.component.html | 2 +- .../filter/filter-predicate-value.component.ts | 2 +- .../filter/filter-predicate.component.html | 2 +- .../filter/filter-predicate.component.ts | 2 +- .../home/components/filter/filter-predicate.scss | 2 +- .../filter/filter-select.component.html | 2 +- .../filter/filter-select.component.models.ts | 2 +- .../components/filter/filter-select.component.ts | 2 +- .../components/filter/filter-text.component.html | 2 +- .../components/filter/filter-text.component.scss | 2 +- .../components/filter/filter-text.component.ts | 2 +- .../filter-user-info-dialog.component.html | 2 +- .../filter/filter-user-info-dialog.component.ts | 2 +- .../filter/filter-user-info.component.html | 2 +- .../filter/filter-user-info.component.ts | 2 +- .../filter/filters-dialog.component.html | 2 +- .../filter/filters-dialog.component.scss | 2 +- .../filter/filters-dialog.component.ts | 2 +- .../filter/filters-edit-panel.component.html | 2 +- .../filter/filters-edit-panel.component.scss | 2 +- .../filter/filters-edit-panel.component.ts | 2 +- .../filter/filters-edit.component.html | 2 +- .../filter/filters-edit.component.scss | 2 +- .../components/filter/filters-edit.component.ts | 2 +- .../filter/key-filter-dialog.component.html | 2 +- .../filter/key-filter-dialog.component.scss | 2 +- .../filter/key-filter-dialog.component.ts | 2 +- .../filter/key-filter-list.component.html | 2 +- .../filter/key-filter-list.component.scss | 2 +- .../filter/key-filter-list.component.ts | 2 +- .../numeric-filter-predicate.component.html | 2 +- .../filter/numeric-filter-predicate.component.ts | 2 +- .../string-filter-predicate.component.html | 2 +- .../filter/string-filter-predicate.component.ts | 2 +- .../filter/user-filter-dialog.component.html | 2 +- .../filter/user-filter-dialog.component.ts | 2 +- .../home/components/home-components.module.ts | 2 +- .../notification-bell.component.html | 2 +- .../notification/notification-bell.component.ts | 2 +- .../send-notification-button.component.html | 2 +- .../send-notification-button.component.ts | 2 +- .../show-notification-popover.component.html | 2 +- .../show-notification-popover.component.ts | 2 +- .../add-device-profile-dialog.component.html | 2 +- .../add-device-profile-dialog.component.scss | 2 +- .../add-device-profile-dialog.component.ts | 2 +- ...alarm-duration-predicate-value.component.html | 2 +- .../alarm-duration-predicate-value.component.ts | 2 +- .../alarm/alarm-dynamic-value.component.html | 2 +- .../alarm/alarm-dynamic-value.component.ts | 2 +- .../alarm-rule-condition-dialog.component.html | 2 +- .../alarm-rule-condition-dialog.component.scss | 2 +- .../alarm-rule-condition-dialog.component.ts | 2 +- .../alarm/alarm-rule-condition.component.html | 2 +- .../alarm/alarm-rule-condition.component.scss | 2 +- .../alarm/alarm-rule-condition.component.ts | 2 +- .../profile/alarm/alarm-rule.component.html | 2 +- .../profile/alarm/alarm-rule.component.scss | 2 +- .../profile/alarm/alarm-rule.component.ts | 2 +- .../alarm/alarm-schedule-dialog.component.html | 2 +- .../alarm/alarm-schedule-dialog.component.ts | 2 +- .../alarm/alarm-schedule-info.component.html | 2 +- .../alarm/alarm-schedule-info.component.scss | 2 +- .../alarm/alarm-schedule-info.component.ts | 2 +- .../profile/alarm/alarm-schedule.component.html | 2 +- .../profile/alarm/alarm-schedule.component.scss | 2 +- .../profile/alarm/alarm-schedule.component.ts | 2 +- .../alarm/create-alarm-rules.component.html | 2 +- .../alarm/create-alarm-rules.component.scss | 2 +- .../alarm/create-alarm-rules.component.ts | 2 +- .../alarm/device-profile-alarm.component.html | 2 +- .../alarm/device-profile-alarm.component.scss | 2 +- .../alarm/device-profile-alarm.component.ts | 2 +- .../alarm/device-profile-alarms.component.html | 2 +- .../alarm/device-profile-alarms.component.scss | 2 +- .../alarm/device-profile-alarms.component.ts | 2 +- .../edit-alarm-details-dialog.component.html | 2 +- .../alarm/edit-alarm-details-dialog.component.ts | 2 +- .../asset-profile-autocomplete.component.html | 2 +- .../asset-profile-autocomplete.component.scss | 2 +- .../asset-profile-autocomplete.component.ts | 2 +- .../profile/asset-profile-dialog.component.html | 2 +- .../profile/asset-profile-dialog.component.ts | 2 +- .../profile/asset-profile.component.html | 2 +- .../profile/asset-profile.component.ts | 2 +- .../device-profile-autocomplete.component.html | 2 +- .../device-profile-autocomplete.component.scss | 2 +- .../device-profile-autocomplete.component.ts | 2 +- .../profile/device-profile-dialog.component.html | 2 +- .../profile/device-profile-dialog.component.ts | 2 +- ...rofile-provision-configuration.component.html | 2 +- ...-profile-provision-configuration.component.ts | 2 +- .../profile/device-profile.component.html | 2 +- .../profile/device-profile.component.ts | 2 +- ...rofile-transport-configuration.component.html | 2 +- ...rofile-transport-configuration.component.scss | 2 +- ...-profile-transport-configuration.component.ts | 2 +- .../common/device-profile-common.module.ts | 2 +- .../common/power-mode-setting.component.html | 2 +- .../common/power-mode-setting.component.ts | 2 +- .../common/time-unit-select.component.html | 2 +- .../device/common/time-unit-select.component.ts | 2 +- ...t-device-profile-configuration.component.html | 2 +- ...ult-device-profile-configuration.component.ts | 2 +- ...rofile-transport-configuration.component.html | 2 +- ...-profile-transport-configuration.component.ts | 2 +- .../device-profile-configuration.component.html | 2 +- .../device-profile-configuration.component.ts | 2 +- ...rofile-transport-configuration.component.html | 2 +- ...-profile-transport-configuration.component.ts | 2 +- .../lwm2m/lwm2m-attributes-dialog.component.html | 2 +- .../lwm2m/lwm2m-attributes-dialog.component.ts | 2 +- .../lwm2m-attributes-key-list.component.html | 2 +- .../lwm2m-attributes-key-list.component.scss | 2 +- .../lwm2m/lwm2m-attributes-key-list.component.ts | 2 +- .../device/lwm2m/lwm2m-attributes.component.html | 2 +- .../device/lwm2m/lwm2m-attributes.component.ts | 2 +- ...strap-add-config-server-dialog.component.html | 2 +- ...otstrap-add-config-server-dialog.component.ts | 2 +- ...lwm2m-bootstrap-config-servers.component.html | 2 +- .../lwm2m-bootstrap-config-servers.component.ts | 2 +- .../lwm2m-device-config-server.component.html | 2 +- .../lwm2m-device-config-server.component.ts | 2 +- ...rofile-transport-configuration.component.html | 2 +- ...rofile-transport-configuration.component.scss | 2 +- ...-profile-transport-configuration.component.ts | 2 +- ...2m-object-add-instances-dialog.component.html | 2 +- ...wm2m-object-add-instances-dialog.component.ts | 2 +- ...wm2m-object-add-instances-list.component.html | 2 +- .../lwm2m-object-add-instances-list.component.ts | 2 +- .../lwm2m/lwm2m-object-list.component.html | 2 +- .../device/lwm2m/lwm2m-object-list.component.ts | 2 +- ...serve-attr-telemetry-instances.component.html | 2 +- ...serve-attr-telemetry-instances.component.scss | 2 +- ...observe-attr-telemetry-instances.component.ts | 2 +- ...serve-attr-telemetry-resources.component.html | 2 +- ...serve-attr-telemetry-resources.component.scss | 2 +- ...observe-attr-telemetry-resources.component.ts | 2 +- .../lwm2m-observe-attr-telemetry.component.html | 2 +- .../lwm2m-observe-attr-telemetry.component.scss | 2 +- .../lwm2m-observe-attr-telemetry.component.ts | 2 +- .../lwm2m/lwm2m-profile-components.module.ts | 2 +- .../device/lwm2m/lwm2m-profile-config.models.ts | 2 +- ...rofile-transport-configuration.component.html | 2 +- ...rofile-transport-configuration.component.scss | 2 +- ...-profile-transport-configuration.component.ts | 2 +- ...e-profile-communication-config.component.html | 2 +- ...e-profile-communication-config.component.scss | 2 +- ...ice-profile-communication-config.component.ts | 2 +- .../snmp-device-profile-mapping.component.html | 2 +- .../snmp-device-profile-mapping.component.scss | 2 +- .../snmp-device-profile-mapping.component.ts | 2 +- ...rofile-transport-configuration.component.html | 2 +- ...-profile-transport-configuration.component.ts | 2 +- .../snmp/snmp-device-profile-transport.module.ts | 2 +- .../queue/tenant-profile-queues.component.html | 2 +- .../queue/tenant-profile-queues.component.scss | 2 +- .../queue/tenant-profile-queues.component.ts | 2 +- .../tenant-profile-autocomplete.component.html | 2 +- .../tenant-profile-autocomplete.component.scss | 2 +- .../tenant-profile-autocomplete.component.ts | 2 +- .../profile/tenant-profile-data.component.html | 2 +- .../profile/tenant-profile-data.component.ts | 2 +- .../profile/tenant-profile-dialog.component.html | 2 +- .../profile/tenant-profile-dialog.component.scss | 2 +- .../profile/tenant-profile-dialog.component.ts | 2 +- .../profile/tenant-profile.component.html | 2 +- .../profile/tenant-profile.component.scss | 2 +- .../profile/tenant-profile.component.ts | 2 +- ...t-tenant-profile-configuration.component.html | 2 +- ...t-tenant-profile-configuration.component.scss | 2 +- ...ult-tenant-profile-configuration.component.ts | 2 +- .../rate-limits-details-dialog.component.html | 2 +- .../rate-limits-details-dialog.component.ts | 2 +- .../rate-limits/rate-limits-list.component.html | 2 +- .../rate-limits/rate-limits-list.component.scss | 2 +- .../rate-limits/rate-limits-list.component.ts | 2 +- .../rate-limits/rate-limits-text.component.html | 2 +- .../rate-limits/rate-limits-text.component.scss | 2 +- .../rate-limits/rate-limits-text.component.ts | 2 +- .../rate-limits/rate-limits.component.html | 2 +- .../rate-limits/rate-limits.component.scss | 2 +- .../tenant/rate-limits/rate-limits.component.ts | 2 +- .../tenant/rate-limits/rate-limits.models.ts | 2 +- .../tenant-profile-configuration.component.html | 2 +- .../tenant-profile-configuration.component.ts | 2 +- .../app/modules/home/components/public-api.ts | 2 +- .../components/queue/queue-form.component.html | 2 +- .../components/queue/queue-form.component.scss | 2 +- .../components/queue/queue-form.component.ts | 2 +- .../relation/relation-dialog.component.html | 2 +- .../relation/relation-dialog.component.scss | 2 +- .../relation/relation-dialog.component.ts | 2 +- .../relation/relation-filters.component.html | 2 +- .../relation/relation-filters.component.scss | 2 +- .../relation/relation-filters.component.ts | 2 +- .../relation/relation-table.component.html | 2 +- .../relation/relation-table.component.scss | 2 +- .../relation/relation-table.component.ts | 2 +- .../home/components/router-tabs.component.html | 2 +- .../home/components/router-tabs.component.scss | 2 +- .../home/components/router-tabs.component.ts | 2 +- .../rule-chain-autocomplete.component.html | 2 +- .../rule-chain-autocomplete.component.ts | 2 +- .../components/shared-home-components.module.ts | 2 +- ...aws-sns-provider-configuration.component.html | 2 +- .../aws-sns-provider-configuration.component.ts | 2 +- ...mpp-sms-provider-configuration.component.html | 2 +- .../smpp-sms-provider-configuration.component.ts | 2 +- .../sms-provider-configuration.component.html | 2 +- .../sms/sms-provider-configuration.component.ts | 2 +- ...lio-sms-provider-configuration.component.html | 2 +- ...wilio-sms-provider-configuration.component.ts | 2 +- ui-ngx/src/app/modules/home/components/tokens.ts | 2 +- .../vc/auto-commit-settings.component.html | 2 +- .../vc/auto-commit-settings.component.scss | 2 +- .../vc/auto-commit-settings.component.ts | 2 +- .../vc/complex-version-create.component.html | 2 +- .../vc/complex-version-create.component.ts | 2 +- .../vc/complex-version-load.component.html | 2 +- .../vc/complex-version-load.component.ts | 2 +- .../entity-types-version-create.component.html | 2 +- .../vc/entity-types-version-create.component.ts | 2 +- .../vc/entity-types-version-load.component.html | 2 +- .../vc/entity-types-version-load.component.ts | 2 +- .../vc/entity-types-version.component.scss | 2 +- .../vc/entity-version-create.component.html | 2 +- .../vc/entity-version-create.component.ts | 2 +- .../vc/entity-version-diff.component.html | 2 +- .../vc/entity-version-diff.component.scss | 2 +- .../vc/entity-version-diff.component.ts | 2 +- .../vc/entity-version-restore.component.html | 2 +- .../vc/entity-version-restore.component.ts | 2 +- .../vc/entity-versions-table.component.html | 2 +- .../vc/entity-versions-table.component.scss | 2 +- .../vc/entity-versions-table.component.ts | 2 +- .../remove-other-entities-confirm.component.html | 2 +- .../remove-other-entities-confirm.component.ts | 2 +- .../vc/repository-settings.component.html | 2 +- .../vc/repository-settings.component.scss | 2 +- .../vc/repository-settings.component.ts | 2 +- .../components/vc/version-control.component.html | 2 +- .../components/vc/version-control.component.scss | 2 +- .../components/vc/version-control.component.ts | 2 +- .../home/components/vc/version-control.scss | 2 +- .../custom-action-pretty-editor.component.html | 2 +- .../custom-action-pretty-editor.component.scss | 2 +- .../custom-action-pretty-editor.component.ts | 2 +- ...m-action-pretty-resources-tabs.component.html | 2 +- ...m-action-pretty-resources-tabs.component.scss | 2 +- ...tom-action-pretty-resources-tabs.component.ts | 2 +- .../widget/action/custom-action.models.ts | 2 +- .../manage-widget-actions-dialog.component.html | 2 +- .../manage-widget-actions-dialog.component.ts | 2 +- .../action/manage-widget-actions.component.html | 2 +- .../manage-widget-actions.component.models.ts | 2 +- .../action/manage-widget-actions.component.scss | 2 +- .../action/manage-widget-actions.component.ts | 2 +- .../action/mobile-action-editor.component.html | 2 +- .../action/mobile-action-editor.component.ts | 2 +- .../widget/action/mobile-action-editor.models.ts | 2 +- .../action/widget-action-dialog.component.html | 2 +- .../action/widget-action-dialog.component.ts | 2 +- .../alarm-count-basic-config.component.html | 2 +- .../alarm/alarm-count-basic-config.component.ts | 2 +- .../alarms-table-basic-config.component.html | 2 +- .../alarm/alarms-table-basic-config.component.ts | 2 +- .../widget/config/basic/basic-config.scss | 3 +-- .../config/basic/basic-widget-config.module.ts | 2 +- .../cards/aggregated-data-key-row.component.html | 2 +- .../cards/aggregated-data-key-row.component.scss | 3 +-- .../cards/aggregated-data-key-row.component.ts | 2 +- .../aggregated-data-keys-panel.component.html | 2 +- .../aggregated-data-keys-panel.component.scss | 3 +-- .../aggregated-data-keys-panel.component.ts | 2 +- ...egated-value-card-basic-config.component.html | 2 +- ...gregated-value-card-basic-config.component.ts | 2 +- .../progress-bar-basic-config.component.html | 2 +- .../cards/progress-bar-basic-config.component.ts | 2 +- .../simple-card-basic-config.component.html | 2 +- .../cards/simple-card-basic-config.component.ts | 2 +- .../timeseries-table-basic-config.component.html | 2 +- .../timeseries-table-basic-config.component.ts | 2 +- .../cards/value-card-basic-config.component.html | 2 +- .../cards/value-card-basic-config.component.ts | 2 +- .../value-chart-card-basic-config.component.html | 2 +- .../value-chart-card-basic-config.component.ts | 2 +- ...chart-with-labels-basic-config.component.html | 2 +- ...r-chart-with-labels-basic-config.component.ts | 2 +- .../chart/doughnut-basic-config.component.html | 2 +- .../chart/doughnut-basic-config.component.ts | 2 +- .../basic/chart/flot-basic-config.component.html | 2 +- .../basic/chart/flot-basic-config.component.ts | 2 +- .../range-chart-basic-config.component.html | 2 +- .../chart/range-chart-basic-config.component.ts | 2 +- .../basic/common/data-key-row.component.html | 2 +- .../basic/common/data-key-row.component.scss | 3 +-- .../basic/common/data-key-row.component.ts | 2 +- .../basic/common/data-keys-panel.component.html | 2 +- .../basic/common/data-keys-panel.component.scss | 3 +-- .../basic/common/data-keys-panel.component.ts | 2 +- .../common/widget-actions-panel.component.html | 2 +- .../common/widget-actions-panel.component.ts | 2 +- .../entities-table-basic-config.component.html | 2 +- .../entities-table-basic-config.component.ts | 2 +- .../entity-count-basic-config.component.html | 2 +- .../entity-count-basic-config.component.ts | 2 +- .../analog-gauge-basic-config.component.html | 2 +- .../gauge/analog-gauge-basic-config.component.ts | 2 +- .../compass-gauge-basic-config.component.html | 2 +- .../compass-gauge-basic-config.component.ts | 2 +- .../gauge/radial-gauge-basic-config.component.ts | 2 +- ...mometer-scale-gauge-basic-config.component.ts | 2 +- .../battery-level-basic-config.component.html | 2 +- .../battery-level-basic-config.component.ts | 2 +- ...liquid-level-card-basic-config.component.html | 2 +- .../liquid-level-card-basic-config.component.ts | 2 +- .../signal-strength-basic-config.component.html | 2 +- .../signal-strength-basic-config.component.ts | 2 +- ...d-speed-direction-basic-config.component.html | 2 +- ...ind-speed-direction-basic-config.component.ts | 2 +- .../config/data-key-config-dialog.component.html | 2 +- .../config/data-key-config-dialog.component.scss | 2 +- .../config/data-key-config-dialog.component.ts | 2 +- .../widget/config/data-key-config.component.html | 2 +- .../widget/config/data-key-config.component.ts | 2 +- .../widget/config/data-keys.component.html | 2 +- .../widget/config/data-keys.component.models.ts | 2 +- .../widget/config/data-keys.component.scss | 3 +-- .../widget/config/data-keys.component.ts | 2 +- .../widget/config/datasource.component.html | 2 +- .../widget/config/datasource.component.models.ts | 2 +- .../widget/config/datasource.component.scss | 2 +- .../widget/config/datasource.component.ts | 2 +- .../widget/config/datasources.component.html | 2 +- .../widget/config/datasources.component.scss | 2 +- .../widget/config/datasources.component.ts | 2 +- .../timewindow-config-panel.component.html | 2 +- .../config/timewindow-config-panel.component.ts | 2 +- .../config/timewindow-style-panel.component.html | 2 +- .../config/timewindow-style-panel.component.scss | 3 +-- .../config/timewindow-style-panel.component.ts | 2 +- .../config/timewindow-style.component.html | 2 +- .../widget/config/timewindow-style.component.ts | 2 +- .../config/widget-config-components.module.ts | 2 +- .../config/widget-config.component.models.ts | 2 +- .../widget/config/widget-settings.component.html | 2 +- .../widget/config/widget-settings.component.scss | 2 +- .../widget/config/widget-settings.component.ts | 2 +- .../dialog/custom-dialog-container.component.ts | 2 +- .../widget/dialog/custom-dialog.component.ts | 2 +- .../widget/dialog/custom-dialog.service.ts | 2 +- .../dialog/embed-dashboard-dialog-token.ts | 2 +- .../dialog/embed-dashboard-dialog.component.html | 2 +- .../dialog/embed-dashboard-dialog.component.scss | 2 +- .../dialog/embed-dashboard-dialog.component.ts | 2 +- .../widget/dynamic-widget.component.ts | 2 +- .../lib/alarm/alarms-table-widget.component.html | 2 +- .../lib/alarm/alarms-table-widget.component.scss | 2 +- .../lib/alarm/alarms-table-widget.component.ts | 2 +- .../widget/lib/analogue-compass.models.ts | 2 +- .../components/widget/lib/analogue-compass.ts | 2 +- .../widget/lib/analogue-gauge.models.ts | 2 +- .../widget/lib/analogue-linear-gauge.models.ts | 2 +- .../widget/lib/analogue-linear-gauge.ts | 2 +- .../widget/lib/analogue-radial-gauge.models.ts | 2 +- .../widget/lib/analogue-radial-gauge.ts | 2 +- .../widget/lib/canvas-digital-gauge.ts | 2 +- .../aggregated-value-card-widget.component.html | 2 +- .../aggregated-value-card-widget.component.scss | 2 +- .../aggregated-value-card-widget.component.ts | 2 +- .../lib/cards/aggregated-value-card.models.ts | 2 +- .../lib/cards/progress-bar-widget.component.html | 2 +- .../lib/cards/progress-bar-widget.component.scss | 2 +- .../lib/cards/progress-bar-widget.component.ts | 2 +- .../lib/cards/progress-bar-widget.models.ts | 2 +- .../lib/cards/value-card-widget.component.html | 2 +- .../lib/cards/value-card-widget.component.scss | 2 +- .../lib/cards/value-card-widget.component.ts | 2 +- .../widget/lib/cards/value-card-widget.models.ts | 2 +- .../cards/value-chart-card-widget.component.html | 2 +- .../cards/value-chart-card-widget.component.scss | 2 +- .../cards/value-chart-card-widget.component.ts | 2 +- .../lib/cards/value-chart-card-widget.models.ts | 2 +- .../bar-chart-with-labels-widget.component.html | 2 +- .../bar-chart-with-labels-widget.component.scss | 3 +-- .../bar-chart-with-labels-widget.component.ts | 2 +- .../chart/bar-chart-with-labels-widget.models.ts | 2 +- .../lib/chart/doughnut-widget.component.html | 2 +- .../lib/chart/doughnut-widget.component.scss | 3 +-- .../lib/chart/doughnut-widget.component.ts | 2 +- .../widget/lib/chart/doughnut-widget.models.ts | 2 +- .../widget/lib/chart/echarts-widget.models.ts | 2 +- .../lib/chart/range-chart-widget.component.html | 2 +- .../lib/chart/range-chart-widget.component.scss | 3 +-- .../lib/chart/range-chart-widget.component.ts | 2 +- .../lib/chart/range-chart-widget.models.ts | 2 +- .../widget/lib/count/count-widget.component.html | 2 +- .../widget/lib/count/count-widget.component.scss | 2 +- .../widget/lib/count/count-widget.component.ts | 2 +- .../widget/lib/count/count-widget.models.ts | 2 +- .../date-range-navigator-panel.component.html | 2 +- .../date-range-navigator-panel.component.scss | 2 +- .../date-range-navigator.component.html | 2 +- .../date-range-navigator.component.scss | 2 +- .../date-range-navigator.component.ts | 2 +- .../date-range-navigator.models.ts | 2 +- .../widget/lib/digital-gauge.models.ts | 2 +- .../home/components/widget/lib/digital-gauge.ts | 2 +- .../lib/display-columns-panel.component.html | 2 +- .../lib/display-columns-panel.component.scss | 2 +- .../lib/display-columns-panel.component.ts | 2 +- .../lib/edges-overview-widget.component.html | 2 +- .../lib/edges-overview-widget.component.scss | 2 +- .../lib/edges-overview-widget.component.ts | 2 +- .../widget/lib/edges-overview-widget.models.ts | 2 +- .../entities-hierarchy-widget.component.html | 2 +- .../entities-hierarchy-widget.component.scss | 2 +- .../entities-hierarchy-widget.component.ts | 2 +- .../entity/entities-hierarchy-widget.models.ts | 2 +- .../entity/entities-table-widget.component.html | 2 +- .../entity/entities-table-widget.component.scss | 2 +- .../entity/entities-table-widget.component.ts | 2 +- .../widget/lib/flot-widget.component.html | 2 +- .../widget/lib/flot-widget.component.ts | 2 +- .../components/widget/lib/flot-widget.models.ts | 2 +- .../home/components/widget/lib/flot-widget.ts | 2 +- .../device-gateway-command.component.html | 2 +- .../device-gateway-command.component.scss | 2 +- .../gateway/device-gateway-command.component.ts | 2 +- .../gateway/gateway-configuration.component.html | 2 +- .../gateway/gateway-configuration.component.scss | 2 +- .../gateway/gateway-configuration.component.ts | 2 +- .../gateway/gateway-connectors.component.html | 2 +- .../gateway/gateway-connectors.component.scss | 2 +- .../lib/gateway/gateway-connectors.component.ts | 2 +- .../lib/gateway/gateway-form.component.html | 2 +- .../lib/gateway/gateway-form.component.scss | 2 +- .../widget/lib/gateway/gateway-form.component.ts | 2 +- .../widget/lib/gateway/gateway-form.models.ts | 2 +- .../lib/gateway/gateway-logs.component.html | 2 +- .../lib/gateway/gateway-logs.component.scss | 2 +- .../widget/lib/gateway/gateway-logs.component.ts | 2 +- .../gateway-remote-configuration-dialog.html | 2 +- .../gateway-remote-configuration-dialog.ts | 2 +- .../gateway/gateway-service-rpc.component.html | 2 +- .../gateway/gateway-service-rpc.component.scss | 2 +- .../lib/gateway/gateway-service-rpc.component.ts | 2 +- .../gateway/gateway-statistics.component.html | 3 +-- .../gateway/gateway-statistics.component.scss | 2 +- .../lib/gateway/gateway-statistics.component.ts | 2 +- .../widget/lib/gateway/gateway-widget.models.ts | 2 +- .../home-page/add-doc-link-dialog.component.html | 2 +- .../home-page/add-doc-link-dialog.component.scss | 2 +- .../home-page/add-doc-link-dialog.component.ts | 2 +- .../add-quick-link-dialog.component.html | 2 +- .../add-quick-link-dialog.component.scss | 2 +- .../home-page/add-quick-link-dialog.component.ts | 2 +- .../home-page/cluster-info-table.component.html | 2 +- .../home-page/cluster-info-table.component.scss | 2 +- .../home-page/cluster-info-table.component.ts | 2 +- .../home-page/configured-features.component.html | 2 +- .../home-page/configured-features.component.scss | 3 +-- .../home-page/configured-features.component.ts | 2 +- .../widget/lib/home-page/doc-link.component.html | 2 +- .../widget/lib/home-page/doc-link.component.ts | 2 +- .../home-page/doc-links-widget.component.html | 2 +- .../lib/home-page/doc-links-widget.component.ts | 2 +- .../home-page/edit-links-dialog.component.html | 2 +- .../home-page/edit-links-dialog.component.scss | 2 +- .../lib/home-page/edit-links-dialog.component.ts | 2 +- ...tting-started-completed-dialog.component.html | 2 +- ...tting-started-completed-dialog.component.scss | 2 +- ...getting-started-completed-dialog.component.ts | 2 +- .../getting-started-widget.component.html | 2 +- .../getting-started-widget.component.scss | 3 +-- .../getting-started-widget.component.ts | 2 +- .../widget/lib/home-page/home-page-widget.scss | 2 +- .../lib/home-page/home-page-widgets.module.ts | 2 +- .../widget/lib/home-page/home-page.scss | 3 +-- .../widget/lib/home-page/link.component.scss | 2 +- .../lib/home-page/links-widget.component.scss | 3 +-- .../lib/home-page/quick-link.component.html | 2 +- .../widget/lib/home-page/quick-link.component.ts | 2 +- .../home-page/quick-links-widget.component.html | 2 +- .../home-page/quick-links-widget.component.ts | 2 +- .../recent-dashboards-widget.component.html | 2 +- .../recent-dashboards-widget.component.scss | 2 +- .../recent-dashboards-widget.component.ts | 2 +- .../home-page/usage-info-widget.component.html | 2 +- .../home-page/usage-info-widget.component.scss | 2 +- .../lib/home-page/usage-info-widget.component.ts | 2 +- .../lib/home-page/version-info.component.html | 2 +- .../lib/home-page/version-info.component.scss | 3 +-- .../lib/home-page/version-info.component.ts | 2 +- .../battery-level-widget.component.html | 2 +- .../battery-level-widget.component.scss | 2 +- .../indicator/battery-level-widget.component.ts | 2 +- .../lib/indicator/battery-level-widget.models.ts | 2 +- .../indicator/liquid-level-widget.component.html | 2 +- .../indicator/liquid-level-widget.component.scss | 2 +- .../indicator/liquid-level-widget.component.ts | 2 +- .../lib/indicator/liquid-level-widget.models.ts | 2 +- .../signal-strength-widget.component.html | 2 +- .../signal-strength-widget.component.scss | 2 +- .../signal-strength-widget.component.ts | 16 ++++++++++++++++ .../indicator/signal-strength-widget.models.ts | 2 +- .../widget/lib/json-input-widget.component.html | 2 +- .../widget/lib/json-input-widget.component.scss | 2 +- .../widget/lib/json-input-widget.component.ts | 2 +- .../components/widget/lib/legend.component.html | 2 +- .../components/widget/lib/legend.component.scss | 2 +- .../components/widget/lib/legend.component.ts | 2 +- .../home/components/widget/lib/maps/circle.ts | 2 +- .../widget/lib/maps/common-maps-utils.ts | 2 +- .../dialogs/select-entity-dialog.component.html | 2 +- .../dialogs/select-entity-dialog.component.scss | 2 +- .../dialogs/select-entity-dialog.component.ts | 2 +- .../components/widget/lib/maps/leaflet-map.ts | 2 +- .../components/widget/lib/maps/map-models.ts | 2 +- .../widget/lib/maps/map-widget.interface.ts | 2 +- .../components/widget/lib/maps/map-widget2.ts | 2 +- .../components/widget/lib/maps/maps-utils.ts | 2 +- .../home/components/widget/lib/maps/markers.scss | 2 +- .../home/components/widget/lib/maps/markers.ts | 2 +- .../home/components/widget/lib/maps/polygon.ts | 2 +- .../home/components/widget/lib/maps/polyline.ts | 2 +- .../widget/lib/maps/providers/google-map.ts | 2 +- .../widget/lib/maps/providers/here-map.ts | 2 +- .../widget/lib/maps/providers/image-map.ts | 2 +- .../widget/lib/maps/providers/index.ts | 2 +- .../widget/lib/maps/providers/openstreet-map.ts | 2 +- .../widget/lib/maps/providers/tencent-map.ts | 2 +- .../widget/lib/markdown-widget.component.html | 2 +- .../widget/lib/markdown-widget.component.ts | 2 +- .../lib/multiple-input-widget.component.html | 2 +- .../lib/multiple-input-widget.component.scss | 2 +- .../lib/multiple-input-widget.component.ts | 2 +- .../lib/navigation-card-widget.component.html | 2 +- .../lib/navigation-card-widget.component.scss | 2 +- .../lib/navigation-card-widget.component.ts | 2 +- .../lib/navigation-cards-widget.component.html | 2 +- .../lib/navigation-cards-widget.component.scss | 2 +- .../lib/navigation-cards-widget.component.ts | 2 +- .../widget/lib/photo-camera-input.component.html | 2 +- .../widget/lib/photo-camera-input.component.scss | 2 +- .../widget/lib/photo-camera-input.component.ts | 2 +- .../widget/lib/qrcode-widget.component.html | 2 +- .../widget/lib/qrcode-widget.component.ts | 2 +- .../widget/lib/rpc/knob.component.html | 2 +- .../widget/lib/rpc/knob.component.scss | 2 +- .../components/widget/lib/rpc/knob.component.ts | 2 +- .../widget/lib/rpc/led-indicator.component.html | 2 +- .../widget/lib/rpc/led-indicator.component.scss | 2 +- .../widget/lib/rpc/led-indicator.component.ts | 2 +- .../lib/rpc/persistent-add-dialog.component.html | 2 +- .../lib/rpc/persistent-add-dialog.component.scss | 2 +- .../lib/rpc/persistent-add-dialog.component.ts | 2 +- .../rpc/persistent-details-dialog.component.html | 2 +- .../rpc/persistent-details-dialog.component.scss | 2 +- .../rpc/persistent-details-dialog.component.ts | 2 +- .../rpc/persistent-filter-panel.component.html | 2 +- .../rpc/persistent-filter-panel.component.scss | 2 +- .../lib/rpc/persistent-filter-panel.component.ts | 2 +- .../lib/rpc/persistent-table.component.html | 2 +- .../lib/rpc/persistent-table.component.scss | 2 +- .../widget/lib/rpc/persistent-table.component.ts | 2 +- .../widget/lib/rpc/round-switch.component.html | 2 +- .../widget/lib/rpc/round-switch.component.scss | 2 +- .../widget/lib/rpc/round-switch.component.ts | 2 +- .../widget/lib/rpc/rpc-widgets.module.ts | 2 +- .../widget/lib/rpc/switch.component.html | 2 +- .../widget/lib/rpc/switch.component.scss | 2 +- .../widget/lib/rpc/switch.component.ts | 2 +- .../components/widget/lib/settings.models.ts | 2 +- .../alarm-count-widget-settings.component.html | 2 +- .../alarm-count-widget-settings.component.ts | 2 +- .../alarms-table-key-settings.component.html | 2 +- .../alarm/alarms-table-key-settings.component.ts | 2 +- .../alarms-table-widget-settings.component.html | 2 +- .../alarms-table-widget-settings.component.ts | 2 +- ...egated-value-card-key-settings.component.html | 2 +- ...gregated-value-card-key-settings.component.ts | 2 +- ...ted-value-card-widget-settings.component.html | 2 +- ...gated-value-card-widget-settings.component.ts | 2 +- ...ashboard-state-widget-settings.component.html | 2 +- .../dashboard-state-widget-settings.component.ts | 2 +- ...quick-overview-widget-settings.component.html | 2 +- ...e-quick-overview-widget-settings.component.ts | 2 +- .../html-card-widget-settings.component.html | 2 +- .../cards/html-card-widget-settings.component.ts | 2 +- .../cards/label-widget-label.component.html | 2 +- .../cards/label-widget-label.component.scss | 2 +- .../cards/label-widget-label.component.ts | 2 +- .../cards/label-widget-settings.component.html | 2 +- .../cards/label-widget-settings.component.ts | 2 +- .../markdown-widget-settings.component.html | 2 +- .../cards/markdown-widget-settings.component.ts | 2 +- .../progress-bar-widget-settings.component.html | 2 +- .../progress-bar-widget-settings.component.ts | 2 +- .../cards/qrcode-widget-settings.component.html | 2 +- .../cards/qrcode-widget-settings.component.ts | 2 +- .../simple-card-widget-settings.component.html | 2 +- .../simple-card-widget-settings.component.ts | 2 +- .../timeseries-table-key-settings.component.html | 2 +- .../timeseries-table-key-settings.component.ts | 2 +- ...ries-table-latest-key-settings.component.html | 2 +- ...series-table-latest-key-settings.component.ts | 2 +- ...meseries-table-widget-settings.component.html | 2 +- ...timeseries-table-widget-settings.component.ts | 2 +- .../value-card-widget-settings.component.html | 2 +- .../value-card-widget-settings.component.ts | 2 +- ...lue-chart-card-widget-settings.component.html | 2 +- ...value-chart-card-widget-settings.component.ts | 2 +- ...rt-with-labels-widget-settings.component.html | 2 +- ...hart-with-labels-widget-settings.component.ts | 2 +- .../chart/chart-widget-settings.component.html | 2 +- .../chart/chart-widget-settings.component.ts | 2 +- ...doughnut-chart-widget-settings.component.html | 2 +- .../doughnut-chart-widget-settings.component.ts | 2 +- .../doughnut-widget-settings.component.html | 2 +- .../chart/doughnut-widget-settings.component.ts | 2 +- .../chart/flot-bar-key-settings.component.html | 2 +- .../chart/flot-bar-key-settings.component.ts | 2 +- .../flot-bar-widget-settings.component.html | 2 +- .../chart/flot-bar-widget-settings.component.ts | 2 +- .../chart/flot-key-settings.component.html | 2 +- .../chart/flot-key-settings.component.ts | 2 +- .../flot-latest-key-settings.component.html | 2 +- .../chart/flot-latest-key-settings.component.ts | 2 +- .../chart/flot-line-key-settings.component.html | 2 +- .../chart/flot-line-key-settings.component.ts | 2 +- .../flot-line-widget-settings.component.html | 2 +- .../chart/flot-line-widget-settings.component.ts | 2 +- .../chart/flot-pie-key-settings.component.html | 2 +- .../chart/flot-pie-key-settings.component.ts | 2 +- .../flot-pie-widget-settings.component.html | 2 +- .../chart/flot-pie-widget-settings.component.ts | 2 +- .../settings/chart/flot-threshold.component.html | 2 +- .../settings/chart/flot-threshold.component.scss | 3 +-- .../settings/chart/flot-threshold.component.ts | 2 +- .../chart/flot-widget-settings.component.html | 2 +- .../chart/flot-widget-settings.component.ts | 2 +- .../settings/chart/label-data-key.component.html | 2 +- .../settings/chart/label-data-key.component.scss | 2 +- .../settings/chart/label-data-key.component.ts | 2 +- .../range-chart-widget-settings.component.html | 2 +- .../range-chart-widget-settings.component.ts | 2 +- .../background-settings-panel.component.html | 2 +- .../background-settings-panel.component.scss | 3 +-- .../background-settings-panel.component.ts | 2 +- .../common/background-settings.component.html | 2 +- .../common/background-settings.component.scss | 2 +- .../common/background-settings.component.ts | 2 +- .../common/color-range-list.component.html | 2 +- .../common/color-range-list.component.ts | 2 +- .../common/color-range-panel.component.html | 2 +- .../common/color-range-panel.component.ts | 2 +- .../common/color-range-settings.component.html | 2 +- .../common/color-range-settings.component.ts | 2 +- .../common/color-settings-panel.component.html | 2 +- .../common/color-settings-panel.component.scss | 3 +-- .../common/color-settings-panel.component.ts | 2 +- .../common/color-settings.component.html | 2 +- .../settings/common/color-settings.component.ts | 2 +- .../common/count-widget-settings.component.html | 2 +- .../common/count-widget-settings.component.ts | 2 +- .../common/css-unit-select.component.html | 2 +- .../settings/common/css-unit-select.component.ts | 2 +- .../common/date-format-select.component.html | 2 +- .../common/date-format-select.component.ts | 2 +- .../date-format-settings-panel.component.html | 2 +- .../date-format-settings-panel.component.scss | 3 +-- .../date-format-settings-panel.component.ts | 2 +- .../common/font-settings-panel.component.html | 2 +- .../common/font-settings-panel.component.scss | 2 +- .../common/font-settings-panel.component.ts | 2 +- .../settings/common/font-settings.component.html | 2 +- .../settings/common/font-settings.component.ts | 2 +- .../common/image-cards-select.component.html | 2 +- .../common/image-cards-select.component.scss | 2 +- .../common/image-cards-select.component.ts | 2 +- .../settings/common/legend-config.component.html | 2 +- .../settings/common/legend-config.component.ts | 2 +- .../settings/common/value-source.component.html | 2 +- .../settings/common/value-source.component.ts | 2 +- .../settings/common/widget-font.component.html | 2 +- .../lib/settings/common/widget-font.component.ts | 2 +- .../common/widget-settings-common.module.ts | 2 +- .../device-key-autocomplete.component.html | 2 +- .../control/device-key-autocomplete.component.ts | 2 +- .../knob-control-widget-settings.component.html | 2 +- .../knob-control-widget-settings.component.ts | 2 +- .../led-indicator-widget-settings.component.html | 2 +- .../led-indicator-widget-settings.component.ts | 2 +- ...rsistent-table-widget-settings.component.html | 2 +- ...persistent-table-widget-settings.component.ts | 2 +- .../round-switch-widget-settings.component.html | 2 +- .../round-switch-widget-settings.component.ts | 2 +- .../control/rpc-button-style.component.html | 2 +- .../control/rpc-button-style.component.ts | 2 +- .../rpc-shell-widget-settings.component.html | 2 +- .../rpc-shell-widget-settings.component.ts | 2 +- .../rpc-terminal-widget-settings.component.html | 2 +- .../rpc-terminal-widget-settings.component.ts | 2 +- .../send-rpc-widget-settings.component.html | 2 +- .../send-rpc-widget-settings.component.ts | 2 +- .../slide-toggle-widget-settings.component.html | 2 +- .../slide-toggle-widget-settings.component.ts | 2 +- ...switch-control-widget-settings.component.html | 2 +- .../switch-control-widget-settings.component.ts | 2 +- .../control/switch-rpc-settings.component.html | 2 +- .../control/switch-rpc-settings.component.ts | 2 +- ...vice-attribute-widget-settings.component.html | 2 +- ...device-attribute-widget-settings.component.ts | 2 +- ...ange-navigator-widget-settings.component.html | 2 +- ...-range-navigator-widget-settings.component.ts | 2 +- ...ties-hierarchy-widget-settings.component.html | 2 +- ...tities-hierarchy-widget-settings.component.ts | 2 +- .../entities-table-key-settings.component.html | 2 +- .../entities-table-key-settings.component.ts | 2 +- ...entities-table-widget-settings.component.html | 2 +- .../entities-table-widget-settings.component.ts | 2 +- .../entity-count-widget-settings.component.html | 2 +- .../entity-count-widget-settings.component.ts | 2 +- ...-single-device-widget-settings.component.html | 2 +- ...ig-single-device-widget-settings.component.ts | 2 +- ...gateway-config-widget-settings.component.html | 2 +- .../gateway-config-widget-settings.component.ts | 2 +- ...gateway-events-widget-settings.component.html | 2 +- .../gateway-events-widget-settings.component.ts | 2 +- .../gateway/gateway-logs-settings.component.html | 2 +- .../gateway/gateway-logs-settings.component.ts | 2 +- .../gateway-service-rpc-settings.component.html | 2 +- .../gateway-service-rpc-settings.component.ts | 2 +- ...alogue-compass-widget-settings.component.html | 2 +- ...analogue-compass-widget-settings.component.ts | 2 +- ...analogue-gauge-widget-settings.component.html | 2 +- .../analogue-gauge-widget-settings.component.ts | 2 +- ...gue-linear-gauge-widget-settings.component.ts | 2 +- ...gue-radial-gauge-widget-settings.component.ts | 2 +- .../digital-gauge-widget-settings.component.html | 2 +- .../digital-gauge-widget-settings.component.ts | 2 +- .../gauge/fixed-color-level.component.html | 2 +- .../gauge/fixed-color-level.component.scss | 2 +- .../gauge/fixed-color-level.component.ts | 2 +- .../lib/settings/gauge/tick-value.component.html | 2 +- .../lib/settings/gauge/tick-value.component.scss | 2 +- .../lib/settings/gauge/tick-value.component.ts | 2 +- .../gpio-control-widget-settings.component.html | 2 +- .../gpio-control-widget-settings.component.ts | 2 +- .../lib/settings/gpio/gpio-item.component.html | 2 +- .../lib/settings/gpio/gpio-item.component.scss | 2 +- .../lib/settings/gpio/gpio-item.component.ts | 2 +- .../gpio-panel-widget-settings.component.html | 2 +- .../gpio/gpio-panel-widget-settings.component.ts | 2 +- .../doc-links-widget-settings.component.html | 2 +- .../doc-links-widget-settings.component.ts | 2 +- .../quick-links-widget-settings.component.html | 2 +- .../quick-links-widget-settings.component.ts | 2 +- .../battery-level-widget-settings.component.html | 2 +- .../battery-level-widget-settings.component.ts | 2 +- ...uid-level-card-widget-settings.component.html | 2 +- ...iquid-level-card-widget-settings.component.ts | 2 +- ...ignal-strength-widget-settings.component.html | 2 +- .../signal-strength-widget-settings.component.ts | 2 +- .../input/datakey-select-option.component.html | 2 +- .../input/datakey-select-option.component.scss | 2 +- .../input/datakey-select-option.component.ts | 2 +- ...evice-claiming-widget-settings.component.html | 2 +- .../device-claiming-widget-settings.component.ts | 2 +- ...o-camera-input-widget-settings.component.html | 2 +- ...oto-camera-input-widget-settings.component.ts | 2 +- ...ate-attribute-general-settings.component.html | 2 +- ...pdate-attribute-general-settings.component.ts | 2 +- ...lean-attribute-widget-settings.component.html | 2 +- ...oolean-attribute-widget-settings.component.ts | 2 +- ...date-attribute-widget-settings.component.html | 2 +- ...e-date-attribute-widget-settings.component.ts | 2 +- ...uble-attribute-widget-settings.component.html | 2 +- ...double-attribute-widget-settings.component.ts | 2 +- ...mage-attribute-widget-settings.component.html | 2 +- ...-image-attribute-widget-settings.component.ts | 2 +- ...eger-attribute-widget-settings.component.html | 2 +- ...nteger-attribute-widget-settings.component.ts | 2 +- ...json-attribute-widget-settings.component.html | 2 +- ...e-json-attribute-widget-settings.component.ts | 2 +- ...tion-attribute-widget-settings.component.html | 2 +- ...cation-attribute-widget-settings.component.ts | 2 +- ...ltiple-attributes-key-settings.component.html | 2 +- ...multiple-attributes-key-settings.component.ts | 2 +- ...ple-attributes-widget-settings.component.html | 2 +- ...tiple-attributes-widget-settings.component.ts | 2 +- ...ring-attribute-widget-settings.component.html | 2 +- ...string-attribute-widget-settings.component.ts | 2 +- .../settings/map/circle-settings.component.html | 2 +- .../settings/map/circle-settings.component.ts | 2 +- .../map/common-map-settings.component.html | 2 +- .../map/common-map-settings.component.ts | 2 +- .../datasources-key-autocomplete.component.html | 2 +- .../datasources-key-autocomplete.component.ts | 2 +- .../google-map-provider-settings.component.html | 2 +- .../google-map-provider-settings.component.ts | 2 +- .../here-map-provider-settings.component.html | 2 +- .../map/here-map-provider-settings.component.ts | 2 +- .../image-map-provider-settings.component.html | 2 +- .../map/image-map-provider-settings.component.ts | 2 +- .../map/map-editor-settings.component.html | 2 +- .../map/map-editor-settings.component.ts | 2 +- .../map/map-provider-settings.component.html | 2 +- .../map/map-provider-settings.component.ts | 2 +- .../lib/settings/map/map-settings.component.html | 2 +- .../lib/settings/map/map-settings.component.ts | 2 +- .../map/map-widget-settings.component.html | 2 +- .../map/map-widget-settings.component.ts | 2 +- .../marker-clustering-settings.component.html | 2 +- .../map/marker-clustering-settings.component.ts | 2 +- .../settings/map/markers-settings.component.html | 2 +- .../settings/map/markers-settings.component.ts | 2 +- ...enstreet-map-provider-settings.component.html | 2 +- ...openstreet-map-provider-settings.component.ts | 2 +- .../settings/map/polygon-settings.component.html | 2 +- .../settings/map/polygon-settings.component.ts | 2 +- .../map/route-map-settings.component.html | 2 +- .../settings/map/route-map-settings.component.ts | 2 +- .../map/route-map-widget-settings.component.html | 2 +- .../map/route-map-widget-settings.component.ts | 2 +- .../tencent-map-provider-settings.component.html | 2 +- .../tencent-map-provider-settings.component.ts | 2 +- ...trip-animation-common-settings.component.html | 2 +- .../trip-animation-common-settings.component.ts | 2 +- ...trip-animation-marker-settings.component.html | 2 +- .../trip-animation-marker-settings.component.ts | 2 +- .../trip-animation-path-settings.component.html | 2 +- .../trip-animation-path-settings.component.ts | 2 +- .../trip-animation-point-settings.component.html | 2 +- .../trip-animation-point-settings.component.ts | 2 +- ...trip-animation-widget-settings.component.html | 2 +- .../trip-animation-widget-settings.component.ts | 2 +- ...avigation-card-widget-settings.component.html | 2 +- .../navigation-card-widget-settings.component.ts | 2 +- ...vigation-cards-widget-settings.component.html | 2 +- ...navigation-cards-widget-settings.component.ts | 2 +- ...peed-direction-widget-settings.component.html | 2 +- ...-speed-direction-widget-settings.component.ts | 2 +- .../lib/settings/widget-settings.module.ts | 2 +- .../widget/lib/settings/widget-settings.scss | 2 +- .../components/widget/lib/table-widget.models.ts | 2 +- .../home/components/widget/lib/table-widget.scss | 2 +- .../lib/timeseries-table-widget.component.html | 2 +- .../lib/timeseries-table-widget.component.scss | 2 +- .../lib/timeseries-table-widget.component.ts | 2 +- .../trip-animation/trip-animation.component.html | 2 +- .../trip-animation/trip-animation.component.scss | 2 +- .../trip-animation/trip-animation.component.ts | 2 +- .../wind-speed-direction-widget.component.html | 2 +- .../wind-speed-direction-widget.component.scss | 2 +- .../wind-speed-direction-widget.component.ts | 2 +- .../wind-speed-direction-widget.models.ts | 2 +- .../widget/widget-component.service.ts | 2 +- .../widget/widget-components.module.ts | 2 +- .../widget/widget-config.component.html | 2 +- .../widget/widget-config.component.scss | 3 +-- .../components/widget/widget-config.component.ts | 2 +- .../widget/widget-container.component.html | 2 +- .../widget/widget-container.component.scss | 3 +-- .../widget/widget-container.component.ts | 2 +- .../widget/widget-preview.component.html | 2 +- .../widget/widget-preview.component.scss | 2 +- .../widget/widget-preview.component.ts | 2 +- .../home/components/widget/widget.component.html | 2 +- .../home/components/widget/widget.component.scss | 2 +- .../home/components/widget/widget.component.ts | 2 +- .../wizard/device-wizard-dialog.component.html | 2 +- .../wizard/device-wizard-dialog.component.scss | 2 +- .../wizard/device-wizard-dialog.component.ts | 2 +- ...dd-entities-to-customer-dialog.component.html | 2 +- .../add-entities-to-customer-dialog.component.ts | 2 +- .../add-entities-to-edge-dialog.component.html | 2 +- .../add-entities-to-edge-dialog.component.ts | 2 +- .../assign-to-customer-dialog.component.html | 2 +- .../assign-to-customer-dialog.component.ts | 2 +- .../modules/home/dialogs/home-dialogs.module.ts | 2 +- .../modules/home/dialogs/home-dialogs.service.ts | 2 +- .../src/app/modules/home/home-routing.module.ts | 2 +- ui-ngx/src/app/modules/home/home.component.html | 2 +- ui-ngx/src/app/modules/home/home.component.scss | 2 +- ui-ngx/src/app/modules/home/home.component.ts | 2 +- ui-ngx/src/app/modules/home/home.module.ts | 2 +- .../modules/home/menu/menu-link.component.html | 2 +- .../modules/home/menu/menu-link.component.scss | 2 +- .../app/modules/home/menu/menu-link.component.ts | 2 +- .../modules/home/menu/menu-toggle.component.html | 2 +- .../modules/home/menu/menu-toggle.component.scss | 2 +- .../modules/home/menu/menu-toggle.component.ts | 2 +- .../modules/home/menu/side-menu.component.html | 2 +- .../modules/home/menu/side-menu.component.scss | 2 +- .../app/modules/home/menu/side-menu.component.ts | 2 +- .../app/modules/home/models/contact.models.ts | 2 +- .../home/models/dashboard-component.models.ts | 2 +- .../models/datasource/attribute-datasource.ts | 2 +- .../home/models/datasource/entity-datasource.ts | 2 +- .../models/datasource/relation-datasource.ts | 2 +- .../entity/entities-table-config.models.ts | 2 +- .../models/entity/entity-component.models.ts | 2 +- .../entity-details-page-component.models.ts | 2 +- .../entity/entity-table-component.models.ts | 2 +- .../home/models/searchable-component.models.ts | 2 +- .../src/app/modules/home/models/services.map.ts | 2 +- .../home/models/widget-component.models.ts | 2 +- .../home/pages/account/account-routing.module.ts | 2 +- .../modules/home/pages/account/account.module.ts | 2 +- .../home/pages/admin/admin-routing.module.ts | 2 +- .../app/modules/home/pages/admin/admin.module.ts | 2 +- .../auto-commit-admin-settings.component.html | 2 +- .../auto-commit-admin-settings.component.ts | 2 +- .../pages/admin/general-settings.component.html | 2 +- .../pages/admin/general-settings.component.scss | 2 +- .../pages/admin/general-settings.component.ts | 2 +- .../pages/admin/home-settings.component.html | 2 +- .../pages/admin/home-settings.component.scss | 2 +- .../home/pages/admin/home-settings.component.ts | 2 +- .../home/pages/admin/mail-server.component.html | 2 +- .../home/pages/admin/mail-server.component.scss | 2 +- .../home/pages/admin/mail-server.component.ts | 2 +- .../pages/admin/oauth2-settings.component.html | 2 +- .../pages/admin/oauth2-settings.component.scss | 2 +- .../pages/admin/oauth2-settings.component.ts | 2 +- .../home/pages/admin/queue/queue.component.html | 2 +- .../home/pages/admin/queue/queue.component.ts | 2 +- .../admin/queue/queues-table-config.resolver.ts | 2 +- .../repository-admin-settings.component.html | 2 +- .../admin/repository-admin-settings.component.ts | 2 +- .../resources-library-table-config.resolve.ts | 2 +- .../resource/resources-library.component.html | 2 +- .../resource/resources-library.component.ts | 2 +- .../resources-table-header.component.html | 2 +- .../resource/resources-table-header.component.ts | 2 +- .../pages/admin/security-settings.component.html | 2 +- .../pages/admin/security-settings.component.scss | 2 +- .../pages/admin/security-settings.component.ts | 2 +- .../admin/send-test-sms-dialog.component.html | 2 +- .../admin/send-test-sms-dialog.component.ts | 2 +- .../modules/home/pages/admin/settings-card.scss | 2 +- .../home/pages/admin/sms-provider.component.html | 2 +- .../home/pages/admin/sms-provider.component.scss | 2 +- .../home/pages/admin/sms-provider.component.ts | 2 +- .../two-factor-auth-settings.component.html | 2 +- .../two-factor-auth-settings.component.scss | 2 +- .../admin/two-factor-auth-settings.component.ts | 2 +- .../home/pages/alarm/alarm-routing.module.ts | 2 +- .../app/modules/home/pages/alarm/alarm.module.ts | 2 +- .../pages/api-usage/api-usage-routing.module.ts | 2 +- .../pages/api-usage/api-usage.component.html | 2 +- .../pages/api-usage/api-usage.component.scss | 2 +- .../home/pages/api-usage/api-usage.component.ts | 2 +- .../home/pages/api-usage/api-usage.module.ts | 2 +- .../asset-profile-routing.module.ts | 2 +- .../asset-profile-tabs.component.html | 2 +- .../asset-profile-tabs.component.ts | 2 +- .../pages/asset-profile/asset-profile.module.ts | 2 +- .../asset-profiles-table-config.resolver.ts | 2 +- .../home/pages/asset/asset-routing.module.ts | 2 +- .../asset/asset-table-header.component.html | 2 +- .../pages/asset/asset-table-header.component.ts | 2 +- .../home/pages/asset/asset-tabs.component.html | 2 +- .../home/pages/asset/asset-tabs.component.ts | 2 +- .../home/pages/asset/asset.component.html | 2 +- .../home/pages/asset/asset.component.scss | 2 +- .../modules/home/pages/asset/asset.component.ts | 2 +- .../app/modules/home/pages/asset/asset.module.ts | 2 +- .../pages/asset/assets-table-config.resolver.ts | 2 +- .../pages/audit-log/audit-log-routing.module.ts | 2 +- .../home/pages/audit-log/audit-log.module.ts | 2 +- .../pages/customer/customer-routing.module.ts | 2 +- .../pages/customer/customer-tabs.component.html | 2 +- .../pages/customer/customer-tabs.component.ts | 2 +- .../home/pages/customer/customer.component.html | 2 +- .../home/pages/customer/customer.component.scss | 2 +- .../home/pages/customer/customer.component.ts | 2 +- .../home/pages/customer/customer.module.ts | 2 +- .../customer/customers-table-config.resolver.ts | 2 +- .../dashboard/dashboard-form.component.html | 2 +- .../dashboard/dashboard-form.component.scss | 2 +- .../pages/dashboard/dashboard-form.component.ts | 2 +- .../pages/dashboard/dashboard-routing.module.ts | 2 +- .../dashboard/dashboard-tabs.component.html | 2 +- .../pages/dashboard/dashboard-tabs.component.ts | 2 +- .../home/pages/dashboard/dashboard.module.ts | 2 +- .../dashboards-table-config.resolver.ts | 2 +- .../make-dashboard-public-dialog.component.html | 2 +- .../make-dashboard-public-dialog.component.ts | 2 +- ...age-dashboard-customers-dialog.component.html | 2 +- ...anage-dashboard-customers-dialog.component.ts | 2 +- .../device-profile-routing.module.ts | 2 +- .../device-profile-tabs.component.html | 2 +- .../device-profile-tabs.component.ts | 2 +- .../device-profile/device-profile.module.ts | 2 +- .../device-profiles-table-config.resolver.ts | 2 +- ...device-transport-configuration.component.html | 2 +- ...p-device-transport-configuration.component.ts | 2 +- .../default-device-configuration.component.html | 2 +- .../default-device-configuration.component.ts | 2 +- ...device-transport-configuration.component.html | 2 +- ...t-device-transport-configuration.component.ts | 2 +- .../data/device-configuration.component.html | 2 +- .../data/device-configuration.component.ts | 2 +- .../pages/device/data/device-data.component.html | 2 +- .../pages/device/data/device-data.component.ts | 2 +- ...device-transport-configuration.component.html | 2 +- .../device-transport-configuration.component.ts | 2 +- ...device-transport-configuration.component.html | 2 +- ...m-device-transport-configuration.component.ts | 2 +- ...device-transport-configuration.component.html | 2 +- ...t-device-transport-configuration.component.ts | 2 +- ...device-transport-configuration.component.html | 2 +- ...p-device-transport-configuration.component.ts | 2 +- ...vice-check-connectivity-dialog.component.html | 2 +- ...vice-check-connectivity-dialog.component.scss | 3 +-- ...device-check-connectivity-dialog.component.ts | 2 +- .../device-credentials-dialog.component.html | 2 +- .../device-credentials-dialog.component.scss | 2 +- .../device-credentials-dialog.component.ts | 2 +- .../home/pages/device/device-routing.module.ts | 2 +- .../device/device-table-header.component.html | 2 +- .../device/device-table-header.component.ts | 2 +- .../home/pages/device/device-tabs.component.html | 2 +- .../home/pages/device/device-tabs.component.ts | 2 +- .../home/pages/device/device.component.html | 2 +- .../home/pages/device/device.component.scss | 2 +- .../home/pages/device/device.component.ts | 2 +- .../modules/home/pages/device/device.module.ts | 2 +- .../device/devices-table-config.resolver.ts | 2 +- .../edge/edge-instructions-dialog.component.html | 2 +- .../edge/edge-instructions-dialog.component.scss | 3 +-- .../edge/edge-instructions-dialog.component.ts | 2 +- .../home/pages/edge/edge-routing.module.ts | 2 +- .../pages/edge/edge-table-header.component.html | 2 +- .../pages/edge/edge-table-header.component.ts | 2 +- .../home/pages/edge/edge-tabs.component.html | 2 +- .../home/pages/edge/edge-tabs.component.ts | 2 +- .../modules/home/pages/edge/edge.component.html | 2 +- .../modules/home/pages/edge/edge.component.scss | 2 +- .../modules/home/pages/edge/edge.component.ts | 2 +- .../app/modules/home/pages/edge/edge.module.ts | 2 +- .../pages/edge/edges-table-config.resolver.ts | 2 +- .../pages/entities/entities-routing.module.ts | 2 +- .../home/pages/entities/entities.module.ts | 2 +- .../entity-view/entity-view-routing.module.ts | 2 +- .../entity-view-table-header.component.html | 2 +- .../entity-view-table-header.component.ts | 2 +- .../entity-view/entity-view-tabs.component.html | 2 +- .../entity-view/entity-view-tabs.component.ts | 2 +- .../pages/entity-view/entity-view.component.html | 2 +- .../pages/entity-view/entity-view.component.scss | 2 +- .../pages/entity-view/entity-view.component.ts | 2 +- .../home/pages/entity-view/entity-view.module.ts | 2 +- .../entity-views-table-config.resolver.ts | 2 +- .../pages/features/features-routing.module.ts | 2 +- .../home/pages/features/features.module.ts | 2 +- .../home-links/home-links-routing.module.ts | 2 +- .../pages/home-links/home-links.component.html | 2 +- .../pages/home-links/home-links.component.scss | 2 +- .../pages/home-links/home-links.component.ts | 2 +- .../home/pages/home-links/home-links.module.ts | 2 +- .../app/modules/home/pages/home-pages.models.ts | 2 +- .../app/modules/home/pages/home-pages.module.ts | 2 +- .../inbox-notification-dialog.component.html | 2 +- .../inbox-notification-dialog.component.scss | 2 +- .../inbox/inbox-notification-dialog.component.ts | 2 +- .../inbox/inbox-table-config.resolver.ts | 2 +- .../inbox/inbox-table-header.component.html | 2 +- .../inbox/inbox-table-header.component.scss | 2 +- .../inbox/inbox-table-header.component.ts | 2 +- .../notification/notification-routing.module.ts | 2 +- .../pages/notification/notification.module.ts | 2 +- .../recipient-notification-dialog.component.html | 2 +- .../recipient-notification-dialog.component.scss | 2 +- .../recipient-notification-dialog.component.ts | 2 +- .../recipient/recipient-table-config.resolver.ts | 2 +- .../recipient-table-header.component.html | 2 +- .../recipient-table-header.component.scss | 2 +- .../recipient-table-header.component.ts | 2 +- .../rule/escalation-form.component.html | 2 +- .../rule/escalation-form.component.scss | 2 +- .../rule/escalation-form.component.ts | 2 +- .../notification/rule/escalations.component.html | 2 +- .../notification/rule/escalations.component.ts | 2 +- .../rule/rule-notification-dialog.component.html | 2 +- .../rule/rule-notification-dialog.component.scss | 2 +- .../rule/rule-notification-dialog.component.ts | 2 +- .../rule/rule-table-config.resolver.ts | 2 +- .../rule/rule-table-header.component.html | 2 +- .../rule/rule-table-header.component.scss | 2 +- .../rule/rule-table-header.component.ts | 2 +- .../sent/sent-error-dialog.component.html | 2 +- .../sent/sent-error-dialog.component.scss | 2 +- .../sent/sent-error-dialog.component.ts | 2 +- .../sent/sent-notification-dialog.component.html | 2 +- .../sent/sent-notification-dialog.component.scss | 2 +- .../sent/sent-notification-dialog.componet.ts | 2 +- .../sent/sent-table-config.resolver.ts | 2 +- .../notification-setting-form.component.html | 2 +- .../notification-setting-form.component.scss | 2 +- .../notification-setting-form.component.ts | 2 +- .../notification-settings-routing.modules.ts | 2 +- .../notification-settings.component.html | 2 +- .../notification-settings.component.scss | 2 +- .../settings/notification-settings.component.ts | 2 +- .../template/template-configuration.ts | 2 +- .../template-notification-dialog.component.html | 2 +- .../template-notification-dialog.component.scss | 2 +- .../template-notification-dialog.component.ts | 2 +- .../template/template-table-config.resolver.ts | 2 +- .../template-table-header.component.html | 2 +- .../template-table-header.component.scss | 2 +- .../template/template-table-header.component.ts | 2 +- .../ota-update/ota-update-routing.module.ts | 2 +- .../ota-update-table-config.resolve.ts | 2 +- .../pages/ota-update/ota-update.component.html | 2 +- .../pages/ota-update/ota-update.component.ts | 2 +- .../home/pages/ota-update/ota-update.module.ts | 2 +- .../home/pages/profile/profile-routing.module.ts | 2 +- .../home/pages/profile/profile.component.html | 2 +- .../home/pages/profile/profile.component.scss | 2 +- .../home/pages/profile/profile.component.ts | 2 +- .../modules/home/pages/profile/profile.module.ts | 2 +- .../pages/profiles/profiles-routing.module.ts | 2 +- .../home/pages/profiles/profiles.module.ts | 2 +- ui-ngx/src/app/modules/home/pages/public-api.ts | 2 +- .../add-rule-node-dialog.component.html | 2 +- .../add-rule-node-dialog.component.scss | 2 +- .../add-rule-node-link-dialog.component.html | 2 +- .../add-rule-node-link-dialog.component.scss | 2 +- ...create-nested-rulechain-dialog.component.html | 2 +- .../pages/rulechain/link-labels.component.html | 2 +- .../pages/rulechain/link-labels.component.ts | 2 +- .../home/pages/rulechain/rule-node-colors.scss | 2 +- .../rulechain/rule-node-config.component.html | 2 +- .../rulechain/rule-node-config.component.scss | 2 +- .../rulechain/rule-node-config.component.ts | 2 +- .../rulechain/rule-node-details.component.html | 2 +- .../rulechain/rule-node-details.component.scss | 2 +- .../rulechain/rule-node-details.component.ts | 2 +- .../rulechain/rule-node-link.component.html | 2 +- .../pages/rulechain/rule-node-link.component.ts | 2 +- .../rulechain/rulechain-page.component.html | 2 +- .../rulechain/rulechain-page.component.scss | 2 +- .../pages/rulechain/rulechain-page.component.ts | 2 +- .../pages/rulechain/rulechain-page.models.ts | 2 +- .../pages/rulechain/rulechain-routing.module.ts | 2 +- .../rulechain/rulechain-tabs.component.html | 2 +- .../pages/rulechain/rulechain-tabs.component.ts | 2 +- .../pages/rulechain/rulechain.component.html | 2 +- .../pages/rulechain/rulechain.component.scss | 2 +- .../home/pages/rulechain/rulechain.component.ts | 2 +- .../home/pages/rulechain/rulechain.module.ts | 2 +- .../rulechains-table-config.resolver.ts | 2 +- .../home/pages/rulechain/rulenode.component.html | 2 +- .../home/pages/rulechain/rulenode.component.scss | 2 +- .../home/pages/rulechain/rulenode.component.ts | 2 +- .../authentication-dialog.component.scss | 2 +- .../authentication-dialog.map.ts | 2 +- .../backup-code-auth-dialog.component.html | 2 +- .../backup-code-auth-dialog.component.ts | 2 +- .../email-auth-dialog.component.html | 2 +- .../email-auth-dialog.component.ts | 2 +- .../sms-auth-dialog.component.html | 2 +- .../sms-auth-dialog.component.ts | 2 +- .../totp-auth-dialog.component.html | 2 +- .../totp-auth-dialog.component.ts | 2 +- .../pages/security/security-routing.module.ts | 2 +- .../home/pages/security/security.component.html | 2 +- .../home/pages/security/security.component.scss | 2 +- .../home/pages/security/security.component.ts | 2 +- .../home/pages/security/security.module.ts | 2 +- .../tenant-profile-routing.module.ts | 2 +- .../tenant-profile-tabs.component.html | 2 +- .../tenant-profile-tabs.component.ts | 2 +- .../tenant-profile/tenant-profile.module.ts | 2 +- .../tenant-profiles-table-config.resolver.ts | 2 +- .../home/pages/tenant/tenant-routing.module.ts | 2 +- .../home/pages/tenant/tenant-tabs.component.html | 2 +- .../home/pages/tenant/tenant-tabs.component.ts | 2 +- .../home/pages/tenant/tenant.component.html | 2 +- .../home/pages/tenant/tenant.component.scss | 2 +- .../home/pages/tenant/tenant.component.ts | 2 +- .../modules/home/pages/tenant/tenant.module.ts | 2 +- .../tenant/tenants-table-config.resolver.ts | 2 +- .../user/activation-link-dialog.component.html | 2 +- .../user/activation-link-dialog.component.ts | 2 +- .../pages/user/add-user-dialog.component.html | 2 +- .../pages/user/add-user-dialog.component.scss | 2 +- .../home/pages/user/add-user-dialog.component.ts | 2 +- .../home/pages/user/user-routing.module.ts | 2 +- .../home/pages/user/user-tabs.component.html | 2 +- .../home/pages/user/user-tabs.component.ts | 2 +- .../modules/home/pages/user/user.component.html | 2 +- .../modules/home/pages/user/user.component.scss | 2 +- .../modules/home/pages/user/user.component.ts | 2 +- .../app/modules/home/pages/user/user.module.ts | 2 +- .../pages/user/users-table-config.resolver.ts | 2 +- .../modules/home/pages/vc/vc-routing.module.ts | 2 +- .../src/app/modules/home/pages/vc/vc.module.ts | 2 +- .../save-widget-type-as-dialog.component.html | 2 +- .../save-widget-type-as-dialog.component.ts | 2 +- .../select-widget-type-dialog.component.html | 2 +- .../select-widget-type-dialog.component.scss | 2 +- .../select-widget-type-dialog.component.ts | 2 +- .../pages/widget/widget-editor.component.html | 2 +- .../pages/widget/widget-editor.component.scss | 2 +- .../home/pages/widget/widget-editor.component.ts | 2 +- .../home/pages/widget/widget-editor.models.ts | 2 +- .../widget/widget-library-routing.module.ts | 2 +- .../home/pages/widget/widget-library.module.ts | 2 +- .../widget-type-autocomplete.component.html | 2 +- .../widget-type-autocomplete.component.scss | 2 +- .../widget/widget-type-autocomplete.component.ts | 2 +- .../pages/widget/widget-type-tabs.component.html | 2 +- .../pages/widget/widget-type-tabs.component.ts | 2 +- .../home/pages/widget/widget-type.component.html | 2 +- .../home/pages/widget/widget-type.component.ts | 2 +- .../widget/widget-types-table-config.resolver.ts | 2 +- .../widget/widgets-bundle-tabs.component.html | 2 +- .../widget/widgets-bundle-tabs.component.ts | 2 +- .../widget/widgets-bundle-widgets.component.html | 2 +- .../widget/widgets-bundle-widgets.component.scss | 2 +- .../widget/widgets-bundle-widgets.component.ts | 2 +- .../pages/widget/widgets-bundle.component.html | 2 +- .../pages/widget/widgets-bundle.component.scss | 2 +- .../pages/widget/widgets-bundle.component.ts | 2 +- .../widgets-bundles-table-config.resolver.ts | 2 +- ui-ngx/src/app/modules/home/public-api.ts | 2 +- .../app/modules/login/login-routing.module.ts | 2 +- ui-ngx/src/app/modules/login/login.module.ts | 2 +- .../pages/login/create-password.component.html | 2 +- .../pages/login/create-password.component.scss | 2 +- .../pages/login/create-password.component.ts | 2 +- .../login/pages/login/login.component.html | 2 +- .../login/pages/login/login.component.scss | 2 +- .../modules/login/pages/login/login.component.ts | 2 +- .../login/reset-password-request.component.html | 2 +- .../login/reset-password-request.component.scss | 2 +- .../login/reset-password-request.component.ts | 2 +- .../pages/login/reset-password.component.html | 2 +- .../pages/login/reset-password.component.scss | 2 +- .../pages/login/reset-password.component.ts | 2 +- .../login/two-factor-auth-login.component.html | 2 +- .../login/two-factor-auth-login.component.scss | 2 +- .../login/two-factor-auth-login.component.ts | 2 +- .../shared/adapter/custom-datatime-adapter.ts | 2 +- .../animations/speed-dial-fab.animations.ts | 2 +- .../shared/components/breadcrumb.component.html | 2 +- .../shared/components/breadcrumb.component.scss | 2 +- .../shared/components/breadcrumb.component.ts | 2 +- ui-ngx/src/app/shared/components/breadcrumb.ts | 2 +- .../components/button/copy-button.component.html | 2 +- .../components/button/copy-button.component.scss | 2 +- .../components/button/copy-button.component.ts | 2 +- .../button/toggle-password.component.html | 2 +- .../button/toggle-password.component.ts | 2 +- .../shared/components/cheatsheet.component.ts | 2 +- .../components/circular-progress.directive.ts | 2 +- .../shared/components/color-input.component.html | 2 +- .../shared/components/color-input.component.scss | 3 +-- .../shared/components/color-input.component.ts | 2 +- .../color-picker-panel.component.html | 2 +- .../color-picker-panel.component.scss | 2 +- .../color-picker/color-picker-panel.component.ts | 2 +- .../color-picker/color-picker.component.html | 2 +- .../color-picker/color-picker.component.scss | 2 +- .../color-picker/color-picker.component.ts | 2 +- .../app/shared/components/contact.component.html | 2 +- .../app/shared/components/contact.component.ts | 2 +- .../src/app/shared/components/css.component.html | 2 +- .../src/app/shared/components/css.component.scss | 2 +- .../src/app/shared/components/css.component.ts | 2 +- .../dashboard-autocomplete.component.html | 2 +- .../dashboard-autocomplete.component.ts | 2 +- .../dashboard-select-panel.component.html | 2 +- .../dashboard-select-panel.component.scss | 2 +- .../dashboard-select-panel.component.ts | 2 +- .../components/dashboard-select.component.html | 2 +- .../components/dashboard-select.component.scss | 2 +- .../components/dashboard-select.component.ts | 2 +- .../dashboard-state-autocomplete.component.html | 2 +- .../dashboard-state-autocomplete.component.ts | 2 +- .../app/shared/components/dialog.component.ts | 2 +- .../dialog/alert-dialog.component.html | 2 +- .../dialog/alert-dialog.component.scss | 2 +- .../components/dialog/alert-dialog.component.ts | 2 +- .../dialog/color-picker-dialog.component.html | 2 +- .../dialog/color-picker-dialog.component.scss | 2 +- .../dialog/color-picker-dialog.component.ts | 2 +- .../dialog/confirm-dialog.component.html | 2 +- .../dialog/confirm-dialog.component.scss | 2 +- .../dialog/confirm-dialog.component.ts | 2 +- .../dialog/error-alert-dialog.component.html | 2 +- .../dialog/error-alert-dialog.component.scss | 2 +- .../dialog/error-alert-dialog.component.ts | 2 +- .../json-object-edit-dialog.component.html | 2 +- .../dialog/json-object-edit-dialog.component.ts | 2 +- .../dialog/material-icons-dialog.component.html | 2 +- .../dialog/material-icons-dialog.component.scss | 2 +- .../dialog/material-icons-dialog.component.ts | 2 +- .../node-script-test-dialog.component.html | 2 +- .../node-script-test-dialog.component.scss | 2 +- .../dialog/node-script-test-dialog.component.ts | 2 +- .../components/dialog/todo-dialog.component.html | 2 +- .../components/dialog/todo-dialog.component.scss | 2 +- .../components/dialog/todo-dialog.component.ts | 2 +- .../directives/component-outlet.directive.ts | 2 +- .../sring-template-outlet.directive.ts | 2 +- .../directives/tb-json-to-string.directive.ts | 2 +- .../entity/entity-autocomplete.component.html | 2 +- .../entity/entity-autocomplete.component.ts | 2 +- .../entity/entity-gateway-select.component.html | 2 +- .../entity/entity-gateway-select.component.ts | 2 +- .../entity/entity-keys-list.component.html | 2 +- .../entity/entity-keys-list.component.ts | 2 +- .../entity/entity-list-select.component.html | 2 +- .../entity/entity-list-select.component.scss | 2 +- .../entity/entity-list-select.component.ts | 2 +- .../components/entity/entity-list.component.html | 2 +- .../components/entity/entity-list.component.ts | 2 +- .../entity/entity-select.component.html | 2 +- .../entity/entity-select.component.scss | 2 +- .../components/entity/entity-select.component.ts | 2 +- .../entity-subtype-autocomplete.component.html | 2 +- .../entity-subtype-autocomplete.component.ts | 2 +- .../entity/entity-subtype-list.component.html | 2 +- .../entity/entity-subtype-list.component.ts | 2 +- .../entity/entity-subtype-select.component.html | 2 +- .../entity/entity-subtype-select.component.scss | 2 +- .../entity/entity-subtype-select.component.ts | 2 +- .../entity/entity-type-list.component.html | 2 +- .../entity/entity-type-list.component.ts | 2 +- .../entity/entity-type-select.component.html | 2 +- .../entity/entity-type-select.component.scss | 2 +- .../entity/entity-type-select.component.ts | 2 +- .../shared/components/fab-toolbar.component.html | 2 +- .../shared/components/fab-toolbar.component.scss | 2 +- .../shared/components/fab-toolbar.component.ts | 2 +- .../shared/components/file-input.component.html | 2 +- .../shared/components/file-input.component.scss | 2 +- .../shared/components/file-input.component.ts | 2 +- .../components/footer-fab-buttons.component.html | 2 +- .../components/footer-fab-buttons.component.scss | 2 +- .../components/footer-fab-buttons.component.ts | 2 +- .../app/shared/components/footer.component.html | 2 +- .../app/shared/components/footer.component.scss | 2 +- .../app/shared/components/footer.component.ts | 2 +- .../shared/components/fullscreen.directive.ts | 2 +- .../components/grid/scroll-grid-datasource.ts | 2 +- .../components/grid/scroll-grid.component.html | 2 +- .../components/grid/scroll-grid.component.scss | 2 +- .../components/grid/scroll-grid.component.ts | 2 +- .../components/help-markdown.component.html | 2 +- .../components/help-markdown.component.scss | 2 +- .../shared/components/help-markdown.component.ts | 2 +- .../shared/components/help-popup.component.html | 2 +- .../shared/components/help-popup.component.scss | 2 +- .../shared/components/help-popup.component.ts | 2 +- .../app/shared/components/help.component.html | 2 +- .../src/app/shared/components/help.component.ts | 2 +- .../components/hint-tooltip-icon.component.html | 2 +- .../components/hint-tooltip-icon.component.scss | 2 +- .../components/hint-tooltip-icon.component.ts | 2 +- .../app/shared/components/hotkeys.directive.ts | 2 +- .../app/shared/components/html.component.html | 2 +- .../app/shared/components/html.component.scss | 2 +- .../src/app/shared/components/html.component.ts | 2 +- .../src/app/shared/components/icon.component.ts | 2 +- .../shared/components/image-input.component.html | 2 +- .../shared/components/image-input.component.scss | 2 +- .../shared/components/image-input.component.ts | 2 +- .../image/embed-image-dialog.component.html | 2 +- .../image/embed-image-dialog.component.scss | 2 +- .../image/embed-image-dialog.component.ts | 2 +- .../image/gallery-image-input.component.html | 2 +- .../image/gallery-image-input.component.scss | 3 +-- .../image/gallery-image-input.component.ts | 2 +- .../components/image/image-dialog.component.html | 2 +- .../components/image/image-dialog.component.scss | 3 +-- .../components/image/image-dialog.component.ts | 2 +- .../image/image-gallery.component.html | 2 +- .../image/image-gallery.component.scss | 3 +-- .../components/image/image-gallery.component.ts | 2 +- .../image/image-references.component.html | 2 +- .../image/image-references.component.scss | 2 +- .../image/image-references.component.ts | 2 +- .../shared/components/image/images-datasource.ts | 2 +- .../image/images-in-use-dialog.component.html | 2 +- .../image/images-in-use-dialog.component.scss | 2 +- .../image/images-in-use-dialog.component.ts | 2 +- .../multiple-gallery-image-input.component.html | 2 +- .../multiple-gallery-image-input.component.scss | 2 +- .../multiple-gallery-image-input.component.ts | 2 +- .../image/upload-image-dialog.component.html | 2 +- .../image/upload-image-dialog.component.ts | 2 +- .../app/shared/components/js-func.component.html | 2 +- .../app/shared/components/js-func.component.scss | 2 +- .../app/shared/components/js-func.component.ts | 2 +- .../components/json-content.component.html | 2 +- .../components/json-content.component.scss | 2 +- .../shared/components/json-content.component.ts | 2 +- .../json-form/json-form-component.models.ts | 2 +- .../json-form/json-form.component.html | 2 +- .../json-form/json-form.component.scss | 2 +- .../components/json-form/json-form.component.ts | 2 +- .../json-form/react/json-form-ace-editor.tsx | 2 +- .../json-form/react/json-form-array.tsx | 2 +- .../json-form/react/json-form-base-component.tsx | 2 +- .../json-form/react/json-form-checkbox.tsx | 2 +- .../json-form/react/json-form-color.tsx | 2 +- .../components/json-form/react/json-form-css.tsx | 2 +- .../json-form/react/json-form-date.tsx | 2 +- .../json-form/react/json-form-fieldset.tsx | 2 +- .../json-form/react/json-form-help.tsx | 2 +- .../json-form/react/json-form-html.tsx | 2 +- .../json-form/react/json-form-icon.tsx | 2 +- .../json-form/react/json-form-image.tsx | 2 +- .../json-form/react/json-form-javascript.tsx | 2 +- .../json-form/react/json-form-json.tsx | 2 +- .../json-form/react/json-form-markdown.tsx | 2 +- .../json-form/react/json-form-number.tsx | 2 +- .../json-form/react/json-form-radios.tsx | 2 +- .../json-form/react/json-form-rc-select.tsx | 2 +- .../json-form/react/json-form-react.tsx | 2 +- .../json-form/react/json-form-schema-form.tsx | 2 +- .../json-form/react/json-form-select.tsx | 2 +- .../json-form/react/json-form-text.tsx | 2 +- .../json-form/react/json-form-utils.ts | 2 +- .../json-form/react/json-form.models.ts | 2 +- .../components/json-form/react/json-form.scss | 2 +- .../json-form/react/styles/thingsboardTheme.ts | 2 +- .../components/json-object-edit.component.html | 2 +- .../components/json-object-edit.component.scss | 2 +- .../components/json-object-edit.component.ts | 2 +- .../components/json-object-view.component.html | 2 +- .../components/json-object-view.component.scss | 2 +- .../components/json-object-view.component.ts | 2 +- .../app/shared/components/kv-map.component.html | 2 +- .../app/shared/components/kv-map.component.scss | 2 +- .../app/shared/components/kv-map.component.ts | 2 +- .../shared/components/led-light.component.html | 2 +- .../app/shared/components/led-light.component.ts | 2 +- .../app/shared/components/logo.component.html | 2 +- .../app/shared/components/logo.component.scss | 2 +- .../src/app/shared/components/logo.component.ts | 2 +- .../components/markdown-editor.component.html | 2 +- .../components/markdown-editor.component.scss | 2 +- .../components/markdown-editor.component.ts | 2 +- .../shared/components/markdown.component.html | 2 +- .../shared/components/markdown.component.scss | 3 +-- .../app/shared/components/markdown.component.ts | 2 +- .../shared/components/marked-options.service.ts | 2 +- .../material-icon-select.component.html | 2 +- .../material-icon-select.component.scss | 2 +- .../components/material-icon-select.component.ts | 2 +- .../components/material-icons.component.html | 2 +- .../components/material-icons.component.scss | 2 +- .../components/material-icons.component.ts | 2 +- .../message-type-autocomplete.component.html | 2 +- .../message-type-autocomplete.component.ts | 2 +- .../multiple-image-input.component.html | 2 +- .../multiple-image-input.component.scss | 2 +- .../components/multiple-image-input.component.ts | 2 +- .../shared/components/nav-tree.component.html | 2 +- .../shared/components/nav-tree.component.scss | 2 +- .../app/shared/components/nav-tree.component.ts | 2 +- .../notification/notification.component.html | 2 +- .../notification/notification.component.scss | 2 +- .../notification/notification.component.ts | 2 +- .../template-autocomplete.component.html | 2 +- .../template-autocomplete.component.scss | 2 +- .../template-autocomplete.component.ts | 2 +- .../ota-package-autocomplete.component.html | 2 +- .../ota-package-autocomplete.component.scss | 2 +- .../ota-package-autocomplete.component.ts | 2 +- .../src/app/shared/components/page.component.ts | 2 +- .../shared/components/phone-input.component.html | 2 +- .../shared/components/phone-input.component.scss | 2 +- .../shared/components/phone-input.component.ts | 2 +- .../app/shared/components/popover.component.scss | 2 +- .../app/shared/components/popover.component.ts | 2 +- .../src/app/shared/components/popover.models.ts | 2 +- .../src/app/shared/components/popover.service.ts | 2 +- .../components/protobuf-content.component.html | 2 +- .../components/protobuf-content.component.scss | 2 +- .../components/protobuf-content.component.ts | 2 +- ui-ngx/src/app/shared/components/public-api.ts | 2 +- .../queue/queue-autocomplete.component.html | 2 +- .../queue/queue-autocomplete.component.scss | 2 +- .../queue/queue-autocomplete.component.ts | 2 +- .../relation-type-autocomplete.component.html | 2 +- .../relation-type-autocomplete.component.ts | 2 +- .../resource-autocomplete.component.html | 2 +- .../resource/resource-autocomplete.component.ts | 2 +- .../rule-chain/rule-chain-select.component.html | 2 +- .../rule-chain/rule-chain-select.component.scss | 2 +- .../rule-chain/rule-chain-select.component.ts | 2 +- .../shared/components/script-lang.component.html | 2 +- .../shared/components/script-lang.component.scss | 2 +- .../shared/components/script-lang.component.ts | 2 +- ...lack-conversation-autocomplete.component.html | 2 +- ...lack-conversation-autocomplete.component.scss | 2 +- .../slack-conversation-autocomplete.component.ts | 2 +- .../shared/components/snack-bar-component.html | 2 +- .../shared/components/snack-bar-component.scss | 2 +- .../components/socialshare-panel.component.html | 2 +- .../components/socialshare-panel.component.scss | 2 +- .../components/socialshare-panel.component.ts | 2 +- .../string-autocomplete.component.html | 2 +- .../string-autocomplete.component.scss | 2 +- .../components/string-autocomplete.component.ts | 2 +- .../components/string-items-list.component.html | 2 +- .../components/string-items-list.component.ts | 2 +- .../app/shared/components/tb-anchor.component.ts | 2 +- .../shared/components/tb-checkbox.component.html | 2 +- .../shared/components/tb-checkbox.component.ts | 2 +- .../app/shared/components/tb-error.component.ts | 2 +- .../time/datetime-period.component.html | 2 +- .../time/datetime-period.component.scss | 2 +- .../components/time/datetime-period.component.ts | 2 +- .../components/time/datetime.component.html | 2 +- .../shared/components/time/datetime.component.ts | 2 +- .../history-selector.component.html | 2 +- .../history-selector.component.scss | 2 +- .../history-selector.component.ts | 2 +- .../time/quick-time-interval.component.html | 2 +- .../time/quick-time-interval.component.scss | 2 +- .../time/quick-time-interval.component.ts | 2 +- .../components/time/timeinterval.component.html | 2 +- .../components/time/timeinterval.component.scss | 2 +- .../components/time/timeinterval.component.ts | 2 +- .../time/timewindow-panel.component.html | 2 +- .../time/timewindow-panel.component.scss | 2 +- .../time/timewindow-panel.component.ts | 2 +- .../components/time/timewindow.component.html | 2 +- .../components/time/timewindow.component.scss | 2 +- .../components/time/timewindow.component.ts | 2 +- .../time/timezone-select.component.html | 2 +- .../components/time/timezone-select.component.ts | 2 +- .../src/app/shared/components/toast.directive.ts | 2 +- .../components/toggle-header.component.html | 2 +- .../components/toggle-header.component.scss | 3 +-- .../shared/components/toggle-header.component.ts | 2 +- .../components/toggle-select.component.html | 2 +- .../shared/components/toggle-select.component.ts | 2 +- ui-ngx/src/app/shared/components/tokens.ts | 2 +- .../shared/components/unit-input.component.html | 2 +- .../shared/components/unit-input.component.scss | 2 +- .../shared/components/unit-input.component.ts | 2 +- .../shared/components/user-menu.component.html | 2 +- .../shared/components/user-menu.component.scss | 2 +- .../app/shared/components/user-menu.component.ts | 2 +- .../shared/components/value-input.component.html | 2 +- .../shared/components/value-input.component.scss | 2 +- .../shared/components/value-input.component.ts | 2 +- .../vc/branch-autocomplete.component.html | 2 +- .../vc/branch-autocomplete.component.scss | 2 +- .../vc/branch-autocomplete.component.ts | 2 +- .../widgets-bundle-search.component.html | 2 +- .../widgets-bundle-search.component.scss | 2 +- .../widgets-bundle-search.component.ts | 2 +- .../widgets-bundle-select.component.html | 2 +- .../widgets-bundle-select.component.scss | 2 +- .../widgets-bundle-select.component.ts | 2 +- ui-ngx/src/app/shared/decorators/coercion.ts | 2 +- ui-ngx/src/app/shared/decorators/enumerable.ts | 2 +- ui-ngx/src/app/shared/decorators/public-api.ts | 2 +- ui-ngx/src/app/shared/decorators/tb-inject.ts | 2 +- .../export-widgets-bundle-dialog.component.html | 2 +- .../export-widgets-bundle-dialog.component.ts | 2 +- .../import-dialog-csv.component.html | 2 +- .../import-dialog-csv.component.scss | 2 +- .../import-export/import-dialog-csv.component.ts | 2 +- .../import-export/import-dialog.component.html | 2 +- .../import-export/import-dialog.component.ts | 2 +- .../shared/import-export/import-export.models.ts | 2 +- .../import-export/import-export.service.ts | 2 +- .../table-columns-assignment.component.html | 2 +- .../table-columns-assignment.component.scss | 2 +- .../table-columns-assignment.component.ts | 2 +- .../src/app/shared/layout/layout.directives.ts | 2 +- ui-ngx/src/app/shared/models/ace/ace.models.ts | 2 +- .../app/shared/models/ace/completion.models.ts | 2 +- .../models/ace/service-completion.models.ts | 2 +- .../src/app/shared/models/ace/tbel/mode-tbel.js | 2 +- .../app/shared/models/ace/tbel/worker-tbel.js | 2 +- .../models/ace/widget-completion.models.ts | 2 +- ui-ngx/src/app/shared/models/alarm.models.ts | 2 +- ui-ngx/src/app/shared/models/alias.models.ts | 2 +- ui-ngx/src/app/shared/models/api-usage.models.ts | 2 +- ui-ngx/src/app/shared/models/asset.models.ts | 2 +- ui-ngx/src/app/shared/models/audit-log.models.ts | 2 +- ui-ngx/src/app/shared/models/authority.enum.ts | 2 +- ui-ngx/src/app/shared/models/base-data.ts | 2 +- ui-ngx/src/app/shared/models/beautify.models.ts | 2 +- .../shared/models/component-descriptor.models.ts | 2 +- ui-ngx/src/app/shared/models/constants.ts | 2 +- .../src/app/shared/models/contact-based.model.ts | 2 +- ui-ngx/src/app/shared/models/country.models.ts | 2 +- ui-ngx/src/app/shared/models/customer.model.ts | 2 +- ui-ngx/src/app/shared/models/dashboard.models.ts | 2 +- ui-ngx/src/app/shared/models/device.models.ts | 2 +- ui-ngx/src/app/shared/models/edge.models.ts | 2 +- .../src/app/shared/models/entity-type.models.ts | 2 +- .../src/app/shared/models/entity-view.models.ts | 2 +- ui-ngx/src/app/shared/models/entity.models.ts | 2 +- ui-ngx/src/app/shared/models/error.models.ts | 2 +- ui-ngx/src/app/shared/models/event.models.ts | 2 +- ui-ngx/src/app/shared/models/icon.models.ts | 2 +- .../src/app/shared/models/id/alarm-comment-id.ts | 2 +- ui-ngx/src/app/shared/models/id/alarm-id.ts | 2 +- ui-ngx/src/app/shared/models/id/asset-id.ts | 2 +- .../src/app/shared/models/id/asset-profile-id.ts | 2 +- ui-ngx/src/app/shared/models/id/audit-log-id.ts | 2 +- ui-ngx/src/app/shared/models/id/customer-id.ts | 2 +- ui-ngx/src/app/shared/models/id/dashboard-id.ts | 2 +- .../shared/models/id/device-credentials-id.ts | 2 +- ui-ngx/src/app/shared/models/id/device-id.ts | 2 +- .../app/shared/models/id/device-profile-id.ts | 2 +- ui-ngx/src/app/shared/models/id/edge-id.ts | 2 +- ui-ngx/src/app/shared/models/id/entity-id.ts | 2 +- .../src/app/shared/models/id/entity-view-id.ts | 2 +- ui-ngx/src/app/shared/models/id/event-id.ts | 2 +- ui-ngx/src/app/shared/models/id/has-uuid.ts | 2 +- .../src/app/shared/models/id/notification-id.ts | 2 +- .../shared/models/id/notification-request-id.ts | 2 +- .../app/shared/models/id/notification-rule-id.ts | 2 +- .../shared/models/id/notification-target-id.ts | 2 +- .../shared/models/id/notification-template-id.ts | 2 +- .../src/app/shared/models/id/ota-package-id.ts | 2 +- ui-ngx/src/app/shared/models/id/public-api.ts | 2 +- ui-ngx/src/app/shared/models/id/queue-id.ts | 2 +- ui-ngx/src/app/shared/models/id/rpc-id.ts | 2 +- ui-ngx/src/app/shared/models/id/rule-chain-id.ts | 2 +- ui-ngx/src/app/shared/models/id/rule-node-id.ts | 2 +- .../src/app/shared/models/id/tb-resource-id.ts | 2 +- ui-ngx/src/app/shared/models/id/tenant-id.ts | 2 +- .../app/shared/models/id/tenant-profile-id.ts | 2 +- ui-ngx/src/app/shared/models/id/user-id.ts | 2 +- .../src/app/shared/models/id/widget-type-id.ts | 2 +- .../app/shared/models/id/widgets-bundle-id.ts | 2 +- .../src/app/shared/models/limited-api.models.ts | 2 +- ui-ngx/src/app/shared/models/login.models.ts | 2 +- .../models/lwm2m-security-config.models.ts | 2 +- ui-ngx/src/app/shared/models/material.models.ts | 2 +- .../src/app/shared/models/notification.models.ts | 2 +- ui-ngx/src/app/shared/models/oauth2.models.ts | 2 +- .../src/app/shared/models/ota-package.models.ts | 2 +- ui-ngx/src/app/shared/models/overlay.models.ts | 2 +- ui-ngx/src/app/shared/models/page/page-data.ts | 2 +- ui-ngx/src/app/shared/models/page/page-link.ts | 2 +- ui-ngx/src/app/shared/models/page/public-api.ts | 2 +- ui-ngx/src/app/shared/models/page/sort-order.ts | 2 +- ui-ngx/src/app/shared/models/public-api.ts | 2 +- .../src/app/shared/models/query/query.models.ts | 2 +- ui-ngx/src/app/shared/models/queue.models.ts | 2 +- ui-ngx/src/app/shared/models/relation.models.ts | 2 +- ui-ngx/src/app/shared/models/resource.models.ts | 2 +- ui-ngx/src/app/shared/models/rpc.models.ts | 2 +- .../src/app/shared/models/rule-chain.models.ts | 2 +- ui-ngx/src/app/shared/models/rule-node.models.ts | 2 +- ui-ngx/src/app/shared/models/settings.models.ts | 2 +- .../shared/models/telemetry/telemetry.models.ts | 2 +- ui-ngx/src/app/shared/models/tenant.model.ts | 2 +- ui-ngx/src/app/shared/models/time/time.models.ts | 2 +- .../app/shared/models/two-factor-auth.models.ts | 2 +- ui-ngx/src/app/shared/models/unit.models.ts | 2 +- ui-ngx/src/app/shared/models/usage.models.ts | 2 +- .../app/shared/models/user-settings.models.ts | 2 +- ui-ngx/src/app/shared/models/user.model.ts | 2 +- ui-ngx/src/app/shared/models/vc.models.ts | 2 +- .../shared/models/websocket/websocket.models.ts | 2 +- .../app/shared/models/widget-settings.models.ts | 2 +- ui-ngx/src/app/shared/models/widget.models.ts | 2 +- .../app/shared/models/widgets-bundle.model.ts | 2 +- .../app/shared/models/window-message.model.ts | 2 +- ui-ngx/src/app/shared/pipe/date-ago.pipe.ts | 2 +- ui-ngx/src/app/shared/pipe/enum-to-array.pipe.ts | 2 +- ui-ngx/src/app/shared/pipe/file-size.pipe.ts | 2 +- ui-ngx/src/app/shared/pipe/highlight.pipe.ts | 2 +- ui-ngx/src/app/shared/pipe/image.pipe.ts | 2 +- .../app/shared/pipe/keyboard-shortcut.pipe.ts | 2 +- .../pipe/milliseconds-to-time-string.pipe.ts | 2 +- ui-ngx/src/app/shared/pipe/nospace.pipe.ts | 2 +- ui-ngx/src/app/shared/pipe/public-api.ts | 2 +- ui-ngx/src/app/shared/pipe/safe.pipe.ts | 2 +- .../app/shared/pipe/selectable-columns.pipe.ts | 2 +- ui-ngx/src/app/shared/pipe/short-number.pipe.ts | 2 +- ui-ngx/src/app/shared/pipe/tbJson.pipe.ts | 2 +- ui-ngx/src/app/shared/pipe/truncate.pipe.ts | 2 +- ui-ngx/src/app/shared/public-api.ts | 2 +- .../app/shared/services/custom-paginator-intl.ts | 2 +- ui-ngx/src/app/shared/shared.module.ts | 2 +- ui-ngx/src/assets/fonts/material-icons.css | 2 +- ui-ngx/src/environments/environment.prod.ts | 2 +- ui-ngx/src/environments/environment.ts | 2 +- ui-ngx/src/form.scss | 3 +-- ui-ngx/src/index.html | 2 +- ui-ngx/src/karma.conf.js | 2 +- ui-ngx/src/main.ts | 2 +- ui-ngx/src/polyfills.ts | 2 +- ui-ngx/src/scss/animations.scss | 2 +- ui-ngx/src/scss/constants.scss | 2 +- ui-ngx/src/scss/fonts.scss | 2 +- ui-ngx/src/scss/mixins.scss | 2 +- ui-ngx/src/styles.scss | 2 +- ui-ngx/src/test.ts | 2 +- ui-ngx/src/theme-overwrites.scss | 2 +- ui-ngx/src/theme.scss | 2 +- ui-ngx/src/theme/datepicker-theme.scss | 2 +- ui-ngx/src/typings/jquery.flot.typings.d.ts | 2 +- ui-ngx/src/typings/jquery.jstree.typings.d.ts | 2 +- ui-ngx/src/typings/jquery.typings.d.ts | 2 +- ui-ngx/src/typings/leaflet-extend-tb.d.ts | 2 +- ui-ngx/src/typings/leaflet-geoman-extend.d.ts | 2 +- ui-ngx/src/typings/rawloader.typings.d.ts | 2 +- ui-ngx/src/typings/split.js.typings.d.ts | 2 +- ui-ngx/src/typings/utils.d.ts | 2 +- ui-ngx/src/zone-flags.ts | 2 +- 5946 files changed, 5961 insertions(+), 5985 deletions(-) diff --git a/.github/release.yml b/.github/release.yml index 1d760fe7bf..5e0ddc4300 100644 --- a/.github/release.yml +++ b/.github/release.yml @@ -1,5 +1,5 @@ # -# Copyright © 2016-2023 The Thingsboard Authors +# Copyright © 2016-2024 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. diff --git a/.github/workflows/check-configuration-files.yml b/.github/workflows/check-configuration-files.yml index 0b292ded79..94bfc85ce3 100644 --- a/.github/workflows/check-configuration-files.yml +++ b/.github/workflows/check-configuration-files.yml @@ -1,5 +1,5 @@ # -# Copyright © 2016-2023 The Thingsboard Authors +# Copyright © 2016-2024 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. diff --git a/application/pom.xml b/application/pom.xml index 076676ae81..aaa8a1f447 100644 --- a/application/pom.xml +++ b/application/pom.xml @@ -1,6 +1,6 @@ - diff --git a/ui-ngx/src/app/modules/home/components/alarm/alarm-assignee.component.scss b/ui-ngx/src/app/modules/home/components/alarm/alarm-assignee.component.scss index 3aed0ccb5e..505db79a36 100644 --- a/ui-ngx/src/app/modules/home/components/alarm/alarm-assignee.component.scss +++ b/ui-ngx/src/app/modules/home/components/alarm/alarm-assignee.component.scss @@ -1,5 +1,5 @@ /** - * Copyright © 2016-2023 The Thingsboard Authors + * Copyright © 2016-2024 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. @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - .user-avatar { display: inline-flex; justify-content: center; diff --git a/ui-ngx/src/app/modules/home/components/alarm/alarm-assignee.component.ts b/ui-ngx/src/app/modules/home/components/alarm/alarm-assignee.component.ts index 1fb1d3f689..0fc489fbfe 100644 --- a/ui-ngx/src/app/modules/home/components/alarm/alarm-assignee.component.ts +++ b/ui-ngx/src/app/modules/home/components/alarm/alarm-assignee.component.ts @@ -1,5 +1,5 @@ /// -/// Copyright © 2016-2023 The Thingsboard Authors +/// Copyright © 2016-2024 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. diff --git a/ui-ngx/src/app/modules/home/components/alarm/alarm-comment-dialog.component.html b/ui-ngx/src/app/modules/home/components/alarm/alarm-comment-dialog.component.html index 8618592ae0..8145c31b06 100644 --- a/ui-ngx/src/app/modules/home/components/alarm/alarm-comment-dialog.component.html +++ b/ui-ngx/src/app/modules/home/components/alarm/alarm-comment-dialog.component.html @@ -1,6 +1,6 @@ -
-

{{ "attribute.delete-timeseries.delete-strategy" | translate }}

diff --git a/ui-ngx/src/app/modules/home/components/attribute/delete-timeseries-panel.component.scss b/ui-ngx/src/app/modules/home/components/attribute/delete-timeseries-panel.component.scss index b0c0ec0621..b6fac754b7 100644 --- a/ui-ngx/src/app/modules/home/components/attribute/delete-timeseries-panel.component.scss +++ b/ui-ngx/src/app/modules/home/components/attribute/delete-timeseries-panel.component.scss @@ -1,5 +1,5 @@ /** - * Copyright © 2016-2023 The Thingsboard Authors + * Copyright © 2016-2024 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. diff --git a/ui-ngx/src/app/modules/home/components/attribute/delete-timeseries-panel.component.ts b/ui-ngx/src/app/modules/home/components/attribute/delete-timeseries-panel.component.ts index df2eb931df..a6ae799198 100644 --- a/ui-ngx/src/app/modules/home/components/attribute/delete-timeseries-panel.component.ts +++ b/ui-ngx/src/app/modules/home/components/attribute/delete-timeseries-panel.component.ts @@ -1,5 +1,5 @@ /// -/// Copyright © 2016-2023 The Thingsboard Authors +/// Copyright © 2016-2024 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. diff --git a/ui-ngx/src/app/modules/home/components/attribute/edit-attribute-value-panel.component.html b/ui-ngx/src/app/modules/home/components/attribute/edit-attribute-value-panel.component.html index 2ec3455adf..6725b36960 100644 --- a/ui-ngx/src/app/modules/home/components/attribute/edit-attribute-value-panel.component.html +++ b/ui-ngx/src/app/modules/home/components/attribute/edit-attribute-value-panel.component.html @@ -1,6 +1,6 @@ -
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/gateway-statistics.component.scss b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/gateway-statistics.component.scss index e704120560..cd7722d12d 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/gateway-statistics.component.scss +++ b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/gateway-statistics.component.scss @@ -1,5 +1,5 @@ /** - * Copyright © 2016-2023 The Thingsboard Authors + * Copyright © 2016-2024 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. diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/gateway-statistics.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/gateway-statistics.component.ts index 503f5643bf..a3cb79e125 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/gateway-statistics.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/gateway-statistics.component.ts @@ -1,5 +1,5 @@ /// -/// Copyright © 2016-2023 The Thingsboard Authors +/// Copyright © 2016-2024 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. diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/gateway-widget.models.ts b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/gateway-widget.models.ts index d58c33079a..603b06cc01 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/gateway-widget.models.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/gateway-widget.models.ts @@ -1,5 +1,5 @@ /// -/// Copyright © 2016-2023 The Thingsboard Authors +/// Copyright © 2016-2024 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. diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/home-page/add-doc-link-dialog.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/home-page/add-doc-link-dialog.component.html index 1eaf791577..7f86897f7e 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/home-page/add-doc-link-dialog.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/home-page/add-doc-link-dialog.component.html @@ -1,6 +1,6 @@ + diff --git a/ui-ngx/src/app/shared/components/image/image-gallery-dialog.component.scss b/ui-ngx/src/app/shared/components/image/image-gallery-dialog.component.scss new file mode 100644 index 0000000000..ac49971339 --- /dev/null +++ b/ui-ngx/src/app/shared/components/image/image-gallery-dialog.component.scss @@ -0,0 +1,32 @@ +@import '../../../../scss/constants'; + +:host { + .tb-image-gallery-dialog { + position: relative; + padding: 24px 32px 16px 32px; + width: 100vw; + height: 100vh; + max-height: 100vh; + @media #{$mat-gt-xs} { + width: 80vw; + height: 80vh; + max-height: 80vh; + } + @media #{$mat-gt-sm} { + width: 700px; + } + @media #{$mat-gt-md} { + width: 900px; + } + @media #{$mat-gt-xl} { + width: 900px; + } + .tb-image-gallery-close { + position: absolute; + top: 12px; + right: 12px; + z-index: 1; + color: rgba(0, 0, 0, 0.38); + } + } +} diff --git a/ui-ngx/src/app/shared/components/image/image-gallery-dialog.component.ts b/ui-ngx/src/app/shared/components/image/image-gallery-dialog.component.ts new file mode 100644 index 0000000000..482fbe76a5 --- /dev/null +++ b/ui-ngx/src/app/shared/components/image/image-gallery-dialog.component.ts @@ -0,0 +1,62 @@ +/// +/// Copyright © 2016-2024 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 { Component, Inject, OnInit, SkipSelf } from '@angular/core'; +import { ErrorStateMatcher } from '@angular/material/core'; +import { MAT_DIALOG_DATA, MatDialog, MatDialogRef } from '@angular/material/dialog'; +import { Store } from '@ngrx/store'; +import { AppState } from '@core/core.state'; +import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms'; +import { DialogComponent } from '@shared/components/dialog.component'; +import { Router } from '@angular/router'; +import { ImageService } from '@core/http/image.service'; +import { ImageResourceInfo, imageResourceType } from '@shared/models/resource.models'; +import { + UploadImageDialogComponent, + UploadImageDialogData +} from '@shared/components/image/upload-image-dialog.component'; +import { UrlHolder } from '@shared/pipe/image.pipe'; +import { ImportExportService } from '@shared/import-export/import-export.service'; +import { EmbedImageDialogComponent, EmbedImageDialogData } from '@shared/components/image/embed-image-dialog.component'; + +@Component({ + selector: 'tb-image-gallery-dialog', + templateUrl: './image-gallery-dialog.component.html', + styleUrls: ['./image-gallery-dialog.component.scss'] +}) +export class ImageGalleryDialogComponent extends + DialogComponent implements OnInit { + + constructor(protected store: Store, + protected router: Router, + private imageService: ImageService, + private dialog: MatDialog, + public dialogRef: MatDialogRef) { + super(store, router, dialogRef); + } + + ngOnInit(): void { + } + + cancel(): void { + this.dialogRef.close(null); + } + + imageSelected(image: ImageResourceInfo): void { + this.dialogRef.close(image); + } + +} diff --git a/ui-ngx/src/app/shared/components/image/image-gallery.component.html b/ui-ngx/src/app/shared/components/image/image-gallery.component.html index 3e357a21b3..21b10e8c66 100644 --- a/ui-ngx/src/app/shared/components/image/image-gallery.component.html +++ b/ui-ngx/src/app/shared/components/image/image-gallery.component.html @@ -15,11 +15,11 @@ limitations under the License. --> -
+
+ fxLayout.lt-lg="column" fxLayoutAlign.lt-lg="start stretch" + [fxShow]="!textSearchMode && (mode === 'grid' || dataSource?.selection.isEmpty())" [ngClass.lt-lg]="{'multi-row': !isSysAdmin}">
image.gallery @@ -44,11 +44,11 @@
{{ 'image.include-system-images' | translate }}
-
+
- {{ 'image.include-system-images' | translate }} @@ -293,7 +293,7 @@ [hidePageSize]="hidePageSize" showFirstLastButtons>
-
+
Date: Tue, 9 Jan 2024 14:54:32 +0200 Subject: [PATCH 060/179] Update license header --- .../image/image-gallery-dialog.component.scss | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/ui-ngx/src/app/shared/components/image/image-gallery-dialog.component.scss b/ui-ngx/src/app/shared/components/image/image-gallery-dialog.component.scss index ac49971339..6ebda09fb5 100644 --- a/ui-ngx/src/app/shared/components/image/image-gallery-dialog.component.scss +++ b/ui-ngx/src/app/shared/components/image/image-gallery-dialog.component.scss @@ -1,3 +1,18 @@ +/** + * Copyright © 2016-2024 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 '../../../../scss/constants'; :host { From 523651b71cb77eb53b049431e015d642e1384ced Mon Sep 17 00:00:00 2001 From: ShvaykaD Date: Tue, 9 Jan 2024 16:52:50 +0200 Subject: [PATCH 061/179] overload saveWidgetType, getWidgetTypes, getBundleWidgetTypesInfos methods --- .../org/thingsboard/rest/client/RestClient.java | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/rest-client/src/main/java/org/thingsboard/rest/client/RestClient.java b/rest-client/src/main/java/org/thingsboard/rest/client/RestClient.java index c950febfa7..10d3863a2a 100644 --- a/rest-client/src/main/java/org/thingsboard/rest/client/RestClient.java +++ b/rest-client/src/main/java/org/thingsboard/rest/client/RestClient.java @@ -2767,13 +2767,24 @@ public class RestClient implements Closeable { } public WidgetTypeDetails saveWidgetType(WidgetTypeDetails widgetTypeDetails) { - return restTemplate.postForEntity(baseURL + "/api/widgetType", widgetTypeDetails, WidgetTypeDetails.class).getBody(); + return saveWidgetType(widgetTypeDetails, null); + } + + public WidgetTypeDetails saveWidgetType(WidgetTypeDetails widgetTypeDetails, Boolean updateExistingByFqn) { + if (updateExistingByFqn == null) { + return restTemplate.postForEntity(baseURL + "/api/widgetType", widgetTypeDetails, WidgetTypeDetails.class).getBody(); + } + return restTemplate.postForEntity(baseURL + "/api/widgetType?updateExistingByFqn={updateExistingByFqn}", widgetTypeDetails, WidgetTypeDetails.class, updateExistingByFqn).getBody(); } public void deleteWidgetType(WidgetTypeId widgetTypeId) { restTemplate.delete(baseURL + "/api/widgetType/{widgetTypeId}", widgetTypeId.getId()); } + public PageData getWidgetTypes(PageLink pageLink) { + return getWidgetTypes(pageLink, null, null, null, null); + } + public PageData getWidgetTypes(PageLink pageLink, Boolean tenantOnly, Boolean fullSearch, DeprecatedFilter deprecatedFilter, List widgetTypeList) { Map params = new HashMap<>(); @@ -2856,6 +2867,10 @@ public class RestClient implements Closeable { bundleAlias).getBody(); } + public PageData getBundleWidgetTypesInfos(WidgetsBundleId widgetsBundleId, PageLink pageLink) { + return getBundleWidgetTypesInfos(widgetsBundleId, pageLink, null, null, null, null); + } + public PageData getBundleWidgetTypesInfos(WidgetsBundleId widgetsBundleId, PageLink pageLink, Boolean tenantOnly, Boolean fullSearch, DeprecatedFilter deprecatedFilter, List widgetTypeList) { From e30e2ca62767c3791070f1c6355c9bfa249f6678 Mon Sep 17 00:00:00 2001 From: rusikv Date: Tue, 9 Jan 2024 17:28:53 +0200 Subject: [PATCH 062/179] UI: rule chain search improvements --- .../rule-chain-select-panel.component.html | 7 +++--- .../rule-chain-select-panel.component.scss | 22 +++++++++++++++++++ .../rule-chain-select.component.html | 7 +++--- .../rule-chain-select.component.scss | 2 ++ 4 files changed, 31 insertions(+), 7 deletions(-) diff --git a/ui-ngx/src/app/shared/components/rule-chain/rule-chain-select-panel.component.html b/ui-ngx/src/app/shared/components/rule-chain/rule-chain-select-panel.component.html index f6c9a3938e..7a9f56255f 100644 --- a/ui-ngx/src/app/shared/components/rule-chain/rule-chain-select-panel.component.html +++ b/ui-ngx/src/app/shared/components/rule-chain/rule-chain-select-panel.component.html @@ -22,13 +22,14 @@ (focusin)="onFocus()" [matAutocomplete]="ruleChainAutocomplete"> search - - + check +
diff --git a/ui-ngx/src/app/shared/components/rule-chain/rule-chain-select-panel.component.scss b/ui-ngx/src/app/shared/components/rule-chain/rule-chain-select-panel.component.scss index 758b1f9bcd..798839627d 100644 --- a/ui-ngx/src/app/shared/components/rule-chain/rule-chain-select-panel.component.scss +++ b/ui-ngx/src/app/shared/components/rule-chain/rule-chain-select-panel.component.scss @@ -13,6 +13,28 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +@import "../../../../scss/constants"; + :host { width: 100%; } + +::ng-deep { + .tb-autocomplete.tb-rule-chain-search { + .mat-mdc-option.tb-selected-option { + display: flex; + flex-direction: row-reverse; + background-color: rgba(0, 0, 0, .04); + + mat-icon { + margin-right: 0; + margin-left: 16px; + color: $tb-primary-color; + } + + .mdc-list-item__primary-text { + color: $tb-primary-color; + } + } + } +} diff --git a/ui-ngx/src/app/shared/components/rule-chain/rule-chain-select.component.html b/ui-ngx/src/app/shared/components/rule-chain/rule-chain-select.component.html index 899a43a781..1e646d2dcb 100644 --- a/ui-ngx/src/app/shared/components/rule-chain/rule-chain-select.component.html +++ b/ui-ngx/src/app/shared/components/rule-chain/rule-chain-select.component.html @@ -16,12 +16,11 @@ --> settings_ethernet - - arrow_drop_down + arrow_drop_down diff --git a/ui-ngx/src/app/shared/components/rule-chain/rule-chain-select.component.scss b/ui-ngx/src/app/shared/components/rule-chain/rule-chain-select.component.scss index 6f781986bf..d981a2954b 100644 --- a/ui-ngx/src/app/shared/components/rule-chain/rule-chain-select.component.scss +++ b/ui-ngx/src/app/shared/components/rule-chain/rule-chain-select.component.scss @@ -23,6 +23,8 @@ input { color: #fff; cursor: pointer; + text-overflow: ellipsis; + pointer-events: none; &:disabled { cursor: unset; From e3041adc42d71a3751823b42113be69eaef02299 Mon Sep 17 00:00:00 2001 From: Andrii Shvaika Date: Tue, 9 Jan 2024 18:18:10 +0200 Subject: [PATCH 063/179] Grouping interval structures --- .../server/ThingsboardServerApplication.java | 6 ++++- .../ws/telemetry/cmd/v2/EntityHistoryCmd.java | 3 +++ .../service/ws/telemetry/cmd/v2/GetTsCmd.java | 5 +++++ .../ws/telemetry/cmd/v2/TimeSeriesCmd.java | 3 +++ .../server/common/data/kv/IntervalType.java | 22 +++++++++++++++++++ 5 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 common/data/src/main/java/org/thingsboard/server/common/data/kv/IntervalType.java diff --git a/application/src/main/java/org/thingsboard/server/ThingsboardServerApplication.java b/application/src/main/java/org/thingsboard/server/ThingsboardServerApplication.java index 60f69cd8a7..77442e53a8 100644 --- a/application/src/main/java/org/thingsboard/server/ThingsboardServerApplication.java +++ b/application/src/main/java/org/thingsboard/server/ThingsboardServerApplication.java @@ -21,6 +21,7 @@ import org.springframework.context.annotation.ComponentScan; import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.scheduling.annotation.EnableScheduling; +import java.time.ZoneId; import java.util.Arrays; @SpringBootConfiguration @@ -33,7 +34,10 @@ public class ThingsboardServerApplication { private static final String DEFAULT_SPRING_CONFIG_PARAM = SPRING_CONFIG_NAME_KEY + "=" + "thingsboard"; public static void main(String[] args) { - SpringApplication.run(ThingsboardServerApplication.class, updateArguments(args)); + + ZoneId.getAvailableZoneIds().stream().sorted().forEach(System.out::println); + +// SpringApplication.run(ThingsboardServerApplication.class, updateArguments(args)); } private static String[] updateArguments(String[] args) { diff --git a/application/src/main/java/org/thingsboard/server/service/ws/telemetry/cmd/v2/EntityHistoryCmd.java b/application/src/main/java/org/thingsboard/server/service/ws/telemetry/cmd/v2/EntityHistoryCmd.java index 6ae9a03ff8..3b3dd0d55d 100644 --- a/application/src/main/java/org/thingsboard/server/service/ws/telemetry/cmd/v2/EntityHistoryCmd.java +++ b/application/src/main/java/org/thingsboard/server/service/ws/telemetry/cmd/v2/EntityHistoryCmd.java @@ -17,6 +17,7 @@ package org.thingsboard.server.service.ws.telemetry.cmd.v2; import lombok.Data; import org.thingsboard.server.common.data.kv.Aggregation; +import org.thingsboard.server.common.data.kv.IntervalType; import java.util.List; @@ -26,7 +27,9 @@ public class EntityHistoryCmd implements GetTsCmd { private List keys; private long startTs; private long endTs; + private IntervalType intervalType; private long interval; + private String timeZoneId; private int limit; private Aggregation agg; private boolean fetchLatestPreviousPoint; diff --git a/application/src/main/java/org/thingsboard/server/service/ws/telemetry/cmd/v2/GetTsCmd.java b/application/src/main/java/org/thingsboard/server/service/ws/telemetry/cmd/v2/GetTsCmd.java index 039873bb18..80a749fbe7 100644 --- a/application/src/main/java/org/thingsboard/server/service/ws/telemetry/cmd/v2/GetTsCmd.java +++ b/application/src/main/java/org/thingsboard/server/service/ws/telemetry/cmd/v2/GetTsCmd.java @@ -16,6 +16,7 @@ package org.thingsboard.server.service.ws.telemetry.cmd.v2; import org.thingsboard.server.common.data.kv.Aggregation; +import org.thingsboard.server.common.data.kv.IntervalType; import java.util.List; @@ -27,8 +28,12 @@ public interface GetTsCmd { List getKeys(); + IntervalType getIntervalType(); + long getInterval(); + String getTimeZoneId(); + int getLimit(); Aggregation getAgg(); diff --git a/application/src/main/java/org/thingsboard/server/service/ws/telemetry/cmd/v2/TimeSeriesCmd.java b/application/src/main/java/org/thingsboard/server/service/ws/telemetry/cmd/v2/TimeSeriesCmd.java index e7a9e03d17..3c3d53e426 100644 --- a/application/src/main/java/org/thingsboard/server/service/ws/telemetry/cmd/v2/TimeSeriesCmd.java +++ b/application/src/main/java/org/thingsboard/server/service/ws/telemetry/cmd/v2/TimeSeriesCmd.java @@ -18,6 +18,7 @@ package org.thingsboard.server.service.ws.telemetry.cmd.v2; import com.fasterxml.jackson.annotation.JsonIgnore; import lombok.Data; import org.thingsboard.server.common.data.kv.Aggregation; +import org.thingsboard.server.common.data.kv.IntervalType; import java.util.List; @@ -27,7 +28,9 @@ public class TimeSeriesCmd implements GetTsCmd { private List keys; private long startTs; private long timeWindow; + private IntervalType intervalType; private long interval; + private String timeZoneId; private int limit; private Aggregation agg; private boolean fetchLatestPreviousPoint; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/kv/IntervalType.java b/common/data/src/main/java/org/thingsboard/server/common/data/kv/IntervalType.java new file mode 100644 index 0000000000..e5ebb7f1a1 --- /dev/null +++ b/common/data/src/main/java/org/thingsboard/server/common/data/kv/IntervalType.java @@ -0,0 +1,22 @@ +/** + * Copyright © 2016-2024 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.server.common.data.kv; + +public enum IntervalType { + + MILLISECONDS, WEEK, WEEK_ISO, MONTH, QUARTER + +} From 1256f09e7e2e6135ff6265002a39dcaf90ec7c91 Mon Sep 17 00:00:00 2001 From: Andrii Landiak Date: Wed, 10 Jan 2024 10:19:07 +0200 Subject: [PATCH 064/179] Introduce edge support for alarm comment --- .../edge/DefaultEdgeNotificationService.java | 3 + .../edge/EdgeEventSourcingListener.java | 16 ++- .../service/edge/rpc/EdgeGrpcSession.java | 9 ++ .../alarm/AlarmMsgConstructor.java | 4 + .../alarm/AlarmMsgConstructorV1.java | 2 +- .../alarm/AlarmMsgConstructorV2.java | 2 +- .../alarm/BaseAlarmMsgConstructor.java | 29 ++++ .../edge/rpc/processor/BaseEdgeProcessor.java | 49 +++---- .../processor/alarm/AlarmEdgeProcessor.java | 136 ++++++++++++------ .../rpc/processor/alarm/AlarmProcessor.java | 5 + .../processor/alarm/BaseAlarmProcessor.java | 32 +++++ .../DefaultTbNotificationEntityService.java | 38 +---- .../controller/AbstractNotifyEntityTest.java | 12 +- .../server/edge/imitator/EdgeImitator.java | 6 + .../rpc/processor/BaseEdgeProcessorTest.java | 4 + .../server/dao/alarm/AlarmCommentService.java | 1 + .../server/common/data/EdgeUtils.java | 13 ++ .../common/data/edge/EdgeEventActionType.java | 59 +++++--- .../common/data/edge/EdgeEventType.java | 1 + common/edge-api/src/main/proto/edge.proto | 7 + .../dao/alarm/BaseAlarmCommentService.java | 7 +- .../server/dao/alarm/BaseAlarmService.java | 2 +- .../engine/edge/AbstractTbMsgPushNode.java | 52 ++++--- .../engine/edge/TbMsgPushToCloudNode.java | 5 + .../rule/engine/edge/TbMsgPushToEdgeNode.java | 52 ++++--- 25 files changed, 345 insertions(+), 201 deletions(-) create mode 100644 application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/alarm/BaseAlarmMsgConstructor.java diff --git a/application/src/main/java/org/thingsboard/server/service/edge/DefaultEdgeNotificationService.java b/application/src/main/java/org/thingsboard/server/service/edge/DefaultEdgeNotificationService.java index b3aba37632..03fb982d6d 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/DefaultEdgeNotificationService.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/DefaultEdgeNotificationService.java @@ -216,6 +216,9 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService { case ALARM: alarmProcessor.processAlarmNotification(tenantId, edgeNotificationMsg); break; + case ALARM_COMMENT: + alarmProcessor.processAlarmCommentNotification(tenantId, edgeNotificationMsg); + break; case RELATION: relationProcessor.processRelationNotification(tenantId, edgeNotificationMsg); break; diff --git a/application/src/main/java/org/thingsboard/server/service/edge/EdgeEventSourcingListener.java b/application/src/main/java/org/thingsboard/server/service/edge/EdgeEventSourcingListener.java index 351f42d1fc..5883d04fe6 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/EdgeEventSourcingListener.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/EdgeEventSourcingListener.java @@ -23,10 +23,12 @@ import org.springframework.stereotype.Component; import org.springframework.transaction.event.TransactionalEventListener; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.cluster.TbClusterService; +import org.thingsboard.server.common.data.EdgeUtils; import org.thingsboard.server.common.data.OtaPackageInfo; import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.alarm.Alarm; import org.thingsboard.server.common.data.alarm.AlarmApiCallResult; +import org.thingsboard.server.common.data.alarm.AlarmComment; import org.thingsboard.server.common.data.edge.EdgeEventActionType; import org.thingsboard.server.common.data.edge.EdgeEventType; import org.thingsboard.server.common.data.relation.EntityRelation; @@ -43,8 +45,6 @@ import org.thingsboard.server.dao.user.UserServiceImpl; import javax.annotation.PostConstruct; -import static org.thingsboard.server.service.entitiy.DefaultTbNotificationEntityService.edgeTypeByActionType; - /** * This event listener does not support async event processing because relay on ThreadLocal * Another possible approach is to implement a special annotation and a bunch of classes similar to TransactionalApplicationListener @@ -91,8 +91,12 @@ public class EdgeEventSourcingListener { public void handleEvent(DeleteEntityEvent event) { try { log.trace("[{}] DeleteEntityEvent called: {}", event.getTenantId(), event); + EdgeEventType type = null; + if (event.getEntity() instanceof AlarmComment) { + type = EdgeEventType.ALARM_COMMENT; + } tbClusterService.sendNotificationMsgToEdge(event.getTenantId(), null, event.getEntityId(), - JacksonUtil.toString(event.getEntity()), null, EdgeEventActionType.DELETED, + JacksonUtil.toString(event.getEntity()), type, EdgeEventActionType.DELETED, edgeSynchronizationManager.getEdgeId().get()); } catch (Exception e) { log.error("[{}] failed to process DeleteEntityEvent: {}", event.getTenantId(), event, e); @@ -104,7 +108,7 @@ public class EdgeEventSourcingListener { try { log.trace("[{}] ActionEntityEvent called: {}", event.getTenantId(), event); tbClusterService.sendNotificationMsgToEdge(event.getTenantId(), event.getEdgeId(), event.getEntityId(), - event.getBody(), null, edgeTypeByActionType(event.getActionType()), + event.getBody(), null, EdgeUtils.getEdgeEventActionTypeByActionType(event.getActionType()), edgeSynchronizationManager.getEdgeId().get()); } catch (Exception e) { log.error("[{}] failed to process ActionEntityEvent: {}", event.getTenantId(), event, e); @@ -125,7 +129,7 @@ public class EdgeEventSourcingListener { } log.trace("[{}] RelationActionEvent called: {}", event.getTenantId(), event); tbClusterService.sendNotificationMsgToEdge(event.getTenantId(), null, null, - JacksonUtil.toString(relation), EdgeEventType.RELATION, edgeTypeByActionType(event.getActionType()), + JacksonUtil.toString(relation), EdgeEventType.RELATION, EdgeUtils.getEdgeEventActionTypeByActionType(event.getActionType()), edgeSynchronizationManager.getEdgeId().get()); } catch (Exception e) { log.error("[{}] failed to process RelationActionEvent: {}", event.getTenantId(), event, e); @@ -150,7 +154,7 @@ public class EdgeEventSourcingListener { cleanUpUserAdditionalInfo(user); return !user.equals(oldUser); } - } else if (entity instanceof AlarmApiCallResult || entity instanceof Alarm) { + } else if (entity instanceof AlarmApiCallResult || entity instanceof Alarm || entity instanceof AlarmComment) { return false; } // Default: If the entity doesn't match any of the conditions, consider it as valid. diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java index f1f473f976..14572bc871 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java @@ -39,6 +39,7 @@ import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.page.SortOrder; import org.thingsboard.server.common.data.page.TimePageLink; +import org.thingsboard.server.gen.edge.v1.AlarmCommentUpdateMsg; import org.thingsboard.server.gen.edge.v1.AlarmUpdateMsg; import org.thingsboard.server.gen.edge.v1.AssetProfileUpdateMsg; import org.thingsboard.server.gen.edge.v1.AssetUpdateMsg; @@ -644,6 +645,8 @@ public final class EdgeGrpcSession implements Closeable { return ctx.getRuleChainProcessor().convertRuleChainMetadataEventToDownlink(edgeEvent, this.edgeVersion); case ALARM: return ctx.getAlarmProcessor().convertAlarmEventToDownlink(edgeEvent, this.edgeVersion); + case ALARM_COMMENT: + return ctx.getAlarmProcessor().convertAlarmCommentEventToDownlink(edgeEvent, this.edgeVersion); case USER: return ctx.getUserProcessor().convertUserEventToDownlink(edgeEvent, this.edgeVersion); case RELATION: @@ -714,6 +717,12 @@ public final class EdgeGrpcSession implements Closeable { .processAlarmMsgFromEdge(edge.getTenantId(), edge.getId(), alarmUpdateMsg)); } } + if (uplinkMsg.getAlarmCommentUpdateMsgCount() > 0) { + for (AlarmCommentUpdateMsg alarmCommentUpdateMsg : uplinkMsg.getAlarmCommentUpdateMsgList()) { + result.add(((AlarmProcessor) ctx.getAlarmEdgeProcessorFactory().getProcessorByEdgeVersion(this.edgeVersion)) + .processAlarmCommentMsgFromEdge(edge.getTenantId(), edge.getId(), alarmCommentUpdateMsg)); + } + } if (uplinkMsg.getEntityViewUpdateMsgCount() > 0) { for (EntityViewUpdateMsg entityViewUpdateMsg : uplinkMsg.getEntityViewUpdateMsgList()) { result.add(((EntityViewProcessor) ctx.getEntityViewProcessorFactory().getProcessorByEdgeVersion(this.edgeVersion)) diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/alarm/AlarmMsgConstructor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/alarm/AlarmMsgConstructor.java index 81606434b5..b5a0f20d6b 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/alarm/AlarmMsgConstructor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/alarm/AlarmMsgConstructor.java @@ -16,6 +16,8 @@ package org.thingsboard.server.service.edge.rpc.constructor.alarm; import org.thingsboard.server.common.data.alarm.Alarm; +import org.thingsboard.server.common.data.alarm.AlarmComment; +import org.thingsboard.server.gen.edge.v1.AlarmCommentUpdateMsg; import org.thingsboard.server.gen.edge.v1.AlarmUpdateMsg; import org.thingsboard.server.gen.edge.v1.UpdateMsgType; import org.thingsboard.server.service.edge.rpc.constructor.MsgConstructor; @@ -23,4 +25,6 @@ import org.thingsboard.server.service.edge.rpc.constructor.MsgConstructor; public interface AlarmMsgConstructor extends MsgConstructor { AlarmUpdateMsg constructAlarmUpdatedMsg(UpdateMsgType msgType, Alarm alarm, String entityName); + + AlarmCommentUpdateMsg constructAlarmCommentUpdatedMsg(UpdateMsgType msgType, AlarmComment alarmComment); } diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/alarm/AlarmMsgConstructorV1.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/alarm/AlarmMsgConstructorV1.java index 5abba029de..81a489671f 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/alarm/AlarmMsgConstructorV1.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/alarm/AlarmMsgConstructorV1.java @@ -24,7 +24,7 @@ import org.thingsboard.server.queue.util.TbCoreComponent; @Component @TbCoreComponent -public class AlarmMsgConstructorV1 implements AlarmMsgConstructor { +public class AlarmMsgConstructorV1 extends BaseAlarmMsgConstructor { @Override public AlarmUpdateMsg constructAlarmUpdatedMsg(UpdateMsgType msgType, Alarm alarm, String entityName) { diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/alarm/AlarmMsgConstructorV2.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/alarm/AlarmMsgConstructorV2.java index d9768b8f9e..143a41b73c 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/alarm/AlarmMsgConstructorV2.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/alarm/AlarmMsgConstructorV2.java @@ -24,7 +24,7 @@ import org.thingsboard.server.queue.util.TbCoreComponent; @Component @TbCoreComponent -public class AlarmMsgConstructorV2 implements AlarmMsgConstructor { +public class AlarmMsgConstructorV2 extends BaseAlarmMsgConstructor { @Override public AlarmUpdateMsg constructAlarmUpdatedMsg(UpdateMsgType msgType, Alarm alarm, String entityName) { diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/alarm/BaseAlarmMsgConstructor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/alarm/BaseAlarmMsgConstructor.java new file mode 100644 index 0000000000..c9af86e8cc --- /dev/null +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/alarm/BaseAlarmMsgConstructor.java @@ -0,0 +1,29 @@ +/** + * Copyright © 2016-2024 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.server.service.edge.rpc.constructor.alarm; + +import org.thingsboard.common.util.JacksonUtil; +import org.thingsboard.server.common.data.alarm.AlarmComment; +import org.thingsboard.server.gen.edge.v1.AlarmCommentUpdateMsg; +import org.thingsboard.server.gen.edge.v1.UpdateMsgType; + +public abstract class BaseAlarmMsgConstructor implements AlarmMsgConstructor { + + @Override + public AlarmCommentUpdateMsg constructAlarmCommentUpdatedMsg(UpdateMsgType msgType, AlarmComment alarmComment) { + return AlarmCommentUpdateMsg.newBuilder().setMsgType(msgType).setEntity(JacksonUtil.toString(alarmComment)).build(); + } +} diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/BaseEdgeProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/BaseEdgeProcessor.java index 6f7474b15d..256f191215 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/BaseEdgeProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/BaseEdgeProcessor.java @@ -51,6 +51,7 @@ import org.thingsboard.server.common.data.id.UserId; import org.thingsboard.server.common.data.kv.AttributeKvEntry; import org.thingsboard.server.common.data.msg.TbMsgType; import org.thingsboard.server.common.data.page.PageData; +import org.thingsboard.server.common.data.page.PageDataIterableByTenantIdEntityId; import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.relation.EntityRelation; import org.thingsboard.server.common.data.relation.RelationTypeGroup; @@ -59,6 +60,7 @@ import org.thingsboard.server.common.data.rule.RuleChainConnectionInfo; 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.alarm.AlarmCommentService; import org.thingsboard.server.dao.alarm.AlarmService; import org.thingsboard.server.dao.asset.AssetProfileService; import org.thingsboard.server.dao.asset.AssetService; @@ -145,6 +147,9 @@ public abstract class BaseEdgeProcessor { @Autowired protected AlarmService alarmService; + @Autowired + protected AlarmCommentService alarmCommentService; + @Autowired protected DeviceService deviceService; @@ -350,10 +355,13 @@ public abstract class BaseEdgeProcessor { case ALARM_ASSIGNED: case ALARM_UNASSIGNED: case CREDENTIALS_REQUEST: + case ADDED_COMMENT: + case UPDATED_COMMENT: return true; } switch (type) { case ALARM: + case ALARM_COMMENT: case RULE_CHAIN: case RULE_CHAIN_METADATA: case USER: @@ -441,14 +449,17 @@ public abstract class BaseEdgeProcessor { case CREDENTIALS_UPDATED: case ASSIGNED_TO_CUSTOMER: case UNASSIGNED_FROM_CUSTOMER: + case UPDATED_COMMENT: return UpdateMsgType.ENTITY_UPDATED_RPC_MESSAGE; case ADDED: case ASSIGNED_TO_EDGE: case RELATION_ADD_OR_UPDATE: + case ADDED_COMMENT: return UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE; case DELETED: case UNASSIGNED_FROM_EDGE: case RELATION_DELETED: + case DELETED_COMMENT: return UpdateMsgType.ENTITY_DELETED_RPC_MESSAGE; case ALARM_ACK: return UpdateMsgType.ALARM_ACK_RPC_MESSAGE; @@ -517,22 +528,14 @@ public abstract class BaseEdgeProcessor { private ListenableFuture processNotificationToRelatedEdges(TenantId tenantId, EntityId entityId, EdgeEventType type, EdgeEventActionType actionType, EdgeId sourceEdgeId) { - PageLink pageLink = new PageLink(DEFAULT_PAGE_SIZE); - PageData pageData; List> futures = new ArrayList<>(); - do { - pageData = edgeService.findRelatedEdgeIdsByEntityId(tenantId, entityId, pageLink); - if (pageData != null && pageData.getData() != null && !pageData.getData().isEmpty()) { - for (EdgeId relatedEdgeId : pageData.getData()) { - if (!relatedEdgeId.equals(sourceEdgeId)) { - futures.add(saveEdgeEvent(tenantId, relatedEdgeId, type, actionType, entityId, null)); - } - } - if (pageData.hasNext()) { - pageLink = pageLink.nextPageLink(); - } + PageDataIterableByTenantIdEntityId edgeIds = + new PageDataIterableByTenantIdEntityId<>(edgeService::findRelatedEdgeIdsByEntityId, tenantId, entityId, DEFAULT_PAGE_SIZE); + for (EdgeId relatedEdgeId : edgeIds) { + if (!relatedEdgeId.equals(sourceEdgeId)) { + futures.add(saveEdgeEvent(tenantId, relatedEdgeId, type, actionType, entityId, null)); } - } while (pageData != null && pageData.hasNext()); + } return Futures.transform(Futures.allAsList(futures), voids -> null, dbCallbackExecutorService); } @@ -715,19 +718,13 @@ public abstract class BaseEdgeProcessor { } private boolean isEntityNotAssignedToEdge(TenantId tenantId, EntityId entityId, EdgeId edgeId) { - PageLink pageLink = new PageLink(DEFAULT_PAGE_SIZE); - PageData pageData; - do { - pageData = edgeService.findRelatedEdgeIdsByEntityId(tenantId, entityId, pageLink); - if (pageData != null && pageData.getData() != null && !pageData.getData().isEmpty()) { - if (pageData.getData().contains(edgeId)) { - return false; - } - if (pageData.hasNext()) { - pageLink = pageLink.nextPageLink(); - } + PageDataIterableByTenantIdEntityId edgeIds = + new PageDataIterableByTenantIdEntityId<>(edgeService::findRelatedEdgeIdsByEntityId, tenantId, entityId, DEFAULT_PAGE_SIZE); + for (EdgeId edgeId1 : edgeIds) { + if (edgeId1.equals(edgeId)) { + return false; } - } while (pageData != null && pageData.hasNext()); + } return true; } } diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/alarm/AlarmEdgeProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/alarm/AlarmEdgeProcessor.java index ea48032b69..e6889a1e6f 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/alarm/AlarmEdgeProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/alarm/AlarmEdgeProcessor.java @@ -22,22 +22,30 @@ import lombok.extern.slf4j.Slf4j; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.common.data.EdgeUtils; import org.thingsboard.server.common.data.alarm.Alarm; +import org.thingsboard.server.common.data.alarm.AlarmComment; import org.thingsboard.server.common.data.edge.EdgeEvent; import org.thingsboard.server.common.data.edge.EdgeEventActionType; import org.thingsboard.server.common.data.edge.EdgeEventType; +import org.thingsboard.server.common.data.id.AlarmCommentId; import org.thingsboard.server.common.data.id.AlarmId; import org.thingsboard.server.common.data.id.EdgeId; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageData; +import org.thingsboard.server.common.data.page.PageDataIterable; +import org.thingsboard.server.common.data.page.PageDataIterableByTenantIdEntityId; import org.thingsboard.server.common.data.page.PageLink; +import org.thingsboard.server.gen.edge.v1.AlarmCommentUpdateMsg; import org.thingsboard.server.gen.edge.v1.AlarmUpdateMsg; import org.thingsboard.server.gen.edge.v1.DownlinkMsg; import org.thingsboard.server.gen.edge.v1.EdgeVersion; +import org.thingsboard.server.gen.edge.v1.UpdateMsgType; import org.thingsboard.server.gen.transport.TransportProtos; +import org.thingsboard.server.service.edge.rpc.constructor.alarm.AlarmMsgConstructor; import java.util.ArrayList; import java.util.List; +import java.util.Optional; import java.util.UUID; @Slf4j @@ -67,58 +75,100 @@ public abstract class AlarmEdgeProcessor extends BaseAlarmProcessor implements A return null; } + @Override + public ListenableFuture processAlarmCommentMsgFromEdge(TenantId tenantId, EdgeId edgeId, AlarmCommentUpdateMsg alarmCommentUpdateMsg) { + log.trace("[{}] processAlarmCommentMsgFromEdge [{}]", tenantId, alarmCommentUpdateMsg); + try { + edgeSynchronizationManager.getEdgeId().set(edgeId); + return processAlarmCommentMsg(tenantId, alarmCommentUpdateMsg); + } finally { + edgeSynchronizationManager.getEdgeId().remove(); + } + } + + @Override + public DownlinkMsg convertAlarmCommentEventToDownlink(EdgeEvent edgeEvent, EdgeVersion edgeVersion) { + AlarmCommentId alarmCommentId = new AlarmCommentId(edgeEvent.getEntityId()); + UpdateMsgType msgType = getUpdateMsgType(edgeEvent.getAction()); + AlarmComment alarmComment; + switch (edgeEvent.getAction()) { + case ADDED_COMMENT: + case UPDATED_COMMENT: + alarmComment = alarmCommentService.findAlarmCommentById(edgeEvent.getTenantId(), alarmCommentId); + break; + case DELETED_COMMENT: + alarmComment = JacksonUtil.convertValue(edgeEvent.getBody(), AlarmComment.class); + break; + default: + return null; + } + return Optional.ofNullable(alarmComment).map(comment -> buildAlarmCommentDownlinkMsg(msgType, comment, edgeVersion)).orElse(null); + } + + private DownlinkMsg buildAlarmCommentDownlinkMsg(UpdateMsgType msgType, AlarmComment alarmComment, EdgeVersion edgeVersion) { + return DownlinkMsg.newBuilder() + .setDownlinkMsgId(EdgeUtils.nextPositiveInt()) + .addAlarmCommentUpdateMsg(((AlarmMsgConstructor) alarmMsgConstructorFactory + .getMsgConstructorByEdgeVersion(edgeVersion)).constructAlarmCommentUpdatedMsg(msgType, alarmComment)) + .build(); + } + public ListenableFuture processAlarmNotification(TenantId tenantId, TransportProtos.EdgeNotificationMsgProto edgeNotificationMsg) { EdgeEventActionType actionType = EdgeEventActionType.valueOf(edgeNotificationMsg.getAction()); AlarmId alarmId = new AlarmId(new UUID(edgeNotificationMsg.getEntityIdMSB(), edgeNotificationMsg.getEntityIdLSB())); EdgeId originatorEdgeId = safeGetEdgeId(edgeNotificationMsg.getOriginatorEdgeIdMSB(), edgeNotificationMsg.getOriginatorEdgeIdLSB()); - switch (actionType) { - case DELETED: - Alarm deletedAlarm = JacksonUtil.fromString(edgeNotificationMsg.getBody(), Alarm.class); - if (deletedAlarm == null) { - return Futures.immediateFuture(null); - } - List> delFutures = pushEventToAllRelatedEdges(tenantId, deletedAlarm.getOriginator(), - alarmId, actionType, JacksonUtil.valueToTree(deletedAlarm), originatorEdgeId); - return Futures.transform(Futures.allAsList(delFutures), voids -> null, dbCallbackExecutorService); - default: - ListenableFuture alarmFuture = alarmService.findAlarmByIdAsync(tenantId, alarmId); - return Futures.transformAsync(alarmFuture, alarm -> { - if (alarm == null) { - return Futures.immediateFuture(null); - } - EdgeEventType type = EdgeUtils.getEdgeEventTypeByEntityType(alarm.getOriginator().getEntityType()); - if (type == null) { - return Futures.immediateFuture(null); - } - List> futures = pushEventToAllRelatedEdges(tenantId, alarm.getOriginator(), - alarmId, actionType, null, originatorEdgeId); - return Futures.transform(Futures.allAsList(futures), voids -> null, dbCallbackExecutorService); - }, dbCallbackExecutorService); + if (EdgeEventActionType.DELETED.equals(actionType)) { + Alarm deletedAlarm = JacksonUtil.fromString(edgeNotificationMsg.getBody(), Alarm.class); + if (deletedAlarm == null) { + return Futures.immediateFuture(null); + } + List> delFutures = pushEventToAllRelatedEdges(tenantId, deletedAlarm.getOriginator(), + alarmId, actionType, JacksonUtil.valueToTree(deletedAlarm), originatorEdgeId, EdgeEventType.ALARM); + return Futures.transform(Futures.allAsList(delFutures), voids -> null, dbCallbackExecutorService); } + ListenableFuture alarmFuture = alarmService.findAlarmByIdAsync(tenantId, alarmId); + return Futures.transformAsync(alarmFuture, alarm -> { + if (alarm == null) { + return Futures.immediateFuture(null); + } + EdgeEventType type = EdgeUtils.getEdgeEventTypeByEntityType(alarm.getOriginator().getEntityType()); + if (type == null) { + return Futures.immediateFuture(null); + } + List> futures = pushEventToAllRelatedEdges(tenantId, alarm.getOriginator(), + alarmId, actionType, null, originatorEdgeId, EdgeEventType.ALARM); + return Futures.transform(Futures.allAsList(futures), voids -> null, dbCallbackExecutorService); + }, dbCallbackExecutorService); } - private List> pushEventToAllRelatedEdges(TenantId tenantId, EntityId originatorId, AlarmId alarmId, EdgeEventActionType actionType, JsonNode body, EdgeId sourceEdgeId) { - PageLink pageLink = new PageLink(DEFAULT_PAGE_SIZE); - PageData pageData; + public ListenableFuture processAlarmCommentNotification(TenantId tenantId, TransportProtos.EdgeNotificationMsgProto edgeNotificationMsg) { + EdgeEventActionType actionType = EdgeEventActionType.valueOf(edgeNotificationMsg.getAction()); + AlarmId alarmId = new AlarmId(new UUID(edgeNotificationMsg.getEntityIdMSB(), edgeNotificationMsg.getEntityIdLSB())); + EdgeId originatorEdgeId = safeGetEdgeId(edgeNotificationMsg.getOriginatorEdgeIdMSB(), edgeNotificationMsg.getOriginatorEdgeIdLSB()); + if (EdgeEventActionType.DELETED.equals(actionType)) { + AlarmComment deletedAlarmComment = JacksonUtil.fromString(edgeNotificationMsg.getBody(), AlarmComment.class); + if (deletedAlarmComment == null) { + return Futures.immediateFuture(null); + } + Alarm alarmById = alarmService.findAlarmById(tenantId, new AlarmId(deletedAlarmComment.getAlarmId().getId())); + List> delFutures = pushEventToAllRelatedEdges(tenantId, alarmById.getOriginator(), + alarmId, actionType, JacksonUtil.valueToTree(deletedAlarmComment), originatorEdgeId, EdgeEventType.ALARM_COMMENT); + return Futures.transform(Futures.allAsList(delFutures), voids -> null, dbCallbackExecutorService); + } + return Futures.immediateFuture(null); + } + + private List> pushEventToAllRelatedEdges(TenantId tenantId, EntityId originatorId, AlarmId alarmId, + EdgeEventActionType actionType, JsonNode body, EdgeId sourceEdgeId, + EdgeEventType edgeEventType) { List> futures = new ArrayList<>(); - do { - pageData = edgeService.findRelatedEdgeIdsByEntityId(tenantId, originatorId, pageLink); - if (pageData != null && pageData.getData() != null && !pageData.getData().isEmpty()) { - for (EdgeId relatedEdgeId : pageData.getData()) { - if (!relatedEdgeId.equals(sourceEdgeId)) { - futures.add(saveEdgeEvent(tenantId, - relatedEdgeId, - EdgeEventType.ALARM, - actionType, - alarmId, - body)); - } - } - if (pageData.hasNext()) { - pageLink = pageLink.nextPageLink(); - } + PageDataIterableByTenantIdEntityId edgeIds = + new PageDataIterableByTenantIdEntityId<>(edgeService::findRelatedEdgeIdsByEntityId, tenantId, originatorId, DEFAULT_PAGE_SIZE); + for (EdgeId relatedEdgeId : edgeIds) { + if (!relatedEdgeId.equals(sourceEdgeId)) { + futures.add(saveEdgeEvent(tenantId, relatedEdgeId, edgeEventType, actionType, alarmId, body)); } - } while (pageData != null && pageData.hasNext()); + } return futures; } } diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/alarm/AlarmProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/alarm/AlarmProcessor.java index 68a72bf01e..938269462d 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/alarm/AlarmProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/alarm/AlarmProcessor.java @@ -19,6 +19,7 @@ import com.google.common.util.concurrent.ListenableFuture; import org.thingsboard.server.common.data.edge.EdgeEvent; import org.thingsboard.server.common.data.id.EdgeId; import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.gen.edge.v1.AlarmCommentUpdateMsg; import org.thingsboard.server.gen.edge.v1.AlarmUpdateMsg; import org.thingsboard.server.gen.edge.v1.DownlinkMsg; import org.thingsboard.server.gen.edge.v1.EdgeVersion; @@ -29,4 +30,8 @@ public interface AlarmProcessor extends EdgeProcessor { ListenableFuture processAlarmMsgFromEdge(TenantId tenantId, EdgeId edgeId, AlarmUpdateMsg alarmUpdateMsg); DownlinkMsg convertAlarmEventToDownlink(EdgeEvent edgeEvent, EdgeVersion edgeVersion); + + ListenableFuture processAlarmCommentMsgFromEdge(TenantId tenantId, EdgeId edgeId, AlarmCommentUpdateMsg alarmCommentUpdateMsg); + + DownlinkMsg convertAlarmCommentEventToDownlink(EdgeEvent edgeEvent, EdgeVersion edgeVersion); } diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/alarm/BaseAlarmProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/alarm/BaseAlarmProcessor.java index 546d6e63db..6d04db5b75 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/alarm/BaseAlarmProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/alarm/BaseAlarmProcessor.java @@ -23,6 +23,7 @@ import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.EntityView; import org.thingsboard.server.common.data.alarm.Alarm; +import org.thingsboard.server.common.data.alarm.AlarmComment; import org.thingsboard.server.common.data.alarm.AlarmCreateOrUpdateActiveRequest; import org.thingsboard.server.common.data.alarm.AlarmUpdateRequest; import org.thingsboard.server.common.data.asset.Asset; @@ -33,6 +34,7 @@ import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.EntityViewId; import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.gen.edge.v1.AlarmCommentUpdateMsg; import org.thingsboard.server.gen.edge.v1.AlarmUpdateMsg; import org.thingsboard.server.gen.edge.v1.EdgeVersion; import org.thingsboard.server.gen.edge.v1.UpdateMsgType; @@ -93,6 +95,36 @@ public abstract class BaseAlarmProcessor extends BaseEdgeProcessor { return Futures.immediateFuture(null); } + public ListenableFuture processAlarmCommentMsg(TenantId tenantId, AlarmCommentUpdateMsg alarmCommentUpdateMsg) { + log.trace("[{}] processAlarmCommentMsg [{}]", tenantId, alarmCommentUpdateMsg); + AlarmComment alarmComment = JacksonUtil.fromString(alarmCommentUpdateMsg.getEntity(), AlarmComment.class, true); + if (alarmComment == null) { + throw new RuntimeException("[{" + tenantId + "}] alarmCommentUpdateMsg {" + alarmCommentUpdateMsg + "} cannot be converted to alarm comment"); + } + try { + switch (alarmCommentUpdateMsg.getMsgType()) { + case ENTITY_CREATED_RPC_MESSAGE: + case ENTITY_UPDATED_RPC_MESSAGE: + alarmCommentService.createOrUpdateAlarmComment(tenantId, alarmComment); + break; + case ENTITY_DELETED_RPC_MESSAGE: + AlarmComment alarmCommentToDelete = alarmCommentService.findAlarmCommentById(tenantId, alarmComment.getId()); + if (alarmCommentToDelete != null) { + alarmCommentService.saveAlarmComment(tenantId, alarmCommentToDelete); + } + break; + case UNRECOGNIZED: + default: + return handleUnsupportedMsgType(alarmCommentUpdateMsg.getMsgType()); + } + } catch (Exception e) { + log.error("[{}] Failed to process alarm comment update msg [{}]", tenantId, alarmCommentUpdateMsg, e); + return Futures.immediateFailedFuture(e); + } + return Futures.immediateFuture(null); + } + + protected abstract EntityId getAlarmOriginatorFromMsg(TenantId tenantId, AlarmUpdateMsg alarmUpdateMsg); protected abstract Alarm constructAlarmFromUpdateMsg(TenantId tenantId, AlarmId alarmId, EntityId originatorId, AlarmUpdateMsg alarmUpdateMsg); diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/DefaultTbNotificationEntityService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/DefaultTbNotificationEntityService.java index 321cc69604..3a87fff506 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/DefaultTbNotificationEntityService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/DefaultTbNotificationEntityService.java @@ -19,7 +19,6 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.thingsboard.common.util.JacksonUtil; -import org.thingsboard.server.common.msg.rule.engine.DeviceCredentialsUpdateNotificationMsg; import org.thingsboard.server.cluster.TbClusterService; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.HasName; @@ -27,7 +26,6 @@ import org.thingsboard.server.common.data.Tenant; import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.edge.Edge; -import org.thingsboard.server.common.data.edge.EdgeEventActionType; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.EdgeId; @@ -40,6 +38,7 @@ import org.thingsboard.server.common.data.security.DeviceCredentials; 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.common.msg.rule.engine.DeviceCredentialsUpdateNotificationMsg; import org.thingsboard.server.service.action.EntityActionService; import org.thingsboard.server.service.gateway_device.GatewayNotificationsService; @@ -174,39 +173,4 @@ public class DefaultTbNotificationEntityService implements TbNotificationEntityS metaData.putValue("assignedFromTenantName", tenant.getName()); return metaData; } - - public static EdgeEventActionType edgeTypeByActionType(ActionType actionType) { - switch (actionType) { - case ADDED: - return EdgeEventActionType.ADDED; - case UPDATED: - return EdgeEventActionType.UPDATED; - case ALARM_ACK: - return EdgeEventActionType.ALARM_ACK; - case ALARM_CLEAR: - return EdgeEventActionType.ALARM_CLEAR; - case ALARM_ASSIGNED: - return EdgeEventActionType.ALARM_ASSIGNED; - case ALARM_UNASSIGNED: - return EdgeEventActionType.ALARM_UNASSIGNED; - case DELETED: - return EdgeEventActionType.DELETED; - case RELATION_ADD_OR_UPDATE: - return EdgeEventActionType.RELATION_ADD_OR_UPDATE; - case RELATION_DELETED: - return EdgeEventActionType.RELATION_DELETED; - case ASSIGNED_TO_CUSTOMER: - return EdgeEventActionType.ASSIGNED_TO_CUSTOMER; - case UNASSIGNED_FROM_CUSTOMER: - return EdgeEventActionType.UNASSIGNED_FROM_CUSTOMER; - case ASSIGNED_TO_EDGE: - return EdgeEventActionType.ASSIGNED_TO_EDGE; - case UNASSIGNED_FROM_EDGE: - return EdgeEventActionType.UNASSIGNED_FROM_EDGE; - case CREDENTIALS_UPDATED: - return EdgeEventActionType.CREDENTIALS_UPDATED; - default: - return null; - } - } } diff --git a/application/src/test/java/org/thingsboard/server/controller/AbstractNotifyEntityTest.java b/application/src/test/java/org/thingsboard/server/controller/AbstractNotifyEntityTest.java index 429d0b765f..44302f08ba 100644 --- a/application/src/test/java/org/thingsboard/server/controller/AbstractNotifyEntityTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/AbstractNotifyEntityTest.java @@ -20,6 +20,7 @@ import org.mockito.ArgumentMatcher; import org.mockito.Mockito; import org.springframework.boot.test.mock.mockito.SpyBean; import org.thingsboard.server.cluster.TbClusterService; +import org.thingsboard.server.common.data.EdgeUtils; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.HasName; import org.thingsboard.server.common.data.HasTenantId; @@ -47,7 +48,6 @@ import java.util.stream.Collectors; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; -import static org.thingsboard.server.service.entitiy.DefaultTbNotificationEntityService.edgeTypeByActionType; @Slf4j public abstract class AbstractNotifyEntityTest extends AbstractWebTest { @@ -91,7 +91,7 @@ public abstract class AbstractNotifyEntityTest extends AbstractWebTest { int cntTime = 1; Mockito.verify(tbClusterService, times(cntTime)).sendNotificationMsgToEdge(Mockito.eq(tenantId), Mockito.isNull(), Mockito.isNull(), Mockito.any(), Mockito.eq(EdgeEventType.RELATION), - Mockito.eq(edgeTypeByActionType(actionType)), Mockito.any()); + Mockito.eq(EdgeUtils.getEdgeEventActionTypeByActionType(actionType)), Mockito.any()); ArgumentMatcher matcherOriginatorId = argument -> argument.equals(relation.getTo()); ArgumentMatcher matcherEntityClassEquals = Objects::isNull; ArgumentMatcher matcherCustomerId = customerId == null ? @@ -111,7 +111,7 @@ public abstract class AbstractNotifyEntityTest extends AbstractWebTest { ActionType actionType, int cntTime) { Mockito.verify(tbClusterService, times(cntTime)).sendNotificationMsgToEdge(Mockito.eq(tenantId), Mockito.isNull(), Mockito.isNull(), Mockito.any(), Mockito.eq(EdgeEventType.RELATION), - Mockito.eq(edgeTypeByActionType(actionType)), Mockito.any()); + Mockito.eq(EdgeUtils.getEdgeEventActionTypeByActionType(actionType)), Mockito.any()); ArgumentMatcher matcherOriginatorId = argument -> argument.getClass().equals(relation.getFrom().getClass()); ArgumentMatcher matcherEntityClassEquals = Objects::isNull; ArgumentMatcher matcherCustomerId = customerId == null ? @@ -317,7 +317,7 @@ public abstract class AbstractNotifyEntityTest extends AbstractWebTest { private void testNotificationMsgToEdgeServiceNeverWithActionType(EntityId entityId, ActionType actionType) { EdgeEventActionType edgeEventActionType = ActionType.CREDENTIALS_UPDATED.equals(actionType) ? - EdgeEventActionType.CREDENTIALS_UPDATED : edgeTypeByActionType(actionType); + EdgeEventActionType.CREDENTIALS_UPDATED : EdgeUtils.getEdgeEventActionTypeByActionType(actionType); Mockito.verify(tbClusterService, never()).sendNotificationMsgToEdge(Mockito.any(), Mockito.any(), Mockito.any(entityId.getClass()), Mockito.any(), Mockito.any(), Mockito.eq(edgeEventActionType), Mockito.any()); } @@ -353,7 +353,7 @@ public abstract class AbstractNotifyEntityTest extends AbstractWebTest { private void testNotificationMsgToEdgeServiceTime(EntityId entityId, TenantId tenantId, ActionType actionType, int cntTime) { EdgeEventActionType edgeEventActionType = ActionType.CREDENTIALS_UPDATED.equals(actionType) ? - EdgeEventActionType.CREDENTIALS_UPDATED : edgeTypeByActionType(actionType); + EdgeEventActionType.CREDENTIALS_UPDATED : EdgeUtils.getEdgeEventActionTypeByActionType(actionType); ArgumentMatcher matcherEntityId = cntTime == 1 ? argument -> argument.equals(entityId) : argument -> argument.getClass().equals(entityId.getClass()); Mockito.verify(tbClusterService, times(cntTime)).sendNotificationMsgToEdge(Mockito.eq(tenantId), @@ -364,7 +364,7 @@ public abstract class AbstractNotifyEntityTest extends AbstractWebTest { private void testSendNotificationMsgToEdgeServiceTimeEntityEqAny(TenantId tenantId, ActionType actionType, int cntTime) { Mockito.verify(tbClusterService, times(cntTime)).sendNotificationMsgToEdge(Mockito.eq(tenantId), Mockito.any(), Mockito.any(EntityId.class), Mockito.any(), Mockito.isNull(), - Mockito.eq(edgeTypeByActionType(actionType)), Mockito.any()); + Mockito.eq(EdgeUtils.getEdgeEventActionTypeByActionType(actionType)), Mockito.any()); } protected void testBroadcastEntityStateChangeEventTime(EntityId entityId, TenantId tenantId, int cntTime) { diff --git a/application/src/test/java/org/thingsboard/server/edge/imitator/EdgeImitator.java b/application/src/test/java/org/thingsboard/server/edge/imitator/EdgeImitator.java index f7c464fab9..f5e018ed3a 100644 --- a/application/src/test/java/org/thingsboard/server/edge/imitator/EdgeImitator.java +++ b/application/src/test/java/org/thingsboard/server/edge/imitator/EdgeImitator.java @@ -27,6 +27,7 @@ import org.checkerframework.checker.nullness.qual.Nullable; import org.thingsboard.edge.rpc.EdgeGrpcClient; import org.thingsboard.edge.rpc.EdgeRpcClient; import org.thingsboard.server.gen.edge.v1.AdminSettingsUpdateMsg; +import org.thingsboard.server.gen.edge.v1.AlarmCommentUpdateMsg; import org.thingsboard.server.gen.edge.v1.AlarmUpdateMsg; import org.thingsboard.server.gen.edge.v1.AssetProfileUpdateMsg; import org.thingsboard.server.gen.edge.v1.AssetUpdateMsg; @@ -231,6 +232,11 @@ public class EdgeImitator { result.add(saveDownlinkMsg(alarmUpdateMsg)); } } + if (downlinkMsg.getAlarmCommentUpdateMsgCount() > 0) { + for (AlarmCommentUpdateMsg alarmCommentUpdateMsg : downlinkMsg.getAlarmCommentUpdateMsgList()) { + result.add(saveDownlinkMsg(alarmCommentUpdateMsg)); + } + } if (downlinkMsg.getEntityDataCount() > 0) { for (EntityDataProto entityData : downlinkMsg.getEntityDataList()) { if (randomFailuresOnTimeseriesDownlink) { diff --git a/application/src/test/java/org/thingsboard/server/service/edge/rpc/processor/BaseEdgeProcessorTest.java b/application/src/test/java/org/thingsboard/server/service/edge/rpc/processor/BaseEdgeProcessorTest.java index 384c00c8ed..9c45977a7c 100644 --- a/application/src/test/java/org/thingsboard/server/service/edge/rpc/processor/BaseEdgeProcessorTest.java +++ b/application/src/test/java/org/thingsboard/server/service/edge/rpc/processor/BaseEdgeProcessorTest.java @@ -32,6 +32,7 @@ import org.thingsboard.server.common.data.id.DashboardId; import org.thingsboard.server.common.data.id.EdgeId; import org.thingsboard.server.common.data.id.RuleChainId; import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.dao.alarm.AlarmCommentService; import org.thingsboard.server.dao.alarm.AlarmService; import org.thingsboard.server.dao.asset.AssetProfileService; import org.thingsboard.server.dao.asset.AssetService; @@ -157,6 +158,9 @@ public abstract class BaseEdgeProcessorTest { @MockBean protected AlarmService alarmService; + @MockBean + protected AlarmCommentService alarmCommentService; + @MockBean protected DeviceService deviceService; diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/alarm/AlarmCommentService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/alarm/AlarmCommentService.java index 7bee9f6983..c822693a71 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/alarm/AlarmCommentService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/alarm/AlarmCommentService.java @@ -25,6 +25,7 @@ import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; public interface AlarmCommentService { + AlarmComment createOrUpdateAlarmComment(TenantId tenantId, AlarmComment alarmComment); AlarmComment saveAlarmComment(TenantId tenantId, AlarmComment alarmComment); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/EdgeUtils.java b/common/data/src/main/java/org/thingsboard/server/common/data/EdgeUtils.java index dc969bb362..69a3fc7d8c 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/EdgeUtils.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/EdgeUtils.java @@ -18,6 +18,7 @@ package org.thingsboard.server.common.data; import com.fasterxml.jackson.databind.JsonNode; import com.google.common.base.Throwables; import lombok.extern.slf4j.Slf4j; +import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.edge.EdgeEvent; import org.thingsboard.server.common.data.edge.EdgeEventActionType; import org.thingsboard.server.common.data.edge.EdgeEventType; @@ -32,6 +33,7 @@ import java.util.concurrent.ThreadLocalRandom; public final class EdgeUtils { private static final EnumMap entityTypeEdgeEventTypeEnumMap; + private static final EnumMap actionTypeEdgeEventActionTypeEnumMap; static { entityTypeEdgeEventTypeEnumMap = new EnumMap<>(EntityType.class); @@ -40,6 +42,13 @@ public final class EdgeUtils { entityTypeEdgeEventTypeEnumMap.put(edgeEventType.getEntityType(), edgeEventType); } } + + actionTypeEdgeEventActionTypeEnumMap = new EnumMap<>(ActionType.class); + for (EdgeEventActionType edgeEventActionType : EdgeEventActionType.values()) { + if (edgeEventActionType.getActionType() != null) { + actionTypeEdgeEventActionTypeEnumMap.put(edgeEventActionType.getActionType(), edgeEventActionType); + } + } } private static final int STACK_TRACE_LIMIT = 10; @@ -54,6 +63,10 @@ public final class EdgeUtils { return entityTypeEdgeEventTypeEnumMap.get(entityType); } + public static EdgeEventActionType getEdgeEventActionTypeByActionType(ActionType actionType) { + return actionTypeEdgeEventActionTypeEnumMap.get(actionType); + } + public static EdgeEvent constructEdgeEvent(TenantId tenantId, EdgeId edgeId, EdgeEventType type, diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/edge/EdgeEventActionType.java b/common/data/src/main/java/org/thingsboard/server/common/data/edge/EdgeEventActionType.java index e355901182..e39d93946c 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/edge/EdgeEventActionType.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/edge/EdgeEventActionType.java @@ -1,5 +1,5 @@ /** - * Copyright © 2016-2024 The Thingsboard Authors + * Copyright © 2016-2023 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. @@ -15,26 +15,39 @@ */ package org.thingsboard.server.common.data.edge; +import lombok.Getter; +import org.thingsboard.server.common.data.audit.ActionType; + +@Getter public enum EdgeEventActionType { - ADDED, - DELETED, - UPDATED, - POST_ATTRIBUTES, - ATTRIBUTES_UPDATED, - ATTRIBUTES_DELETED, - TIMESERIES_UPDATED, - CREDENTIALS_UPDATED, - ASSIGNED_TO_CUSTOMER, - UNASSIGNED_FROM_CUSTOMER, - RELATION_ADD_OR_UPDATE, - RELATION_DELETED, - RPC_CALL, - ALARM_ACK, - ALARM_CLEAR, - ALARM_ASSIGNED, - ALARM_UNASSIGNED, - ASSIGNED_TO_EDGE, - UNASSIGNED_FROM_EDGE, - CREDENTIALS_REQUEST, - ENTITY_MERGE_REQUEST // deprecated -} \ No newline at end of file + ADDED(ActionType.ADDED), + UPDATED(ActionType.UPDATED), + DELETED(ActionType.DELETED), + POST_ATTRIBUTES(null), + ATTRIBUTES_UPDATED(ActionType.ATTRIBUTES_UPDATED), + ATTRIBUTES_DELETED(ActionType.ATTRIBUTES_DELETED), + TIMESERIES_UPDATED(ActionType.TIMESERIES_UPDATED), + CREDENTIALS_UPDATED(ActionType.CREDENTIALS_UPDATED), + ASSIGNED_TO_CUSTOMER(ActionType.ASSIGNED_TO_CUSTOMER), + UNASSIGNED_FROM_CUSTOMER(ActionType.UNASSIGNED_FROM_CUSTOMER), + RELATION_ADD_OR_UPDATE(ActionType.RELATION_ADD_OR_UPDATE), + RELATION_DELETED(ActionType.RELATION_DELETED), + RPC_CALL(ActionType.RPC_CALL), + ALARM_ACK(ActionType.ALARM_ACK), + ALARM_CLEAR(ActionType.ALARM_CLEAR), + ALARM_ASSIGNED(ActionType.ALARM_ASSIGNED), + ALARM_UNASSIGNED(ActionType.ALARM_UNASSIGNED), + ADDED_COMMENT(ActionType.ADDED_COMMENT), + UPDATED_COMMENT(ActionType.UPDATED_COMMENT), + DELETED_COMMENT(ActionType.DELETED_COMMENT), + ASSIGNED_TO_EDGE(ActionType.ASSIGNED_TO_EDGE), + UNASSIGNED_FROM_EDGE(ActionType.UNASSIGNED_FROM_EDGE), + CREDENTIALS_REQUEST(null), + ENTITY_MERGE_REQUEST(null); // deprecated + + private final ActionType actionType; + + EdgeEventActionType(ActionType actionType) { + this.actionType = actionType; + } +} diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/edge/EdgeEventType.java b/common/data/src/main/java/org/thingsboard/server/common/data/edge/EdgeEventType.java index a8627d3c0d..6fc255501f 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/edge/EdgeEventType.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/edge/EdgeEventType.java @@ -27,6 +27,7 @@ public enum EdgeEventType { ASSET_PROFILE(true, EntityType.ASSET_PROFILE), ENTITY_VIEW(false, EntityType.ENTITY_VIEW), ALARM(false, EntityType.ALARM), + ALARM_COMMENT(false, null), RULE_CHAIN(false, EntityType.RULE_CHAIN), RULE_CHAIN_METADATA(false, null), EDGE(false, EntityType.EDGE), diff --git a/common/edge-api/src/main/proto/edge.proto b/common/edge-api/src/main/proto/edge.proto index 2f33c21fd8..34a8c6f093 100644 --- a/common/edge-api/src/main/proto/edge.proto +++ b/common/edge-api/src/main/proto/edge.proto @@ -325,6 +325,11 @@ message AlarmUpdateMsg { string entity = 18; } +message AlarmCommentUpdateMsg { + UpdateMsgType msgType = 1; + string entity = 2; +} + message CustomerUpdateMsg { UpdateMsgType msgType = 1; int64 idMSB = 2; @@ -618,6 +623,7 @@ message UplinkMsg { repeated AssetProfileUpdateMsg assetProfileUpdateMsg = 19; repeated DeviceProfileUpdateMsg deviceProfileUpdateMsg = 20; repeated ResourceUpdateMsg resourceUpdateMsg = 21; + repeated AlarmCommentUpdateMsg alarmCommentUpdateMsg = 22; } message UplinkResponseMsg { @@ -661,5 +667,6 @@ message DownlinkMsg { repeated TenantUpdateMsg tenantUpdateMsg = 26; repeated TenantProfileUpdateMsg tenantProfileUpdateMsg = 27; repeated ResourceUpdateMsg resourceUpdateMsg = 28; + repeated AlarmCommentUpdateMsg alarmCommentUpdateMsg = 29; } diff --git a/dao/src/main/java/org/thingsboard/server/dao/alarm/BaseAlarmCommentService.java b/dao/src/main/java/org/thingsboard/server/dao/alarm/BaseAlarmCommentService.java index 3bc8ceb1a0..b60acc6550 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/alarm/BaseAlarmCommentService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/alarm/BaseAlarmCommentService.java @@ -31,6 +31,7 @@ import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.dao.entity.AbstractEntityService; +import org.thingsboard.server.dao.eventsourcing.DeleteEntityEvent; import org.thingsboard.server.dao.service.DataValidator; import java.util.UUID; @@ -61,7 +62,10 @@ public class BaseAlarmCommentService extends AbstractEntityService implements Al public AlarmComment saveAlarmComment(TenantId tenantId, AlarmComment alarmComment) { log.debug("Deleting Alarm Comment: {}", alarmComment); alarmCommentDataValidator.validate(alarmComment, c -> tenantId); - return alarmCommentDao.save(tenantId, alarmComment); + AlarmComment result = alarmCommentDao.save(tenantId, alarmComment); + eventPublisher.publishEvent(DeleteEntityEvent.builder().tenantId(tenantId).entity(result) + .entityId(result.getAlarmId()).build()); + return result; } @Override @@ -112,5 +116,4 @@ public class BaseAlarmCommentService extends AbstractEntityService implements Al } return null; } - } diff --git a/dao/src/main/java/org/thingsboard/server/dao/alarm/BaseAlarmService.java b/dao/src/main/java/org/thingsboard/server/dao/alarm/BaseAlarmService.java index ae9763c59c..2a42544bec 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/alarm/BaseAlarmService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/alarm/BaseAlarmService.java @@ -135,7 +135,7 @@ public class BaseAlarmService extends AbstractCachedEntityService metadata = msg.getMetaData().getData(); EdgeEventActionType actionType = getEdgeEventActionTypeByMsgType(msg); @@ -100,7 +100,8 @@ public abstract class AbstractTbMsgPushNode keys = JacksonUtil.convertValue(dataJson.get("attributes"), new TypeReference<>() {}); + List keys = JacksonUtil.convertValue(dataJson.get("attributes"), new TypeReference<>() { + }); entityBody.put("keys", keys); entityBody.put(SCOPE, getScope(metadata)); break; @@ -137,6 +138,8 @@ public abstract class AbstractTbMsgPushNode getConfigClazz(); @@ -149,6 +152,11 @@ public abstract class AbstractTbMsgPushNode metadata) { String scope = metadata.get(SCOPE); if (StringUtils.isEmpty(scope)) { @@ -171,6 +179,10 @@ public abstract class AbstractTbMsgPushNodeSupports next originator types:" + - "
DEVICE" + - "
ASSET" + - "
ENTITY_VIEW" + - "
DASHBOARD" + - "
TENANT" + - "
CUSTOMER" + - "
EDGE

" + - "As well node supports next message types:" + + "Supports next message types:" + "
POST_TELEMETRY_REQUEST" + "
POST_ATTRIBUTES_REQUEST" + "
ATTRIBUTES_UPDATED" + "
ATTRIBUTES_DELETED" + "
ALARM

" + - "Message will be routed via Failure route if node was not able to save edge event to database or unsupported originator type/message type arrived. " + + "Message will be routed via Failure route if node was not able to save edge event to database or unsupported message type arrived. " + "In case successful storage edge event to database message will be routed via Success route.", uiResources = {"static/rulenode/rulenode-core-config.js"}, configDirective = "tbActionNodePushToEdgeConfig", @@ -99,6 +93,11 @@ public class TbMsgPushToEdgeNode extends AbstractTbMsgPushNode pageData; - List> futures = new ArrayList<>(); - do { - pageData = ctx.getEdgeService().findRelatedEdgeIdsByEntityId(ctx.getTenantId(), msg.getOriginator(), pageLink); - if (pageData != null && pageData.getData() != null && !pageData.getData().isEmpty()) { - for (EdgeId edgeId : pageData.getData()) { - EdgeEvent edgeEvent = buildEvent(msg, ctx); - futures.add(notifyEdge(ctx, edgeEvent, edgeId)); - } - if (pageData.hasNext()) { - pageLink = pageLink.nextPageLink(); - } + EntityId originatorId = msg.getOriginator(); + if (DataConstants.COMMENT_CREATED.equals(msg.getType()) || DataConstants.COMMENT_UPDATED.equals(msg.getType())) { + Alarm alarm = JacksonUtil.fromString(msg.getData(), Alarm.class); + if (alarm != null) { + originatorId = alarm.getOriginator(); } - } while (pageData != null && pageData.hasNext()); + } + List> futures = new ArrayList<>(); + EntityId finalOriginatorId = originatorId; + PageDataIterableByTenantIdEntityId edgeIds = new PageDataIterableByTenantIdEntityId<>( + ctx.getEdgeService()::findRelatedEdgeIdsByEntityId, ctx.getTenantId(), finalOriginatorId, DEFAULT_PAGE_SIZE); + for (EdgeId edgeId : edgeIds) { + EdgeEvent edgeEvent = buildEvent(msg, ctx); + futures.add(notifyEdge(ctx, edgeEvent, edgeId)); + } if (futures.isEmpty()) { // ack in case no edges are related to provided entity @@ -176,5 +175,4 @@ public class TbMsgPushToEdgeNode extends AbstractTbMsgPushNode Date: Wed, 10 Jan 2024 12:42:53 +0200 Subject: [PATCH 065/179] added missing WidgetsBundleController APIs to RestClient --- .../thingsboard/rest/client/RestClient.java | 47 ++++++++++++++++--- 1 file changed, 40 insertions(+), 7 deletions(-) diff --git a/rest-client/src/main/java/org/thingsboard/rest/client/RestClient.java b/rest-client/src/main/java/org/thingsboard/rest/client/RestClient.java index 10d3863a2a..0f982c3ff0 100644 --- a/rest-client/src/main/java/org/thingsboard/rest/client/RestClient.java +++ b/rest-client/src/main/java/org/thingsboard/rest/client/RestClient.java @@ -2715,15 +2715,33 @@ public class RestClient implements Closeable { return restTemplate.postForEntity(baseURL + "/api/widgetsBundle", widgetsBundle, WidgetsBundle.class).getBody(); } + public void updateWidgetsBundleWidgetTypes(WidgetsBundleId widgetsBundleId, List widgetTypeIds) { + var httpEntity = new HttpEntity<>(widgetTypeIds.stream() + .map(widgetTypeId -> widgetTypeId.getId().toString()) + .collect(Collectors.toList())); + restTemplate.exchange(baseURL + "/api/widgetsBundle/{widgetsBundleId}/widgetTypes", + HttpMethod.POST, httpEntity, Void.class, widgetsBundleId.getId()); + } + + public void updateWidgetsBundleWidgetFqns(WidgetsBundleId widgetsBundleId, List widgetTypeFqns) { + restTemplate.exchange(baseURL + "/api/widgetsBundle/{widgetsBundleId}/widgetTypeFqns", + HttpMethod.POST, new HttpEntity<>(widgetTypeFqns), Void.class, widgetsBundleId.getId()); + } + public void deleteWidgetsBundle(WidgetsBundleId widgetsBundleId) { restTemplate.delete(baseURL + "/api/widgetsBundle/{widgetsBundleId}", widgetsBundleId.getId()); } public PageData getWidgetsBundles(PageLink pageLink) { + return getWidgetsBundles(pageLink, null, null); + } + + public PageData getWidgetsBundles(PageLink pageLink, Boolean tenantOnly, Boolean fullSearch) { Map params = new HashMap<>(); addPageLinkToParam(params, pageLink); + addTenantOnlyAndFullSearchToParams(tenantOnly, fullSearch, params); return restTemplate.exchange( - baseURL + "/api/widgetsBundles?" + getUrlParams(pageLink), + baseURL + "/api/widgetsBundles?" + getUrlParams(pageLink) + getWidgetsBundlePageRequestUrlParams(tenantOnly, fullSearch), HttpMethod.GET, HttpEntity.EMPTY, new ParameterizedTypeReference>() { @@ -3758,6 +3776,17 @@ public class RestClient implements Closeable { return urlParams; } + private String getWidgetsBundlePageRequestUrlParams(Boolean tenantOnly, Boolean fullSearch) { + String urlParams = ""; + if (tenantOnly != null) { + urlParams = "&tenantOnly={tenantOnly}"; + } + if (fullSearch != null) { + urlParams += "&fullSearch={fullSearch}"; + } + return urlParams; + } + private String getWidgetTypeInfoPageRequestUrlParams(Boolean tenantOnly, Boolean fullSearch, DeprecatedFilter deprecatedFilter, List widgetTypeList) { @@ -3801,12 +3830,7 @@ public class RestClient implements Closeable { private void addWidgetInfoFiltersToParams(Boolean tenantOnly, Boolean fullSearch, DeprecatedFilter deprecatedFilter, List widgetTypeList, Map params) { - if (tenantOnly != null) { - params.put("tenantOnly", tenantOnly.toString()); - } - if (fullSearch != null) { - params.put("fullSearch", fullSearch.toString()); - } + addTenantOnlyAndFullSearchToParams(tenantOnly, fullSearch, params); if (deprecatedFilter != null) { params.put("deprecatedFilter", deprecatedFilter.name()); } @@ -3815,6 +3839,15 @@ public class RestClient implements Closeable { } } + private void addTenantOnlyAndFullSearchToParams(Boolean tenantOnly, Boolean fullSearch, Map params) { + if (tenantOnly != null) { + params.put("tenantOnly", tenantOnly.toString()); + } + if (fullSearch != null) { + params.put("fullSearch", fullSearch.toString()); + } + } + private String listToString(List list) { return String.join(",", list); } From cae0aaf9640baf1218502717eaf8fd7d09880b78 Mon Sep 17 00:00:00 2001 From: Andrii Landiak Date: Wed, 10 Jan 2024 13:04:38 +0200 Subject: [PATCH 066/179] Fix license headers. Add test for alarm comments from edge --- .../processor/alarm/BaseAlarmProcessor.java | 7 + .../entitiy/alarm/TbAlarmCommentService.java | 1 + .../server/edge/AlarmEdgeTest.java | 124 +++++++++--------- .../common/data/edge/EdgeEventActionType.java | 2 +- .../data/page/BasePageDataIterable.java | 5 +- 5 files changed, 73 insertions(+), 66 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/alarm/BaseAlarmProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/alarm/BaseAlarmProcessor.java index 6d04db5b75..e82c2aa2d0 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/alarm/BaseAlarmProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/alarm/BaseAlarmProcessor.java @@ -19,6 +19,7 @@ import com.fasterxml.jackson.databind.JsonNode; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.EntityView; @@ -34,6 +35,7 @@ import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.EntityViewId; import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.dao.alarm.AlarmCommentDao; import org.thingsboard.server.gen.edge.v1.AlarmCommentUpdateMsg; import org.thingsboard.server.gen.edge.v1.AlarmUpdateMsg; import org.thingsboard.server.gen.edge.v1.EdgeVersion; @@ -46,6 +48,9 @@ import java.util.UUID; @Slf4j public abstract class BaseAlarmProcessor extends BaseEdgeProcessor { + @Autowired + protected AlarmCommentDao alarmCommentDao; + public ListenableFuture processAlarmMsg(TenantId tenantId, AlarmUpdateMsg alarmUpdateMsg) { log.trace("[{}] processAlarmMsg [{}]", tenantId, alarmUpdateMsg); AlarmId alarmId = new AlarmId(new UUID(alarmUpdateMsg.getIdMSB(), alarmUpdateMsg.getIdLSB())); @@ -104,6 +109,8 @@ public abstract class BaseAlarmProcessor extends BaseEdgeProcessor { try { switch (alarmCommentUpdateMsg.getMsgType()) { case ENTITY_CREATED_RPC_MESSAGE: + alarmCommentDao.createAlarmComment(tenantId, alarmComment); + break; case ENTITY_UPDATED_RPC_MESSAGE: alarmCommentService.createOrUpdateAlarmComment(tenantId, alarmComment); break; diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/alarm/TbAlarmCommentService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/alarm/TbAlarmCommentService.java index c0274792cb..da7c69050e 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/alarm/TbAlarmCommentService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/alarm/TbAlarmCommentService.java @@ -21,6 +21,7 @@ import org.thingsboard.server.common.data.alarm.AlarmComment; import org.thingsboard.server.common.data.exception.ThingsboardException; public interface TbAlarmCommentService { + AlarmComment saveAlarmComment(Alarm alarm, AlarmComment alarmComment, User user) throws ThingsboardException; void deleteAlarmComment(Alarm alarm, AlarmComment alarmComment, User user) throws ThingsboardException; diff --git a/application/src/test/java/org/thingsboard/server/edge/AlarmEdgeTest.java b/application/src/test/java/org/thingsboard/server/edge/AlarmEdgeTest.java index 5ada0e69d5..6e10507f1e 100644 --- a/application/src/test/java/org/thingsboard/server/edge/AlarmEdgeTest.java +++ b/application/src/test/java/org/thingsboard/server/edge/AlarmEdgeTest.java @@ -15,21 +15,27 @@ */ package org.thingsboard.server.edge; +import com.datastax.oss.driver.api.core.uuid.Uuids; import com.fasterxml.jackson.core.type.TypeReference; -import com.google.protobuf.AbstractMessage; +import com.fasterxml.jackson.databind.node.TextNode; import org.junit.Assert; import org.junit.Test; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.alarm.Alarm; +import org.thingsboard.server.common.data.alarm.AlarmComment; +import org.thingsboard.server.common.data.alarm.AlarmCommentInfo; +import org.thingsboard.server.common.data.alarm.AlarmCommentType; import org.thingsboard.server.common.data.alarm.AlarmInfo; import org.thingsboard.server.common.data.alarm.AlarmSeverity; import org.thingsboard.server.common.data.alarm.AlarmStatus; +import org.thingsboard.server.common.data.id.AlarmCommentId; import org.thingsboard.server.common.data.id.AlarmId; import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.dao.service.DaoSqlTest; +import org.thingsboard.server.gen.edge.v1.AlarmCommentUpdateMsg; import org.thingsboard.server.gen.edge.v1.AlarmUpdateMsg; import org.thingsboard.server.gen.edge.v1.UpdateMsgType; import org.thingsboard.server.gen.edge.v1.UplinkMsg; @@ -38,8 +44,6 @@ import java.util.List; import java.util.Optional; import java.util.UUID; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - @DaoSqlTest public class AlarmEdgeTest extends AbstractEdgeTest { @@ -77,66 +81,48 @@ public class AlarmEdgeTest extends AbstractEdgeTest { } @Test - public void testAlarms() throws Exception { - // create alarm - Device device = findDeviceByName("Edge Device 1"); - Alarm alarm = new Alarm(); - alarm.setOriginator(device.getId()); - alarm.setType("alarm"); - alarm.setSeverity(AlarmSeverity.CRITICAL); - edgeImitator.expectMessageAmount(1); - Alarm savedAlarm = doPost("/api/alarm", alarm, Alarm.class); - Assert.assertTrue(edgeImitator.waitForMessages()); - AbstractMessage latestMessage = edgeImitator.getLatestMessage(); - Assert.assertTrue(latestMessage instanceof AlarmUpdateMsg); - AlarmUpdateMsg alarmUpdateMsg = (AlarmUpdateMsg) latestMessage; - Alarm alarmMsg = JacksonUtil.fromString(alarmUpdateMsg.getEntity(), Alarm.class, true); - Assert.assertNotNull(alarmMsg); - Assert.assertEquals(savedAlarm, alarmMsg); - Assert.assertEquals(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE, alarmUpdateMsg.getMsgType()); - - // ack alarm - edgeImitator.expectMessageAmount(1); - doPost("/api/alarm/" + savedAlarm.getUuidId() + "/ack"); - Assert.assertTrue(edgeImitator.waitForMessages()); - latestMessage = edgeImitator.getLatestMessage(); - Assert.assertTrue(latestMessage instanceof AlarmUpdateMsg); - alarmUpdateMsg = (AlarmUpdateMsg) latestMessage; - Assert.assertEquals(UpdateMsgType.ALARM_ACK_RPC_MESSAGE, alarmUpdateMsg.getMsgType()); - alarmMsg = JacksonUtil.fromString(alarmUpdateMsg.getEntity(), Alarm.class, true); - Assert.assertNotNull(alarmMsg); - Assert.assertEquals(savedAlarm.getType(), alarmMsg.getType()); - Assert.assertEquals(savedAlarm.getName(), alarmMsg.getName()); - Assert.assertEquals(AlarmStatus.ACTIVE_ACK, alarmMsg.getStatus()); - - // clear alarm - edgeImitator.expectMessageAmount(1); - doPost("/api/alarm/" + savedAlarm.getUuidId() + "/clear"); - Assert.assertTrue(edgeImitator.waitForMessages()); - latestMessage = edgeImitator.getLatestMessage(); - Assert.assertTrue(latestMessage instanceof AlarmUpdateMsg); - alarmUpdateMsg = (AlarmUpdateMsg) latestMessage; - Assert.assertEquals(UpdateMsgType.ALARM_CLEAR_RPC_MESSAGE, alarmUpdateMsg.getMsgType()); - alarmMsg = JacksonUtil.fromString(alarmUpdateMsg.getEntity(), Alarm.class, true); - Assert.assertNotNull(alarmMsg); - Assert.assertEquals(savedAlarm.getType(), alarmMsg.getType()); - Assert.assertEquals(savedAlarm.getName(), alarmMsg.getName()); - Assert.assertEquals(AlarmStatus.CLEARED_ACK, alarmMsg.getStatus()); - - // delete alarm - edgeImitator.expectMessageAmount(1); - doDelete("/api/alarm/" + savedAlarm.getUuidId()) - .andExpect(status().isOk()); - Assert.assertTrue(edgeImitator.waitForMessages()); - latestMessage = edgeImitator.getLatestMessage(); - Assert.assertTrue(latestMessage instanceof AlarmUpdateMsg); - alarmUpdateMsg = (AlarmUpdateMsg) latestMessage; - Assert.assertEquals(UpdateMsgType.ENTITY_DELETED_RPC_MESSAGE, alarmUpdateMsg.getMsgType()); - alarmMsg = JacksonUtil.fromString(alarmUpdateMsg.getEntity(), Alarm.class, true); - Assert.assertNotNull(alarmMsg); - Assert.assertEquals(savedAlarm.getType(), alarmMsg.getType()); - Assert.assertEquals(savedAlarm.getName(), alarmMsg.getName()); - Assert.assertEquals(AlarmStatus.CLEARED_ACK, alarmMsg.getStatus()); + public void testSendAlarmCommentToCloud() throws Exception { + Device device = saveDeviceOnCloudAndVerifyDeliveryToEdge(); + + Alarm alarm = buildAlarmForUplinkMsg(device.getId()); + + UplinkMsg.Builder uplinkMsgBuilder = UplinkMsg.newBuilder(); + AlarmUpdateMsg.Builder alarmUpdateMgBuilder = AlarmUpdateMsg.newBuilder(); + alarmUpdateMgBuilder.setIdMSB(alarm.getUuidId().getMostSignificantBits()); + alarmUpdateMgBuilder.setIdLSB(alarm.getUuidId().getLeastSignificantBits()); + alarmUpdateMgBuilder.setEntity(JacksonUtil.toString(alarm)); + testAutoGeneratedCodeByProtobuf(alarmUpdateMgBuilder); + uplinkMsgBuilder.addAlarmUpdateMsg(alarmUpdateMgBuilder.build()); + + testAutoGeneratedCodeByProtobuf(uplinkMsgBuilder); + + edgeImitator.expectResponsesAmount(1); + edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build()); + Assert.assertTrue(edgeImitator.waitForResponses()); + + AlarmComment alarmComment = buildAlarmCommentForUplinkMsg(alarm.getId()); + + uplinkMsgBuilder = UplinkMsg.newBuilder(); + AlarmCommentUpdateMsg.Builder alarmCommentUpdateMgBuilder = AlarmCommentUpdateMsg.newBuilder(); + alarmCommentUpdateMgBuilder.setEntity(JacksonUtil.toString(alarmComment)); + alarmCommentUpdateMgBuilder.setMsgType(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE); + testAutoGeneratedCodeByProtobuf(alarmCommentUpdateMgBuilder); + uplinkMsgBuilder.addAlarmCommentUpdateMsg(alarmCommentUpdateMgBuilder.build()); + + testAutoGeneratedCodeByProtobuf(uplinkMsgBuilder); + + edgeImitator.expectResponsesAmount(1); + edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build()); + Assert.assertTrue(edgeImitator.waitForResponses()); + + PageData pageData = doGetTyped("/api/alarm/" + alarmComment.getAlarmId().getId() + "/comment" + "?page=0&pageSize=1", new TypeReference<>() {}); + Assert.assertNotNull("Found pageData is null", pageData); + Assert.assertNotEquals("Expected alarms are not found!", 0, pageData.getTotalElements()); + + Assert.assertNotNull(pageData.getData().get(0)); + AlarmCommentInfo alarmInfo = pageData.getData().get(0); + Assert.assertEquals(alarm.getId(), alarmInfo.getAlarmId()); + Assert.assertEquals(alarmComment.getAlarmId(), alarmInfo.getAlarmId()); } private Alarm buildAlarmForUplinkMsg(DeviceId deviceId) { @@ -148,4 +134,16 @@ public class AlarmEdgeTest extends AbstractEdgeTest { alarm.setSeverity(AlarmSeverity.CRITICAL); return alarm; } + + private AlarmComment buildAlarmCommentForUplinkMsg(AlarmId alarmId) { + UUID uuid = Uuids.timeBased(); + AlarmComment alarmComment = new AlarmComment(); + alarmComment.setAlarmId(alarmId); + alarmComment.setType(AlarmCommentType.OTHER); + alarmComment.setUserId(tenantAdminUserId); + alarmComment.setId(new AlarmCommentId(uuid)); + alarmComment.setComment(new TextNode("AlarmComment")); + alarmComment.setCreatedTime(Uuids.unixTimestamp(uuid)); + return alarmComment; + } } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/edge/EdgeEventActionType.java b/common/data/src/main/java/org/thingsboard/server/common/data/edge/EdgeEventActionType.java index e39d93946c..680f744c7b 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/edge/EdgeEventActionType.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/edge/EdgeEventActionType.java @@ -1,5 +1,5 @@ /** - * Copyright © 2016-2023 The Thingsboard Authors + * Copyright © 2016-2024 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. diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/page/BasePageDataIterable.java b/common/data/src/main/java/org/thingsboard/server/common/data/page/BasePageDataIterable.java index 19c3fc8f4f..8d46a46781 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/page/BasePageDataIterable.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/page/BasePageDataIterable.java @@ -15,6 +15,7 @@ */ package org.thingsboard.server.common.data.page; +import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.NoSuchElementException; @@ -64,8 +65,8 @@ public abstract class BasePageDataIterable implements Iterable, Iterator pageData = fetchPageData(link); currentIdx = 0; - currentItems = pageData.getData(); - hasNextPack = pageData.hasNext(); + currentItems = pageData != null ? pageData.getData() : new ArrayList<>(); + hasNextPack = pageData != null && pageData.hasNext(); nextPackLink = link.nextPageLink(); } From 4155fcd03fa2d08b2d583cb464ddaa631e5f0e72 Mon Sep 17 00:00:00 2001 From: ShvaykaD Date: Wed, 10 Jan 2024 13:07:19 +0200 Subject: [PATCH 067/179] Minor refactoring of private method after self review --- .../thingsboard/rest/client/RestClient.java | 26 +++++++------------ 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/rest-client/src/main/java/org/thingsboard/rest/client/RestClient.java b/rest-client/src/main/java/org/thingsboard/rest/client/RestClient.java index 0f982c3ff0..4c03bb1847 100644 --- a/rest-client/src/main/java/org/thingsboard/rest/client/RestClient.java +++ b/rest-client/src/main/java/org/thingsboard/rest/client/RestClient.java @@ -2741,7 +2741,7 @@ public class RestClient implements Closeable { addPageLinkToParam(params, pageLink); addTenantOnlyAndFullSearchToParams(tenantOnly, fullSearch, params); return restTemplate.exchange( - baseURL + "/api/widgetsBundles?" + getUrlParams(pageLink) + getWidgetsBundlePageRequestUrlParams(tenantOnly, fullSearch), + baseURL + "/api/widgetsBundles?" + getUrlParams(pageLink) + getTenantOnlyAndFullSearchUrlParams(tenantOnly, fullSearch), HttpMethod.GET, HttpEntity.EMPTY, new ParameterizedTypeReference>() { @@ -3776,20 +3776,20 @@ public class RestClient implements Closeable { return urlParams; } - private String getWidgetsBundlePageRequestUrlParams(Boolean tenantOnly, Boolean fullSearch) { - String urlParams = ""; - if (tenantOnly != null) { - urlParams = "&tenantOnly={tenantOnly}"; + private String getWidgetTypeInfoPageRequestUrlParams(Boolean tenantOnly, Boolean fullSearch, + DeprecatedFilter deprecatedFilter, + List widgetTypeList) { + String urlParams = getTenantOnlyAndFullSearchUrlParams(tenantOnly, fullSearch); + if (deprecatedFilter != null) { + urlParams += "&deprecatedFilter={deprecatedFilter}"; } - if (fullSearch != null) { - urlParams += "&fullSearch={fullSearch}"; + if (!CollectionUtils.isEmpty(widgetTypeList)) { + urlParams += "&widgetTypeList={widgetTypeList}"; } return urlParams; } - private String getWidgetTypeInfoPageRequestUrlParams(Boolean tenantOnly, Boolean fullSearch, - DeprecatedFilter deprecatedFilter, - List widgetTypeList) { + private String getTenantOnlyAndFullSearchUrlParams(Boolean tenantOnly, Boolean fullSearch) { String urlParams = ""; if (tenantOnly != null) { urlParams = "&tenantOnly={tenantOnly}"; @@ -3797,12 +3797,6 @@ public class RestClient implements Closeable { if (fullSearch != null) { urlParams += "&fullSearch={fullSearch}"; } - if (deprecatedFilter != null) { - urlParams += "&deprecatedFilter={deprecatedFilter}"; - } - if (!CollectionUtils.isEmpty(widgetTypeList)) { - urlParams += "&widgetTypeList={widgetTypeList}"; - } return urlParams; } From e84a1f066201b83579bba6732b43126e7585569a Mon Sep 17 00:00:00 2001 From: Andrii Landiak Date: Wed, 10 Jan 2024 15:00:15 +0200 Subject: [PATCH 068/179] Add comment types to convertEntityEventToDownlink --- .../thingsboard/server/service/edge/rpc/EdgeGrpcSession.java | 3 +++ .../service/edge/rpc/processor/alarm/BaseAlarmProcessor.java | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java index 14572bc871..5e6f7a263e 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java @@ -531,6 +531,9 @@ public final class EdgeGrpcSession implements Closeable { case RPC_CALL: case ASSIGNED_TO_CUSTOMER: case UNASSIGNED_FROM_CUSTOMER: + case ADDED_COMMENT: + case UPDATED_COMMENT: + case DELETED_COMMENT: downlinkMsg = convertEntityEventToDownlink(edgeEvent); log.trace("[{}][{}] entity message processed [{}]", this.tenantId, this.sessionId, downlinkMsg); break; diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/alarm/BaseAlarmProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/alarm/BaseAlarmProcessor.java index e82c2aa2d0..11cd2ab56c 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/alarm/BaseAlarmProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/alarm/BaseAlarmProcessor.java @@ -107,6 +107,10 @@ public abstract class BaseAlarmProcessor extends BaseEdgeProcessor { throw new RuntimeException("[{" + tenantId + "}] alarmCommentUpdateMsg {" + alarmCommentUpdateMsg + "} cannot be converted to alarm comment"); } try { + Alarm alarm = alarmService.findAlarmById(tenantId, new AlarmId(alarmComment.getAlarmId().getId())); + if (alarm == null) { + return Futures.immediateFuture(null); + } switch (alarmCommentUpdateMsg.getMsgType()) { case ENTITY_CREATED_RPC_MESSAGE: alarmCommentDao.createAlarmComment(tenantId, alarmComment); From 1478383db6c51436b54013c03ee8fd8452558274 Mon Sep 17 00:00:00 2001 From: Andrii Landiak Date: Thu, 11 Jan 2024 11:27:23 +0200 Subject: [PATCH 069/179] Fix tests. Improve TbMsgPushNode toCloud and toEdge description --- .../server/controller/AlarmControllerTest.java | 6 +++--- .../rule/engine/edge/AbstractTbMsgPushNode.java | 6 +++--- .../rule/engine/edge/TbMsgPushToCloudNode.java | 12 +++--------- .../rule/engine/edge/TbMsgPushToEdgeNode.java | 2 ++ 4 files changed, 11 insertions(+), 15 deletions(-) diff --git a/application/src/test/java/org/thingsboard/server/controller/AlarmControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/AlarmControllerTest.java index f5c1fbdae9..1415e38d7e 100644 --- a/application/src/test/java/org/thingsboard/server/controller/AlarmControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/AlarmControllerTest.java @@ -110,7 +110,7 @@ public class AlarmControllerTest extends AbstractControllerTest { Alarm alarm = createAlarm(TEST_ALARM_TYPE); - testNotifyEntityAllOneTime(alarm, alarm.getId(), alarm.getOriginator(), + testNotifyEntityOneTimeMsgToEdgeServiceNever(alarm, alarm.getId(), alarm.getOriginator(), tenantId, customerId, customerUserId, CUSTOMER_USER_EMAIL, ActionType.ADDED); } @@ -122,7 +122,7 @@ public class AlarmControllerTest extends AbstractControllerTest { Alarm alarm = createAlarm(TEST_ALARM_TYPE); - testNotifyEntityAllOneTime(alarm, alarm.getId(), alarm.getOriginator(), + testNotifyEntityOneTimeMsgToEdgeServiceNever(alarm, alarm.getId(), alarm.getOriginator(), tenantId, customerId, tenantAdminUserId, TENANT_ADMIN_EMAIL, ActionType.ADDED); } @@ -772,7 +772,7 @@ public class AlarmControllerTest extends AbstractControllerTest { alarm = doPost("/api/alarm", alarm, Alarm.class); Assert.assertNotNull("Saved alarm is null!", alarm); - testNotifyEntityNeverMsgToEdgeServiceOneTime(alarm, alarm.getId(), tenantId, ActionType.ADDED); + testNotifyEntityNever(alarm.getId(), alarm); resetTokens(); diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/edge/AbstractTbMsgPushNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/edge/AbstractTbMsgPushNode.java index 2349fbdbb6..6ed8a33c2d 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/edge/AbstractTbMsgPushNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/edge/AbstractTbMsgPushNode.java @@ -27,6 +27,7 @@ import org.thingsboard.rule.engine.api.util.TbNodeUtils; import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.StringUtils; +import org.thingsboard.server.common.data.alarm.Alarm; import org.thingsboard.server.common.data.alarm.AlarmComment; import org.thingsboard.server.common.data.edge.EdgeEventActionType; import org.thingsboard.server.common.data.id.TenantId; @@ -147,9 +148,8 @@ public abstract class AbstractTbMsgPushNodeSupports next originator types:" + - "
DEVICE" + - "
ASSET" + - "
ENTITY_VIEW" + - "
DASHBOARD" + - "
TENANT" + - "
CUSTOMER" + - "
EDGE

" + - "As well node supports next message types:" + + "Supports next message types:" + "
POST_TELEMETRY_REQUEST" + "
POST_ATTRIBUTES_REQUEST" + "
ATTRIBUTES_UPDATED" + "
ATTRIBUTES_DELETED" + "
ALARM

" + + "
COMMENT_CREATED" + + "
COMMENT_UPDATED" + "Message will be routed via Failure route if node was not able to save cloud event to database or unsupported originator type/message type arrived. " + "In case successful storage cloud event to database message will be routed via Success route.", uiResources = {"static/rulenode/rulenode-core-config.js"}, diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/edge/TbMsgPushToEdgeNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/edge/TbMsgPushToEdgeNode.java index d9d634c03d..0c6461d3a7 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/edge/TbMsgPushToEdgeNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/edge/TbMsgPushToEdgeNode.java @@ -60,6 +60,8 @@ import java.util.UUID; "
ATTRIBUTES_UPDATED" + "
ATTRIBUTES_DELETED" + "
ALARM

" + + "
COMMENT_CREATED" + + "
COMMENT_UPDATED" + "Message will be routed via Failure route if node was not able to save edge event to database or unsupported message type arrived. " + "In case successful storage edge event to database message will be routed via Success route.", uiResources = {"static/rulenode/rulenode-core-config.js"}, From 7fc22311898196f5758630a80bbf33b029c47c3c Mon Sep 17 00:00:00 2001 From: Andrii Shvaika Date: Thu, 11 Jan 2024 12:40:50 +0200 Subject: [PATCH 070/179] Interval types back-end implementation --- .../controller/TelemetryController.java | 21 ++++- ...efaultTbEntityDataSubscriptionService.java | 7 +- .../service/ws/telemetry/cmd/v2/GetTsCmd.java | 13 +++ .../controller/TelemetryControllerTest.java | 59 ++++++++++++ .../common/data/kv/AggregationParams.java | 92 +++++++++++++++++++ .../common/data/kv/BaseReadTsKvQuery.java | 26 ++++-- .../server/common/data/kv/IntervalType.java | 2 +- .../server/common/data/kv/ReadTsKvQuery.java | 12 ++- ...stractChunkedAggregationTimeseriesDao.java | 23 ++++- .../timescale/TimescaleTimeseriesDao.java | 24 ++++- .../CassandraBaseTimeseriesDao.java | 18 +++- .../dao/timeseries/TsKvQueryCursor.java | 2 +- .../server/dao/util/TimeUtils.java | 45 +++++++++ .../server/dao/util/TimeUtilsTest.java | 60 ++++++++++++ 14 files changed, 370 insertions(+), 34 deletions(-) create mode 100644 common/data/src/main/java/org/thingsboard/server/common/data/kv/AggregationParams.java create mode 100644 dao/src/main/java/org/thingsboard/server/dao/util/TimeUtils.java create mode 100644 dao/src/test/java/org/thingsboard/server/dao/util/TimeUtilsTest.java diff --git a/application/src/main/java/org/thingsboard/server/controller/TelemetryController.java b/application/src/main/java/org/thingsboard/server/controller/TelemetryController.java index 295b8cad99..288828f046 100644 --- a/application/src/main/java/org/thingsboard/server/controller/TelemetryController.java +++ b/application/src/main/java/org/thingsboard/server/controller/TelemetryController.java @@ -45,6 +45,8 @@ import org.springframework.web.bind.annotation.RestController; import org.springframework.web.context.request.async.DeferredResult; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.common.util.ThingsBoardThreadFactory; +import org.thingsboard.server.common.data.kv.AggregationParams; +import org.thingsboard.server.common.data.kv.IntervalType; import org.thingsboard.server.common.msg.rule.engine.DeviceAttributesEventNotificationMsg; import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.EntityType; @@ -310,8 +312,12 @@ public class TelemetryController extends BaseController { @RequestParam(name = "startTs") Long startTs, @ApiParam(value = "A long value representing the end timestamp of the time range in milliseconds, UTC.") @RequestParam(name = "endTs") Long endTs, + @ApiParam(value = "A string value representing the type fo the interval.", allowableValues = "MILLISECONDS, WEEK, WEEK_ISO, MONTH, QUARTER") + @RequestParam(name = "intervalType", required = false) IntervalType intervalType, @ApiParam(value = "A long value representing the aggregation interval range in milliseconds.") @RequestParam(name = "interval", defaultValue = "0") Long interval, + @ApiParam(value = "A string value representing the timezone that will be used to calculate exact timestamps for 'WEEK', 'WEEK_ISO', 'MONTH' and 'QUARTER' interval types.") + @RequestParam(name = "timeZone", required = false) String timeZone, @ApiParam(value = "An integer value that represents a max number of timeseries data points to fetch." + " This parameter is used only in the case if 'agg' parameter is set to 'NONE'.", defaultValue = "100") @RequestParam(name = "limit", defaultValue = "100") Integer limit, @@ -325,11 +331,16 @@ public class TelemetryController extends BaseController { @RequestParam(name = "useStrictDataTypes", required = false, defaultValue = "false") Boolean useStrictDataTypes) throws ThingsboardException { return accessValidator.validateEntityAndCallback(getCurrentUser(), Operation.READ_TELEMETRY, entityType, entityIdStr, (result, tenantId, entityId) -> { - // If interval is 0, convert this to a NONE aggregation, which is probably what the user really wanted - Aggregation agg = interval == 0L ? Aggregation.valueOf(Aggregation.NONE.name()) : Aggregation.valueOf(aggStr); - List queries = toKeysList(keys).stream().map(key -> new BaseReadTsKvQuery(key, startTs, endTs, interval, limit, agg, orderBy)) - .collect(Collectors.toList()); - + AggregationParams params; + Aggregation agg = Aggregation.valueOf(aggStr); + if (Aggregation.NONE.equals(agg)) { + params = AggregationParams.none(); + } else if (intervalType == null || IntervalType.MILLISECONDS.equals(intervalType)) { + params = interval == 0L ? AggregationParams.none() : AggregationParams.milliseconds(agg, interval); + } else { + params = AggregationParams.calendar(agg, intervalType, timeZone); + } + List queries = toKeysList(keys).stream().map(key -> new BaseReadTsKvQuery(key, startTs, endTs, params, limit, orderBy)).collect(Collectors.toList()); Futures.addCallback(tsService.findAll(tenantId, entityId, queries), getTsKvListCallback(result, useStrictDataTypes), MoreExecutors.directExecutor()); }); } diff --git a/application/src/main/java/org/thingsboard/server/service/subscription/DefaultTbEntityDataSubscriptionService.java b/application/src/main/java/org/thingsboard/server/service/subscription/DefaultTbEntityDataSubscriptionService.java index 5251ee72f6..6e31a24275 100644 --- a/application/src/main/java/org/thingsboard/server/service/subscription/DefaultTbEntityDataSubscriptionService.java +++ b/application/src/main/java/org/thingsboard/server/service/subscription/DefaultTbEntityDataSubscriptionService.java @@ -560,17 +560,14 @@ public class DefaultTbEntityDataSubscriptionService implements TbEntityDataSubsc List keys = cmd.getKeys(); List finalTsKvQueryList; List tsKvQueryList = keys.stream().map(key -> { - var query = new BaseReadTsKvQuery( - key, cmd.getStartTs(), cmd.getEndTs(), cmd.getInterval(), getLimit(cmd.getLimit()), cmd.getAgg() - ); + var query = new BaseReadTsKvQuery(key, cmd.getStartTs(), cmd.getEndTs(), cmd.toAggregationParams(), getLimit(cmd.getLimit())); queriesKeys.put(query.getId(), query.getKey()); return query; }).collect(Collectors.toList()); if (cmd.isFetchLatestPreviousPoint()) { finalTsKvQueryList = new ArrayList<>(tsKvQueryList); finalTsKvQueryList.addAll(keys.stream().map(key -> { - var query = new BaseReadTsKvQuery( - key, cmd.getStartTs() - TimeUnit.DAYS.toMillis(365), cmd.getStartTs(), cmd.getInterval(), 1, cmd.getAgg()); + var query = new BaseReadTsKvQuery(key, cmd.getStartTs() - TimeUnit.DAYS.toMillis(365), cmd.getStartTs(), cmd.toAggregationParams(), 1); queriesKeys.put(query.getId(), query.getKey()); return query; } diff --git a/application/src/main/java/org/thingsboard/server/service/ws/telemetry/cmd/v2/GetTsCmd.java b/application/src/main/java/org/thingsboard/server/service/ws/telemetry/cmd/v2/GetTsCmd.java index 80a749fbe7..ef5d9efb96 100644 --- a/application/src/main/java/org/thingsboard/server/service/ws/telemetry/cmd/v2/GetTsCmd.java +++ b/application/src/main/java/org/thingsboard/server/service/ws/telemetry/cmd/v2/GetTsCmd.java @@ -16,6 +16,7 @@ package org.thingsboard.server.service.ws.telemetry.cmd.v2; import org.thingsboard.server.common.data.kv.Aggregation; +import org.thingsboard.server.common.data.kv.AggregationParams; import org.thingsboard.server.common.data.kv.IntervalType; import java.util.List; @@ -40,4 +41,16 @@ public interface GetTsCmd { boolean isFetchLatestPreviousPoint(); + default AggregationParams toAggregationParams() { + var agg = getAgg(); + var intervalType = getIntervalType(); + if (agg == null || Aggregation.NONE.equals(agg)) { + return AggregationParams.none(); + } else if (intervalType == null || IntervalType.MILLISECONDS.equals(intervalType)) { + return AggregationParams.milliseconds(agg, getInterval()); + } else { + return AggregationParams.calendar(agg, intervalType, getTimeZoneId()); + } + } + } diff --git a/application/src/test/java/org/thingsboard/server/controller/TelemetryControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/TelemetryControllerTest.java index 8061cf0eab..98fbffaee5 100644 --- a/application/src/test/java/org/thingsboard/server/controller/TelemetryControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/TelemetryControllerTest.java @@ -15,12 +15,17 @@ */ package org.thingsboard.server.controller; +import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; import org.junit.Assert; import org.junit.Test; import org.springframework.test.context.TestPropertySource; +import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.SaveDeviceWithCredentialsRequest; +import org.thingsboard.server.common.data.kv.BasicTsKvEntry; +import org.thingsboard.server.common.data.kv.LongDataEntry; +import org.thingsboard.server.common.data.kv.TsKvEntry; import org.thingsboard.server.common.data.query.EntityKey; import org.thingsboard.server.common.data.query.SingleEntityFilter; import org.thingsboard.server.common.data.security.DeviceCredentials; @@ -28,6 +33,7 @@ import org.thingsboard.server.common.data.security.DeviceCredentialsType; import org.thingsboard.server.dao.service.DaoSqlTest; import java.util.List; +import java.util.concurrent.TimeUnit; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import static org.thingsboard.server.common.data.query.EntityKeyType.TIME_SERIES; @@ -51,6 +57,59 @@ public class TelemetryControllerTest extends AbstractControllerTest { doPostAsync("/api/plugins/telemetry/DEVICE/" + device.getId() + "/timeseries/smth", invalidRequestBody, String.class, status().isBadRequest()); } + @Test + public void testTelemetryRequests() throws Exception { + loginTenantAdmin(); + Device device = createDevice(); + + var startTs = 1704899727000L; // Wednesday, January 10 15:15:27 GMT + var endOfWeek1Ts = 1705269600000L; // Monday, January 15, 2024 0:00:00 GMT+02:00 + var endOfWeek2Ts = 1705874400000L; // Monday, January 22, 2024 0:00:00 GMT+02:00 + var endTs = endOfWeek2Ts + TimeUnit.DAYS.toMillis(1) + TimeUnit.HOURS.toMillis(1); // Monday, January 23, 2024 1:00:00 GMT+02:00 + + var firstIntervalTs = startTs + (endOfWeek1Ts - startTs) / 2; + var secondIntervalTs = endOfWeek1Ts + (endOfWeek2Ts - endOfWeek1Ts) / 2; + var thirdIntervalTs = endOfWeek2Ts + (endTs - endOfWeek2Ts) / 2; + + var middleOfTheInterval = startTs + (endTs - startTs) / 2; + + tsService.save(tenantId, device.getId(), new BasicTsKvEntry(1704899728000L, new LongDataEntry("t", 1L))); // Wednesday, January 10 15:15:28 GMT + tsService.save(tenantId, device.getId(), new BasicTsKvEntry(1704899729000L, new LongDataEntry("t", 3L))); // Wednesday, January 10 15:15:29 GMT + tsService.save(tenantId, device.getId(), new BasicTsKvEntry(endOfWeek1Ts + 1000, new LongDataEntry("t", 7L))); // Monday, January 15, 2024 0:00:01 GMT+02:00 + tsService.save(tenantId, device.getId(), new BasicTsKvEntry(endOfWeek2Ts + 1000, new LongDataEntry("t", 11L))); // Monday, January 22, 2024 0:00:01 GMT+02:00 + + ObjectNode result = doGetAsync("/api/plugins/telemetry/DEVICE/" + device.getId() + + "/values/timeseries?keys=t&startTs={startTs}&endTs={endTs}&agg={agg}&intervalType={intervalType}&timeZone={timeZone}", + ObjectNode.class, startTs, endTs, "SUM", "WEEK_ISO", "Europe/Kyiv"); + Assert.assertNotNull(result); + Assert.assertNotNull(result.get("t")); + Assert.assertEquals(3, result.get("t").size()); + + var firstIntervalResult = result.get("t").get(0); + Assert.assertEquals(4L, firstIntervalResult.get("value").asLong()); + Assert.assertEquals(firstIntervalTs, firstIntervalResult.get("ts").asLong()); + + var secondIntervalResult = result.get("t").get(1); + Assert.assertEquals(7L, secondIntervalResult.get("value").asLong()); + Assert.assertEquals(secondIntervalTs, secondIntervalResult.get("ts").asLong()); + + var thirdIntervalResult = result.get("t").get(2); + Assert.assertEquals(11L, thirdIntervalResult.get("value").asLong()); + Assert.assertEquals(thirdIntervalTs, thirdIntervalResult.get("ts").asLong()); + + result = doGetAsync("/api/plugins/telemetry/DEVICE/" + device.getId() + + "/values/timeseries?keys=t&startTs={startTs}&endTs={endTs}&agg={agg}&intervalType={intervalType}&timeZone={timeZone}", + ObjectNode.class, startTs, endTs, "SUM", "MONTH", "Europe/Kyiv"); + + Assert.assertNotNull(result); + Assert.assertNotNull(result.get("t")); + Assert.assertEquals(1, result.get("t").size()); + + var monthResult = result.get("t").get(0); + Assert.assertEquals(22L, monthResult.get("value").asLong()); + Assert.assertEquals(middleOfTheInterval, monthResult.get("ts").asLong()); + } + @Test public void testDeleteAllTelemetryWithLatest() throws Exception { loginTenantAdmin(); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/kv/AggregationParams.java b/common/data/src/main/java/org/thingsboard/server/common/data/kv/AggregationParams.java new file mode 100644 index 0000000000..9d7470b676 --- /dev/null +++ b/common/data/src/main/java/org/thingsboard/server/common/data/kv/AggregationParams.java @@ -0,0 +1,92 @@ +/** + * Copyright © 2016-2024 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.server.common.data.kv; + +import lombok.AllArgsConstructor; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; +import org.jetbrains.annotations.NotNull; +import org.thingsboard.server.common.data.StringUtils; + +import java.time.DateTimeException; +import java.time.ZoneId; +import java.time.zone.ZoneRulesException; +import java.util.concurrent.TimeUnit; + +@AllArgsConstructor +@EqualsAndHashCode +@Slf4j +public class AggregationParams { + @Getter + private final Aggregation aggregation; + @Getter + private final IntervalType intervalType; + @Getter + private final ZoneId tzId; + + private final long interval; + + public static AggregationParams none() { + return new AggregationParams(Aggregation.NONE, null, null, 0L); + } + + public static AggregationParams milliseconds(Aggregation aggregationType, long aggregationIntervalMs) { + return new AggregationParams(aggregationType, IntervalType.MILLISECONDS, null, aggregationIntervalMs); + } + + public static AggregationParams calendar(Aggregation aggregationType, IntervalType intervalType, String tzIdStr) { + return calendar(aggregationType, intervalType, getZoneId(tzIdStr)); + } + + public static AggregationParams calendar(Aggregation aggregationType, IntervalType intervalType, ZoneId tzId) { + return new AggregationParams(aggregationType, intervalType, tzId, 0L); + } + + public static AggregationParams of(Aggregation aggregation, IntervalType intervalType, ZoneId tzId, long interval) { + return new AggregationParams(aggregation, intervalType, tzId, interval); + } + + public long getInterval() { + if (intervalType == null) { + return 0L; + } else { + switch (intervalType) { + case WEEK: + case WEEK_ISO: + return TimeUnit.DAYS.toMillis(7); + case MONTH: + return TimeUnit.DAYS.toMillis(30); + case QUARTER: + return TimeUnit.DAYS.toMillis(90); + default: + return interval; + } + } + } + + private static ZoneId getZoneId(String tzIdStr) { + if (StringUtils.isEmpty(tzIdStr)) { + return ZoneId.systemDefault(); + } + try { + return ZoneId.of(tzIdStr); + } catch (DateTimeException e) { + log.warn("[{}] Failed to convert the time zone. Fallback to default.", tzIdStr); + return ZoneId.systemDefault(); + } + } +} diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/kv/BaseReadTsKvQuery.java b/common/data/src/main/java/org/thingsboard/server/common/data/kv/BaseReadTsKvQuery.java index 54b3a15bd2..09d52e46a1 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/kv/BaseReadTsKvQuery.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/kv/BaseReadTsKvQuery.java @@ -18,41 +18,47 @@ package org.thingsboard.server.common.data.kv; import lombok.Data; import lombok.EqualsAndHashCode; +import java.time.ZoneId; + @Data @EqualsAndHashCode(callSuper = true) public class BaseReadTsKvQuery extends BaseTsKvQuery implements ReadTsKvQuery { - private final long interval; + private final AggregationParams aggParameters; private final int limit; - private final Aggregation aggregation; private final String order; public BaseReadTsKvQuery(String key, long startTs, long endTs, long interval, int limit, Aggregation aggregation) { this(key, startTs, endTs, interval, limit, aggregation, "DESC"); } - public BaseReadTsKvQuery(String key, long startTs, long endTs, long interval, int limit, Aggregation aggregation, String order) { + public BaseReadTsKvQuery(String key, long startTs, long endTs, long interval, int limit, Aggregation aggregation, String descOrder) { + this(key, startTs, endTs, AggregationParams.of(aggregation, IntervalType.MILLISECONDS, ZoneId.systemDefault(), interval), limit, descOrder); + } + + public BaseReadTsKvQuery(String key, long startTs, long endTs, AggregationParams parameters, int limit) { + this(key, startTs, endTs, parameters, limit, "DESC"); + } + + public BaseReadTsKvQuery(String key, long startTs, long endTs, AggregationParams parameters, int limit, String order) { super(key, startTs, endTs); - this.interval = interval; + this.aggParameters = parameters; this.limit = limit; - this.aggregation = aggregation; this.order = order; } public BaseReadTsKvQuery(String key, long startTs, long endTs) { - this(key, startTs, endTs, endTs - startTs, 1, Aggregation.AVG, "DESC"); + this(key, startTs, endTs, AggregationParams.milliseconds(Aggregation.AVG, endTs - startTs), 1, "DESC"); } public BaseReadTsKvQuery(String key, long startTs, long endTs, int limit, String order) { - this(key, startTs, endTs, endTs - startTs, limit, Aggregation.NONE, order); + this(key, startTs, endTs, AggregationParams.none(), limit, order); } public BaseReadTsKvQuery(ReadTsKvQuery query, long startTs, long endTs) { super(query.getId(), query.getKey(), startTs, endTs); - this.interval = query.getInterval(); + this.aggParameters = query.getAggParameters(); this.limit = query.getLimit(); - this.aggregation = query.getAggregation(); this.order = query.getOrder(); } - } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/kv/IntervalType.java b/common/data/src/main/java/org/thingsboard/server/common/data/kv/IntervalType.java index e5ebb7f1a1..121b5993e0 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/kv/IntervalType.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/kv/IntervalType.java @@ -17,6 +17,6 @@ package org.thingsboard.server.common.data.kv; public enum IntervalType { - MILLISECONDS, WEEK, WEEK_ISO, MONTH, QUARTER + MILLISECONDS, WEEK/*Sunday-Saturday*/, WEEK_ISO/*Monday-Sunday*/, MONTH, QUARTER } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/kv/ReadTsKvQuery.java b/common/data/src/main/java/org/thingsboard/server/common/data/kv/ReadTsKvQuery.java index e979ec665a..776179967f 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/kv/ReadTsKvQuery.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/kv/ReadTsKvQuery.java @@ -17,11 +17,17 @@ package org.thingsboard.server.common.data.kv; public interface ReadTsKvQuery extends TsKvQuery { - long getInterval(); + AggregationParams getAggParameters(); - int getLimit(); + default long getInterval(){ + return getAggParameters().getInterval(); + } + + default Aggregation getAggregation() { + return getAggParameters().getAggregation(); + } - Aggregation getAggregation(); + int getLimit(); String getOrder(); diff --git a/dao/src/main/java/org/thingsboard/server/dao/sqlts/AbstractChunkedAggregationTimeseriesDao.java b/dao/src/main/java/org/thingsboard/server/dao/sqlts/AbstractChunkedAggregationTimeseriesDao.java index 96e87e954e..6c22935b61 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sqlts/AbstractChunkedAggregationTimeseriesDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sqlts/AbstractChunkedAggregationTimeseriesDao.java @@ -25,6 +25,7 @@ import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.kv.Aggregation; import org.thingsboard.server.common.data.kv.DeleteTsKvQuery; +import org.thingsboard.server.common.data.kv.IntervalType; import org.thingsboard.server.common.data.kv.ReadTsKvQuery; import org.thingsboard.server.common.data.kv.ReadTsKvQueryResult; import org.thingsboard.server.common.data.kv.TsKvEntry; @@ -37,9 +38,18 @@ import org.thingsboard.server.dao.sql.TbSqlBlockingQueueWrapper; import org.thingsboard.server.dao.sqlts.insert.InsertTsRepository; import org.thingsboard.server.dao.sqlts.ts.TsKvRepository; import org.thingsboard.server.dao.timeseries.TimeseriesDao; +import org.thingsboard.server.dao.util.TimeUtils; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.time.temporal.ChronoUnit; +import java.time.temporal.IsoFields; +import java.time.temporal.TemporalUnit; +import java.time.temporal.WeekFields; import java.util.ArrayList; import java.util.Comparator; import java.util.List; @@ -112,16 +122,23 @@ public abstract class AbstractChunkedAggregationTimeseriesDao extends AbstractSq @Override public ListenableFuture findAllAsync(TenantId tenantId, EntityId entityId, ReadTsKvQuery query) { - if (query.getAggregation() == Aggregation.NONE) { + var aggParams = query.getAggParameters(); + if (Aggregation.NONE.equals(aggParams.getAggregation())) { return Futures.immediateFuture(findAllAsyncWithLimit(entityId, query)); } else { List>> futures = new ArrayList<>(); + var intervalType = aggParams.getIntervalType(); long startPeriod = query.getStartTs(); long endPeriod = Math.max(query.getStartTs() + 1, query.getEndTs()); - long step = query.getInterval(); while (startPeriod < endPeriod) { long startTs = startPeriod; - long endTs = Math.min(startPeriod + step, endPeriod); + long endTs; + if (IntervalType.MILLISECONDS.equals(intervalType)) { + endTs = startPeriod + aggParams.getInterval(); + } else { + endTs = TimeUtils.calculateIntervalEnd(startTs, intervalType, aggParams.getTzId()); + } + endTs = Math.min(endTs, endPeriod); long ts = startTs + (endTs - startTs) / 2; ListenableFuture> aggregateTsKvEntry = findAndAggregateAsync(entityId, query.getKey(), startTs, endTs, ts, query.getAggregation()); futures.add(aggregateTsKvEntry); diff --git a/dao/src/main/java/org/thingsboard/server/dao/sqlts/timescale/TimescaleTimeseriesDao.java b/dao/src/main/java/org/thingsboard/server/dao/sqlts/timescale/TimescaleTimeseriesDao.java index 6f1d569730..bb0ce06026 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sqlts/timescale/TimescaleTimeseriesDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sqlts/timescale/TimescaleTimeseriesDao.java @@ -19,6 +19,7 @@ import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.MoreExecutors; import lombok.extern.slf4j.Slf4j; +import org.jetbrains.annotations.NotNull; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Sort; @@ -28,6 +29,7 @@ import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.kv.Aggregation; import org.thingsboard.server.common.data.kv.DeleteTsKvQuery; +import org.thingsboard.server.common.data.kv.IntervalType; import org.thingsboard.server.common.data.kv.ReadTsKvQuery; import org.thingsboard.server.common.data.kv.ReadTsKvQueryResult; import org.thingsboard.server.common.data.kv.TsKvEntry; @@ -35,11 +37,13 @@ import org.thingsboard.server.common.stats.StatsFactory; import org.thingsboard.server.dao.DaoUtil; import org.thingsboard.server.dao.model.sql.AbstractTsKvEntity; import org.thingsboard.server.dao.model.sqlts.timescale.ts.TimescaleTsKvEntity; +import org.thingsboard.server.dao.model.sqlts.ts.TsKvEntity; import org.thingsboard.server.dao.sql.TbSqlBlockingQueueParams; import org.thingsboard.server.dao.sql.TbSqlBlockingQueueWrapper; import org.thingsboard.server.dao.sqlts.AbstractSqlTimeseriesDao; import org.thingsboard.server.dao.sqlts.insert.InsertTsRepository; import org.thingsboard.server.dao.timeseries.TimeseriesDao; +import org.thingsboard.server.dao.util.TimeUtils; import org.thingsboard.server.dao.util.TimescaleDBTsDao; import javax.annotation.PostConstruct; @@ -143,14 +147,28 @@ public class TimescaleTimeseriesDao extends AbstractSqlTimeseriesDao implements @Override public ListenableFuture findAllAsync(TenantId tenantId, EntityId entityId, ReadTsKvQuery query) { + var aggParams = query.getAggParameters(); + var intervalType = aggParams.getIntervalType(); if (query.getAggregation() == Aggregation.NONE) { return Futures.immediateFuture(findAllAsyncWithLimit(entityId, query)); - } else { + } else if (IntervalType.MILLISECONDS.equals(intervalType)) { long startTs = query.getStartTs(); long endTs = Math.max(query.getStartTs() + 1, query.getEndTs()); long timeBucket = query.getInterval(); List> data = findAllAndAggregateAsync(entityId, query.getKey(), startTs, endTs, timeBucket, query.getAggregation()); return getReadTsKvQueryResultFuture(query, Futures.immediateFuture(data)); + } else { + //TODO: @dshvaika improve according to native capabilities of Timescale. + long startPeriod = query.getStartTs(); + long endPeriod = Math.max(query.getStartTs() + 1, query.getEndTs()); + List timescaleTsKvEntities = new ArrayList<>(); + while (startPeriod < endPeriod) { + long startTs = startPeriod; + long endTs = Math.min(TimeUtils.calculateIntervalEnd(startTs, intervalType, aggParams.getTzId()), endPeriod); + timescaleTsKvEntities.addAll(switchAggregation(query.getKey(), startTs, endTs, endTs - startTs, query.getAggregation(), entityId.getId())); + startPeriod = endTs; + } + return getReadTsKvQueryResultFuture(query, Futures.immediateFuture(toResultList(entityId, query.getKey(), timescaleTsKvEntities))); } } @@ -187,6 +205,10 @@ public class TimescaleTimeseriesDao extends AbstractSqlTimeseriesDao implements timescaleTsKvEntities.addAll(switchAggregation(key, startTs + interval, endTs, remainingPart, aggregation, entityId.getId())); } + return toResultList(entityId, key, timescaleTsKvEntities); + } + + private static List> toResultList(EntityId entityId, String key, List timescaleTsKvEntities) { if (!CollectionUtils.isEmpty(timescaleTsKvEntities)) { List> result = new ArrayList<>(); timescaleTsKvEntities.forEach(entity -> { diff --git a/dao/src/main/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDao.java b/dao/src/main/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDao.java index 71541962ec..31e29434e8 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDao.java @@ -41,6 +41,7 @@ import org.thingsboard.server.common.data.kv.Aggregation; import org.thingsboard.server.common.data.kv.BaseReadTsKvQuery; import org.thingsboard.server.common.data.kv.DataType; import org.thingsboard.server.common.data.kv.DeleteTsKvQuery; +import org.thingsboard.server.common.data.kv.IntervalType; import org.thingsboard.server.common.data.kv.KvEntry; import org.thingsboard.server.common.data.kv.ReadTsKvQuery; import org.thingsboard.server.common.data.kv.ReadTsKvQueryResult; @@ -51,6 +52,7 @@ import org.thingsboard.server.dao.nosql.TbResultSet; import org.thingsboard.server.dao.nosql.TbResultSetFuture; import org.thingsboard.server.dao.sqlts.AggregationTimeseriesDao; import org.thingsboard.server.dao.util.NoSqlTsDao; +import org.thingsboard.server.dao.util.TimeUtils; import javax.annotation.Nullable; import javax.annotation.PostConstruct; @@ -227,18 +229,24 @@ public class CassandraBaseTimeseriesDao extends AbstractCassandraBaseTimeseriesD @Override public ListenableFuture findAllAsync(TenantId tenantId, EntityId entityId, ReadTsKvQuery query) { - if (query.getAggregation() == Aggregation.NONE) { + var aggParams = query.getAggParameters(); + if (Aggregation.NONE.equals(aggParams.getAggregation())) { return findAllAsyncWithLimit(tenantId, entityId, query); } else { long startPeriod = query.getStartTs(); long endPeriod = Math.max(query.getStartTs() + 1, query.getEndTs()); - long step = Math.max(query.getInterval(), MIN_AGGREGATION_STEP_MS); List>> futures = new ArrayList<>(); + var intervalType = aggParams.getIntervalType(); while (startPeriod < endPeriod) { long startTs = startPeriod; - long endTs = Math.min(startPeriod + step, endPeriod); - long ts = endTs - startTs; - ReadTsKvQuery subQuery = new BaseReadTsKvQuery(query.getKey(), startTs, endTs, ts, 1, query.getAggregation(), query.getOrder()); + long endTs; + if (IntervalType.MILLISECONDS.equals(intervalType)) { + endTs = startPeriod + Math.max(query.getInterval(), MIN_AGGREGATION_STEP_MS); + } else { + endTs = TimeUtils.calculateIntervalEnd(startTs, aggParams.getIntervalType(), aggParams.getTzId()); + } + endTs = Math.min(endTs, endPeriod); + ReadTsKvQuery subQuery = new BaseReadTsKvQuery(query.getKey(), startTs, endTs, endTs - startTs, 1, query.getAggregation(), query.getOrder()); futures.add(findAndAggregateAsync(tenantId, entityId, subQuery, toPartitionTs(startTs), toPartitionTs(endTs))); startPeriod = endTs; } diff --git a/dao/src/main/java/org/thingsboard/server/dao/timeseries/TsKvQueryCursor.java b/dao/src/main/java/org/thingsboard/server/dao/timeseries/TsKvQueryCursor.java index 9c302be53d..8ab9a2c4da 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/timeseries/TsKvQueryCursor.java +++ b/dao/src/main/java/org/thingsboard/server/dao/timeseries/TsKvQueryCursor.java @@ -33,7 +33,7 @@ public class TsKvQueryCursor extends QueryCursor { @Getter private final List data; @Getter - private String orderBy; + private final String orderBy; private int partitionIndex; private int currentLimit; diff --git a/dao/src/main/java/org/thingsboard/server/dao/util/TimeUtils.java b/dao/src/main/java/org/thingsboard/server/dao/util/TimeUtils.java new file mode 100644 index 0000000000..3a768673b8 --- /dev/null +++ b/dao/src/main/java/org/thingsboard/server/dao/util/TimeUtils.java @@ -0,0 +1,45 @@ +/** + * Copyright © 2016-2024 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.server.dao.util; + +import org.thingsboard.server.common.data.kv.IntervalType; + +import java.time.Instant; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.time.temporal.ChronoUnit; +import java.time.temporal.IsoFields; +import java.time.temporal.WeekFields; + +public class TimeUtils { + + public static long calculateIntervalEnd(long startTs, IntervalType intervalType, ZoneId tzId) { + var startTime = ZonedDateTime.ofInstant(Instant.ofEpochMilli(startTs), tzId); + switch (intervalType) { + case WEEK: + return startTime.truncatedTo(ChronoUnit.DAYS).with(WeekFields.SUNDAY_START.dayOfWeek(), 1).plusDays(7).toInstant().toEpochMilli(); + case WEEK_ISO: + return startTime.truncatedTo(ChronoUnit.DAYS).with(WeekFields.ISO.dayOfWeek(), 1).plusDays(7).toInstant().toEpochMilli(); + case MONTH: + return startTime.truncatedTo(ChronoUnit.DAYS).withDayOfMonth(1).plusMonths(1).toInstant().toEpochMilli(); + case QUARTER: + return startTime.truncatedTo(ChronoUnit.DAYS).with(IsoFields.DAY_OF_QUARTER, 1).plusMonths(3).toInstant().toEpochMilli(); + default: + throw new RuntimeException("Not supported!"); + } + } + +} diff --git a/dao/src/test/java/org/thingsboard/server/dao/util/TimeUtilsTest.java b/dao/src/test/java/org/thingsboard/server/dao/util/TimeUtilsTest.java new file mode 100644 index 0000000000..a3df974236 --- /dev/null +++ b/dao/src/test/java/org/thingsboard/server/dao/util/TimeUtilsTest.java @@ -0,0 +1,60 @@ +/** + * Copyright © 2016-2024 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.server.dao.util; + +import org.junit.jupiter.api.Test; +import org.thingsboard.server.common.data.kv.IntervalType; + +import java.time.ZoneId; + +import static org.assertj.core.api.Assertions.assertThat; + +class TimeUtilsTest { + + @Test + void testWeekEnd() { + long ts = 1704899727000L; // Wednesday, January 10 15:15:27 GMT + assertThat(TimeUtils.calculateIntervalEnd(ts, IntervalType.WEEK, ZoneId.of("Europe/Kyiv"))).isEqualTo(1705183200000L); // Sunday, January 14, 2024 0:00:00 GMT+02:00 + assertThat(TimeUtils.calculateIntervalEnd(ts, IntervalType.WEEK_ISO, ZoneId.of("Europe/Kyiv"))).isEqualTo(1705269600000L); // Monday, January 15, 2024 0:00:00 GMT+02:00 + + assertThat(TimeUtils.calculateIntervalEnd(ts, IntervalType.WEEK, ZoneId.of("Europe/Amsterdam"))).isEqualTo(1705186800000L); // Sunday, January 14, 2024 0:00:00 GMT+01:00 + assertThat(TimeUtils.calculateIntervalEnd(ts, IntervalType.WEEK_ISO, ZoneId.of("Europe/Amsterdam"))).isEqualTo(1705273200000L); // Monday, January 15, 2024 0:00:00 GMT+01:00 + + ts = 1704621600000L; // Sunday, January 7, 2024 12:00:00 GMT+02:00 + assertThat(TimeUtils.calculateIntervalEnd(ts, IntervalType.WEEK, ZoneId.of("Europe/Kyiv"))).isEqualTo(1705183200000L); // Sunday, January 14, 2024 0:00:00 GMT+02:00 + assertThat(TimeUtils.calculateIntervalEnd(ts, IntervalType.WEEK_ISO, ZoneId.of("Europe/Kyiv"))).isEqualTo(1704664800000L); // Monday, January 8, 2024 0:00:00 GMT+02:00 + } + + + @Test + void testMonthEnd() { + long ts = 1704899727000L; // Wednesday, January 10 15:15:27 GMT + assertThat(TimeUtils.calculateIntervalEnd(ts, IntervalType.MONTH, ZoneId.of("Europe/Kyiv"))).isEqualTo(1706738400000L); // Thursday, February 1, 2024 0:00:00 GMT+02:00 + assertThat(TimeUtils.calculateIntervalEnd(ts, IntervalType.MONTH, ZoneId.of("Europe/Amsterdam"))).isEqualTo(1706742000000L); // Monday, January 15, 2024 0:00:00 GMT+02:00 + } + + @Test + void testQuarterEnd() { + long ts = 1704899727000L; // Wednesday, January 10 15:15:27 GMT + assertThat(TimeUtils.calculateIntervalEnd(ts, IntervalType.QUARTER, ZoneId.of("Europe/Kyiv"))).isEqualTo(1711918800000L); // Monday, April 1, 2024 0:00:00 GMT+03:00 DST + assertThat(TimeUtils.calculateIntervalEnd(ts, IntervalType.QUARTER, ZoneId.of("Europe/Amsterdam"))).isEqualTo(1711922400000L); // Monday, April 1, 2024 1:00:00 GMT+03:00 DST + + ts = 1711929600000L; // Monday, April 1, 2024 3:00:00 GMT+03:00 + assertThat(TimeUtils.calculateIntervalEnd(ts, IntervalType.QUARTER, ZoneId.of("Europe/Kyiv"))).isEqualTo(1719781200000L); // Monday, July 1, 2024 0:00:00 GMT+03:00 DST + assertThat(TimeUtils.calculateIntervalEnd(ts, IntervalType.QUARTER, ZoneId.of("America/New_York"))).isEqualTo(1711944000000L); // Monday, April 1, 2024 7:00:00 GMT+03:00 DST + } + +} From baf8845de9fc2873c45e8167374d40f890f67310 Mon Sep 17 00:00:00 2001 From: rusikv Date: Thu, 11 Jan 2024 12:49:17 +0200 Subject: [PATCH 071/179] UI: rule chain search license fix --- .../rule-chain/rule-chain-select-panel.component.html | 2 +- .../rule-chain/rule-chain-select-panel.component.scss | 2 +- .../components/rule-chain/rule-chain-select-panel.component.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ui-ngx/src/app/shared/components/rule-chain/rule-chain-select-panel.component.html b/ui-ngx/src/app/shared/components/rule-chain/rule-chain-select-panel.component.html index 7a9f56255f..799abc1ee3 100644 --- a/ui-ngx/src/app/shared/components/rule-chain/rule-chain-select-panel.component.html +++ b/ui-ngx/src/app/shared/components/rule-chain/rule-chain-select-panel.component.html @@ -1,6 +1,6 @@ -
+

{{ (isTelemetry ? 'attribute.add-telemetry' : 'attribute.add') | translate }}

diff --git a/ui-ngx/src/app/modules/home/components/attribute/add-widget-to-dashboard-dialog.component.ts b/ui-ngx/src/app/modules/home/components/attribute/add-widget-to-dashboard-dialog.component.ts index 0ac4f79c55..9935ea5bbf 100644 --- a/ui-ngx/src/app/modules/home/components/attribute/add-widget-to-dashboard-dialog.component.ts +++ b/ui-ngx/src/app/modules/home/components/attribute/add-widget-to-dashboard-dialog.component.ts @@ -126,9 +126,8 @@ export class AddWidgetToDashboardDialogComponent extends mergeMap((dashboard) => { dashboard = this.dashboardUtils.validateAndUpdateDashboard(dashboard); return this.selectTargetState(dashboard).pipe( - mergeMap((targetState) => { - return forkJoin([of(dashboard), of(targetState), this.selectTargetLayout(dashboard, targetState)]); - }) + mergeMap((targetState) => + forkJoin([of(dashboard), of(targetState), this.selectTargetLayout(dashboard, targetState)])) ); }) ).subscribe((res) => { @@ -177,7 +176,7 @@ export class AddWidgetToDashboardDialogComponent extends private addWidgetToDashboard(dashboard: Dashboard, targetState: string, targetLayout: DashboardLayoutId) { const aliasesInfo: AliasesInfo = { datasourceAliases: {}, - targetDeviceAliases: {} + targetDeviceAlias: null }; aliasesInfo.datasourceAliases[0] = { alias: this.data.entityName, diff --git a/ui-ngx/src/app/modules/home/components/attribute/edit-attribute-value-panel.component.html b/ui-ngx/src/app/modules/home/components/attribute/edit-attribute-value-panel.component.html index 6725b36960..7c682e6c0c 100644 --- a/ui-ngx/src/app/modules/home/components/attribute/edit-attribute-value-panel.component.html +++ b/ui-ngx/src/app/modules/home/components/attribute/edit-attribute-value-panel.component.html @@ -16,7 +16,7 @@ --> + [formGroup]="attributeFormGroup" (ngSubmit)="update()" style="padding: 5px; width: 375px;">
diff --git a/ui-ngx/src/app/modules/home/components/filter/filters-dialog.component.ts b/ui-ngx/src/app/modules/home/components/filter/filters-dialog.component.ts index 762e56f5d6..c4bbdca1db 100644 --- a/ui-ngx/src/app/modules/home/components/filter/filters-dialog.component.ts +++ b/ui-ngx/src/app/modules/home/components/filter/filters-dialog.component.ts @@ -39,6 +39,7 @@ import { DialogService } from '@core/services/dialog.service'; import { deepClone, isUndefined } from '@core/utils'; import { Filter, Filters, KeyFilterInfo } from '@shared/models/query/query.models'; import { FilterDialogComponent, FilterDialogData } from '@home/components/filter/filter-dialog.component'; +import { DashboardUtilsService } from '@core/services/dashboard-utils.service'; export interface FiltersDialogData { filters: Filters; @@ -77,6 +78,7 @@ export class FiltersDialogComponent extends DialogComponent, private fb: UntypedFormBuilder, private utils: UtilsService, + private dashboardUtils: DashboardUtilsService, private translate: TranslateService, private dialogs: DialogService, private dialog: MatDialog) { @@ -94,7 +96,7 @@ export class FiltersDialogComponent extends DialogComponent { - const datasources = this.utils.validateDatasources(widget.config.datasources); + const datasources = this.dashboardUtils.validateAndUpdateDatasources(widget.config.datasources); datasources.forEach((datasource) => { if (datasource.type === DatasourceType.entity && datasource.filterId) { widgetsTitleList = this.filterToWidgetsMap[datasource.filterId]; diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/basic-widget-config.module.ts b/ui-ngx/src/app/modules/home/components/widget/config/basic/basic-widget-config.module.ts index 5d7439feae..9f8586b12e 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/basic/basic-widget-config.module.ts +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/basic-widget-config.module.ts @@ -91,6 +91,9 @@ import { import { BarChartWithLabelsBasicConfigComponent } from '@home/components/widget/config/basic/chart/bar-chart-with-labels-basic-config.component'; +import { + SingSwitchBasicConfigComponent +} from '@home/components/widget/config/basic/rpc/single-switch-basic-config.component'; @NgModule({ declarations: [ @@ -119,7 +122,8 @@ import { LiquidLevelCardBasicConfigComponent, DoughnutBasicConfigComponent, RangeChartBasicConfigComponent, - BarChartWithLabelsBasicConfigComponent + BarChartWithLabelsBasicConfigComponent, + SingSwitchBasicConfigComponent ], imports: [ CommonModule, @@ -152,7 +156,8 @@ import { LiquidLevelCardBasicConfigComponent, DoughnutBasicConfigComponent, RangeChartBasicConfigComponent, - BarChartWithLabelsBasicConfigComponent + BarChartWithLabelsBasicConfigComponent, + SingSwitchBasicConfigComponent ] }) export class BasicWidgetConfigModule { @@ -179,5 +184,6 @@ export const basicWidgetConfigComponentsMap: {[key: string]: Type + + +
+
widgets.single-switch.behavior
+
+
widgets.rpc-state.initial-state
+ +
+
+
widgets.rpc-state.turn-on
+ +
+
+
widgets.rpc-state.turn-off
+ +
+
+
+
widget-config.appearance
+ + + {{ singleSwitchLayoutTranslationMap.get(layout) | translate }} + + +
+ + {{ 'widgets.single-switch.auto-scale' | translate }} + +
+
+ + {{ 'widgets.single-switch.label' | translate }} + +
+ + + + + + + +
+
+
+ + {{ 'widgets.single-switch.icon' | translate }} + +
+ + + + + + + + +
+
+
+
{{ 'widgets.single-switch.switch-color' | translate }}
+
+
+
widgets.single-switch.on
+ + +
+ +
+
widgets.single-switch.off
+ + +
+ +
+
widgets.single-switch.disabled
+ + +
+
+
+
+
{{ 'widgets.single-switch.tumbler-color' | translate }}
+
+
+
widgets.single-switch.on
+ + +
+ +
+
widgets.single-switch.off
+ + +
+ +
+
widgets.single-switch.disabled
+ + +
+
+
+
+ + {{ 'widgets.single-switch.on-label' | translate }} + +
+ + + + + + + +
+
+
+ + {{ 'widgets.single-switch.off-label' | translate }} + +
+ + + + + + + +
+
+
+
+
widget-config.card-appearance
+
+
{{ 'widgets.background.background' | translate }}
+ + +
+
+
widget-config.show-card-buttons
+ + {{ 'fullscreen.fullscreen' | translate }} + +
+
+
{{ 'widget-config.card-border-radius' | translate }}
+ + + +
+
+ + +
diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/rpc/single-switch-basic-config.component.ts b/ui-ngx/src/app/modules/home/components/widget/config/basic/rpc/single-switch-basic-config.component.ts new file mode 100644 index 0000000000..ed95847654 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/rpc/single-switch-basic-config.component.ts @@ -0,0 +1,231 @@ +/// +/// Copyright © 2016-2024 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 { Component } from '@angular/core'; +import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms'; +import { Store } from '@ngrx/store'; +import { AppState } from '@core/core.state'; +import { BasicWidgetConfigComponent } from '@home/components/widget/config/widget-config.component.models'; +import { WidgetConfigComponentData } from '@home/models/widget-component.models'; +import { TargetDevice, WidgetConfig, } from '@shared/models/widget.models'; +import { WidgetConfigComponent } from '@home/components/widget/widget-config.component'; +import { isUndefined } from '@core/utils'; +import { + singleSwitchDefaultSettings, + singleSwitchLayoutImages, + singleSwitchLayouts, + singleSwitchLayoutTranslations, + SingleSwitchWidgetSettings +} from '@home/components/widget/lib/rpc/single-switch-widget.models'; +import { ValueType } from '@shared/models/constants'; + +@Component({ + selector: 'tb-single-switch-basic-config', + templateUrl: './single-switch-basic-config.component.html', + styleUrls: ['../basic-config.scss'] +}) +export class SingSwitchBasicConfigComponent extends BasicWidgetConfigComponent { + + get targetDevice(): TargetDevice { + return this.singleSwitchWidgetConfigForm.get('targetDevice').value; + } + + singleSwitchLayouts = singleSwitchLayouts; + + singleSwitchLayoutTranslationMap = singleSwitchLayoutTranslations; + singleSwitchLayoutImageMap = singleSwitchLayoutImages; + + valueType = ValueType; + + singleSwitchWidgetConfigForm: UntypedFormGroup; + + constructor(protected store: Store, + protected widgetConfigComponent: WidgetConfigComponent, + private fb: UntypedFormBuilder) { + super(store, widgetConfigComponent); + } + + protected configForm(): UntypedFormGroup { + return this.singleSwitchWidgetConfigForm; + } + + protected onConfigSet(configData: WidgetConfigComponentData) { + const settings: SingleSwitchWidgetSettings = {...singleSwitchDefaultSettings, ...(configData.config.settings || {})}; + this.singleSwitchWidgetConfigForm = this.fb.group({ + targetDevice: [configData.config.targetDevice, []], + + initialState: [settings.initialState, []], + onUpdateState: [settings.onUpdateState, []], + offUpdateState: [settings.offUpdateState, []], + + layout: [settings.layout, []], + autoScale: [settings.autoScale, []], + + showLabel: [settings.showLabel, []], + label: [settings.label, []], + labelFont: [settings.labelFont, []], + labelColor: [settings.labelColor, []], + + showIcon: [settings.showIcon, []], + iconSize: [settings.iconSize, [Validators.min(0)]], + iconSizeUnit: [settings.iconSizeUnit, []], + icon: [settings.icon, []], + iconColor: [settings.iconColor, []], + + switchColorOn: [settings.switchColorOn, []], + switchColorOff: [settings.switchColorOff, []], + switchColorDisabled: [settings.switchColorDisabled, []], + + tumblerColorOn: [settings.tumblerColorOn, []], + tumblerColorOff: [settings.tumblerColorOff, []], + tumblerColorDisabled: [settings.tumblerColorDisabled, []], + + showOnLabel: [settings.showOnLabel, []], + onLabel: [settings.onLabel, []], + onLabelFont: [settings.onLabelFont, []], + onLabelColor: [settings.onLabelColor, []], + + showOffLabel: [settings.showOffLabel, []], + offLabel: [settings.offLabel, []], + offLabelFont: [settings.offLabelFont, []], + offLabelColor: [settings.offLabelColor, []], + + background: [settings.background, []], + + cardButtons: [this.getCardButtons(configData.config), []], + borderRadius: [configData.config.borderRadius, []], + + actions: [configData.config.actions || {}, []] + }); + } + + protected prepareOutputConfig(config: any): WidgetConfigComponentData { + this.widgetConfig.config.targetDevice = config.targetDevice; + + this.widgetConfig.config.settings = this.widgetConfig.config.settings || {}; + + this.widgetConfig.config.settings.initialState = config.initialState; + this.widgetConfig.config.settings.onUpdateState = config.onUpdateState; + this.widgetConfig.config.settings.offUpdateState = config.offUpdateState; + + this.widgetConfig.config.settings.layout = config.layout; + this.widgetConfig.config.settings.autoScale = config.autoScale; + + this.widgetConfig.config.settings.showLabel = config.showLabel; + this.widgetConfig.config.settings.label = config.label; + this.widgetConfig.config.settings.labelFont = config.labelFont; + this.widgetConfig.config.settings.labelColor = config.labelColor; + + this.widgetConfig.config.settings.showIcon = config.showIcon; + this.widgetConfig.config.settings.iconSize = config.iconSize; + this.widgetConfig.config.settings.iconSizeUnit = config.iconSizeUnit; + this.widgetConfig.config.settings.icon = config.icon; + this.widgetConfig.config.settings.iconColor = config.iconColor; + + this.widgetConfig.config.settings.switchColorOn = config.switchColorOn; + this.widgetConfig.config.settings.switchColorOff = config.switchColorOff; + this.widgetConfig.config.settings.switchColorDisabled = config.switchColorDisabled; + + this.widgetConfig.config.settings.tumblerColorOn = config.tumblerColorOn; + this.widgetConfig.config.settings.tumblerColorOff = config.tumblerColorOff; + this.widgetConfig.config.settings.tumblerColorDisabled = config.tumblerColorDisabled; + + this.widgetConfig.config.settings.showOnLabel = config.showOnLabel; + this.widgetConfig.config.settings.onLabel = config.onLabel; + this.widgetConfig.config.settings.onLabelFont = config.onLabelFont; + this.widgetConfig.config.settings.onLabelColor = config.onLabelColor; + + this.widgetConfig.config.settings.showOffLabel = config.showOffLabel; + this.widgetConfig.config.settings.offLabel = config.offLabel; + this.widgetConfig.config.settings.offLabelFont = config.offLabelFont; + this.widgetConfig.config.settings.offLabelColor = config.offLabelColor; + + this.widgetConfig.config.settings.background = config.background; + + this.setCardButtons(config.cardButtons, this.widgetConfig.config); + this.widgetConfig.config.borderRadius = config.borderRadius; + + this.widgetConfig.config.actions = config.actions; + return this.widgetConfig; + } + + protected validatorTriggers(): string[] { + return ['showLabel', 'showIcon', 'showOnLabel', 'showOffLabel']; + } + + protected updateValidators(emitEvent: boolean, trigger?: string) { + const showLabel: boolean = this.singleSwitchWidgetConfigForm.get('showLabel').value; + const showIcon: boolean = this.singleSwitchWidgetConfigForm.get('showIcon').value; + const showOnLabel: boolean = this.singleSwitchWidgetConfigForm.get('showOnLabel').value; + const showOffLabel: boolean = this.singleSwitchWidgetConfigForm.get('showOffLabel').value; + + if (showLabel) { + this.singleSwitchWidgetConfigForm.get('label').enable(); + this.singleSwitchWidgetConfigForm.get('labelFont').enable(); + this.singleSwitchWidgetConfigForm.get('labelColor').enable(); + } else { + this.singleSwitchWidgetConfigForm.get('label').disable(); + this.singleSwitchWidgetConfigForm.get('labelFont').disable(); + this.singleSwitchWidgetConfigForm.get('labelColor').disable(); + } + + if (showIcon) { + this.singleSwitchWidgetConfigForm.get('iconSize').enable(); + this.singleSwitchWidgetConfigForm.get('iconSizeUnit').enable(); + this.singleSwitchWidgetConfigForm.get('icon').enable(); + this.singleSwitchWidgetConfigForm.get('iconColor').enable(); + } else { + this.singleSwitchWidgetConfigForm.get('iconSize').disable(); + this.singleSwitchWidgetConfigForm.get('iconSizeUnit').disable(); + this.singleSwitchWidgetConfigForm.get('icon').disable(); + this.singleSwitchWidgetConfigForm.get('iconColor').disable(); + } + + if (showOnLabel) { + this.singleSwitchWidgetConfigForm.get('onLabel').enable(); + this.singleSwitchWidgetConfigForm.get('onLabelFont').enable(); + this.singleSwitchWidgetConfigForm.get('onLabelColor').enable(); + } else { + this.singleSwitchWidgetConfigForm.get('onLabel').disable(); + this.singleSwitchWidgetConfigForm.get('onLabelFont').disable(); + this.singleSwitchWidgetConfigForm.get('onLabelColor').disable(); + } + + if (showOffLabel) { + this.singleSwitchWidgetConfigForm.get('offLabel').enable(); + this.singleSwitchWidgetConfigForm.get('offLabelFont').enable(); + this.singleSwitchWidgetConfigForm.get('offLabelColor').enable(); + } else { + this.singleSwitchWidgetConfigForm.get('offLabel').disable(); + this.singleSwitchWidgetConfigForm.get('offLabelFont').disable(); + this.singleSwitchWidgetConfigForm.get('offLabelColor').disable(); + } + + } + + private getCardButtons(config: WidgetConfig): string[] { + const buttons: string[] = []; + if (isUndefined(config.enableFullscreen) || config.enableFullscreen) { + buttons.push('fullscreen'); + } + return buttons; + } + + private setCardButtons(buttons: string[], config: WidgetConfig) { + config.enableFullscreen = buttons.includes('fullscreen'); + } + +} diff --git a/ui-ngx/src/app/modules/home/components/widget/config/target-device.component.html b/ui-ngx/src/app/modules/home/components/widget/config/target-device.component.html new file mode 100644 index 0000000000..b46e5ccc90 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/config/target-device.component.html @@ -0,0 +1,39 @@ + +
+
+
widget-config.target-device
+ + {{ 'device.device' | translate }} + {{ 'entity.entity-alias' | translate }} + +
+ + + + +
diff --git a/ui-ngx/src/app/modules/home/components/widget/config/target-device.component.ts b/ui-ngx/src/app/modules/home/components/widget/config/target-device.component.ts new file mode 100644 index 0000000000..c1d09f50b6 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/config/target-device.component.ts @@ -0,0 +1,166 @@ +/// +/// Copyright © 2016-2024 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 { + ControlValueAccessor, + NG_VALIDATORS, + NG_VALUE_ACCESSOR, + UntypedFormBuilder, + UntypedFormControl, + UntypedFormGroup, + Validator, + Validators +} from '@angular/forms'; +import { Component, forwardRef, Input, OnInit } from '@angular/core'; +import { UtilsService } from '@core/services/utils.service'; +import { TranslateService } from '@ngx-translate/core'; +import { WidgetConfigComponent } from '@home/components/widget/widget-config.component'; +import { TargetDevice, TargetDeviceType } from '@shared/models/widget.models'; +import { EntityType } from '@shared/models/entity-type.models'; +import { IAliasController } from '@core/api/widget-api.models'; +import { EntityAliasSelectCallbacks } from '@home/components/alias/entity-alias-select.component.models'; + +@Component({ + selector: 'tb-target-device', + templateUrl: './target-device.component.html', + styleUrls: [], + providers: [ + { + provide: NG_VALUE_ACCESSOR, + useExisting: forwardRef(() => TargetDeviceComponent), + multi: true + }, + { + provide: NG_VALIDATORS, + useExisting: forwardRef(() => TargetDeviceComponent), + multi: true, + } + ] +}) +export class TargetDeviceComponent implements ControlValueAccessor, OnInit, Validator { + + public get aliasController(): IAliasController { + return this.widgetConfigComponent.aliasController; + } + + public get entityAliasSelectCallbacks(): EntityAliasSelectCallbacks { + return this.widgetConfigComponent.widgetConfigCallbacks; + } + + targetDeviceType = TargetDeviceType; + + entityType = EntityType; + + @Input() + disabled: boolean; + + widgetEditMode = this.utils.widgetEditMode; + + targetDeviceFormGroup: UntypedFormGroup; + + private propagateChange = (_val: any) => {}; + + constructor(private fb: UntypedFormBuilder, + private utils: UtilsService, + public translate: TranslateService, + private widgetConfigComponent: WidgetConfigComponent) { + } + + registerOnChange(fn: any): void { + this.propagateChange = fn; + if (!this.targetDeviceFormGroup.valid) { + setTimeout(() => { + this.targetDeviceUpdated(this.targetDeviceFormGroup.value); + }, 0); + } + } + + registerOnTouched(fn: any): void { + } + + setDisabledState(isDisabled: boolean): void { + this.disabled = isDisabled; + if (this.disabled) { + this.targetDeviceFormGroup.disable({emitEvent: false}); + } else { + this.targetDeviceFormGroup.enable({emitEvent: false}); + this.updateValidators(); + } + } + + ngOnInit() { + this.targetDeviceFormGroup = this.fb.group({ + type: [null, !this.widgetEditMode ? [Validators.required] : []], + deviceId: [null, !this.widgetEditMode ? [Validators.required] : []], + entityAliasId: [null, !this.widgetEditMode ? [Validators.required] : []] + }); + this.targetDeviceFormGroup.get('type').valueChanges.subscribe(() => { + this.updateValidators(); + }); + this.targetDeviceFormGroup.valueChanges.subscribe( + () => { + this.targetDeviceUpdated(this.targetDeviceFormGroup.value); + } + ); + } + + writeValue(targetDevice?: TargetDevice): void { + this.targetDeviceFormGroup.patchValue({ + type: targetDevice?.type || TargetDeviceType.device, + deviceId: targetDevice?.deviceId, + entityAliasId: targetDevice?.entityAliasId + }, {emitEvent: false}); + this.updateValidators(); + if (targetDevice?.type === TargetDeviceType.entity && targetDevice?.entityAliasId) { + const entityAliases = this.aliasController.getEntityAliases(); + if (!entityAliases[targetDevice.entityAliasId]) { + this.targetDeviceFormGroup.get('entityAliasId').patchValue(null, {emitEvent: false}); + setTimeout(() => { + this.targetDeviceUpdated(this.targetDeviceFormGroup.value); + }, 0); + } + } + } + + validate(c: UntypedFormControl) { + return (this.targetDeviceFormGroup.valid) ? null : { + targetDevice: { + valid: false, + }, + }; + } + + private targetDeviceUpdated(targetDevice: TargetDevice) { + this.propagateChange(targetDevice); + } + + private updateValidators() { + const type: TargetDeviceType = this.targetDeviceFormGroup.get('type').value; + if (!this.widgetEditMode && type) { + if (type === TargetDeviceType.device) { + this.targetDeviceFormGroup.get('deviceId').enable({emitEvent: false}); + this.targetDeviceFormGroup.get('entityAliasId').disable({emitEvent: false}); + } else { + this.targetDeviceFormGroup.get('deviceId').disable({emitEvent: false}); + this.targetDeviceFormGroup.get('entityAliasId').enable({emitEvent: false}); + } + } else { + this.targetDeviceFormGroup.get('deviceId').disable({emitEvent: false}); + this.targetDeviceFormGroup.get('entityAliasId').disable({emitEvent: false}); + } + } + +} diff --git a/ui-ngx/src/app/modules/home/components/widget/config/widget-config-components.module.ts b/ui-ngx/src/app/modules/home/components/widget/config/widget-config-components.module.ts index fa19f2b2b5..4470fc1327 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/widget-config-components.module.ts +++ b/ui-ngx/src/app/modules/home/components/widget/config/widget-config-components.module.ts @@ -32,6 +32,7 @@ import { TimewindowConfigPanelComponent } from '@home/components/widget/config/t import { WidgetSettingsCommonModule } from '@home/components/widget/lib/settings/common/widget-settings-common.module'; import { TimewindowStyleComponent } from '@home/components/widget/config/timewindow-style.component'; import { TimewindowStylePanelComponent } from '@home/components/widget/config/timewindow-style-panel.component'; +import { TargetDeviceComponent } from '@home/components/widget/config/target-device.component'; @NgModule({ declarations: @@ -43,6 +44,7 @@ import { TimewindowStylePanelComponent } from '@home/components/widget/config/ti DataKeyConfigComponent, DatasourceComponent, DatasourcesComponent, + TargetDeviceComponent, EntityAliasSelectComponent, FilterSelectComponent, TimewindowStyleComponent, @@ -64,6 +66,7 @@ import { TimewindowStylePanelComponent } from '@home/components/widget/config/ti DataKeyConfigComponent, DatasourceComponent, DatasourcesComponent, + TargetDeviceComponent, EntityAliasSelectComponent, FilterSelectComponent, TimewindowStyleComponent, diff --git a/ui-ngx/src/app/modules/home/components/widget/config/widget-config.component.models.ts b/ui-ngx/src/app/modules/home/components/widget/config/widget-config.component.models.ts index 6373770e38..1132e8bf91 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/widget-config.component.models.ts +++ b/ui-ngx/src/app/modules/home/components/widget/config/widget-config.component.models.ts @@ -27,6 +27,7 @@ import { DataKey, DatasourceType, KeyInfo, WidgetConfigMode } from '@shared/mode import { WidgetConfigComponent } from '@home/components/widget/widget-config.component'; import { DataKeyType } from '@shared/models/telemetry/telemetry.models'; import { isDefinedAndNotNull } from '@core/utils'; +import { IAliasController } from '@core/api/widget-api.models'; export type WidgetConfigCallbacks = DatasourceCallbacks & WidgetActionCallbacks; @@ -58,6 +59,10 @@ export abstract class BasicWidgetConfigComponent extends PageComponent implement return this.widgetConfigValue; } + get aliasController(): IAliasController { + return this.widgetConfigComponent.aliasController; + } + widgetConfigChangedEmitter = new EventEmitter(); widgetConfigChanged = this.widgetConfigChangedEmitter.asObservable(); diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/rpc/rpc-widget.models.ts b/ui-ngx/src/app/modules/home/components/widget/lib/rpc/rpc-widget.models.ts new file mode 100644 index 0000000000..77dbd31ddb --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/lib/rpc/rpc-widget.models.ts @@ -0,0 +1,561 @@ +/// +/// Copyright © 2016-2024 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 { AttributeData, LatestTelemetry } from '@shared/models/telemetry/telemetry.models'; +import { WidgetContext } from '@home/models/widget-component.models'; +import { BehaviorSubject, Observable, of } from 'rxjs'; +import { catchError, delay, map, share } from 'rxjs/operators'; +import { UtilsService } from '@core/services/utils.service'; +import { AfterViewInit, ChangeDetectorRef, Directive, Input, OnInit, TemplateRef } from '@angular/core'; +import { backgroundStyle, ComponentStyle, overlayStyle } from '@shared/models/widget-settings.models'; +import { ImagePipe } from '@shared/pipe/image.pipe'; +import { DomSanitizer } from '@angular/platform-browser'; +import { + RpcGetAttributeSettings, + RpcSetAttributeSettings, + RpcSettings, + RpcStateToParamsSettings, + RpcStateToParamsType, + RpcStateWidgetSettings, + RpcTelemetrySettings, + RpcUpdateStateAction +} from '@shared/models/rpc-widget-settings.models'; +import { + RpcDataToStateSettings, + RpcDataToStateType, + RpcInitialStateAction, + RpcInitialStateSettings, + RpcStateBehaviourSettings, + RpcUpdateStateSettings +} from '@app/shared/models/rpc-widget-settings.models'; +import { ValueType } from '@shared/models/constants'; + +@Directive() +// eslint-disable-next-line @angular-eslint/directive-class-suffix +export abstract class BasicRpcStateWidgetComponent> implements OnInit, AfterViewInit { + + @Input() + ctx: WidgetContext; + + @Input() + widgetTitlePanel: TemplateRef; + + settings: S; + + behaviorApi: RpcStateBehaviorApi; + loading$: Observable; + + backgroundStyle$: Observable; + overlayStyle: ComponentStyle = {}; + + value: V; + + error = ''; + + protected constructor(protected imagePipe: ImagePipe, + protected sanitizer: DomSanitizer, + protected cd: ChangeDetectorRef) { + } + + ngOnInit(): void { + this.ctx.$scope.rpcWidget = this; + this.settings = {...this.defaultSettings(), ...this.ctx.settings}; + this.backgroundStyle$ = backgroundStyle(this.settings.background, this.imagePipe, this.sanitizer); + this.overlayStyle = overlayStyle(this.settings.background.overlay); + + const behaviourSettings: RpcStateBehaviourSettings = { + initialState: this.settings.initialState, + updateStateByValue: val => this.getUpdateStateSettingsForValue(val) + }; + + const callbacks: RpcStateCallbacks = { + onStateValue: val => this.setValue(val), + onError: err => this.onError(err), + validateStateValue: val => this.validateValue(val) + }; + + this.behaviorApi = new RpcStateBehaviorApi(this.defaultValue(), this.ctx, + behaviourSettings, callbacks, this.stateValueType()); + this.loading$ = this.behaviorApi.loading$.pipe(share()); + } + + ngAfterViewInit(): void { + this.behaviorApi.initState(); + } + + public onInit() { + const borderRadius = this.ctx.$widgetElement.css('borderRadius'); + this.overlayStyle = {...this.overlayStyle, ...{borderRadius}}; + this.cd.detectChanges(); + } + + public clearError() { + this.error = ''; + } + + public updateValue() { + this.behaviorApi.updateState(this.value); + } + + private onError(error: string) { + this.error = error; + this.ctx.detectChanges(); + } + + protected abstract defaultSettings(): S; + + protected abstract getUpdateStateSettingsForValue(value: V): RpcUpdateStateSettings; + + protected stateValueType(): ValueType { + return ValueType.BOOLEAN; + } + + protected defaultValue(): V { + return null; + } + + protected setValue(value: V) { + this.value = value; + } + + protected validateValue(value: any): V { + return value; + } + +} + +export abstract class RpcHasLoading { + + public get loading$() { + return this.loadingSubject.asObservable(); + } + + protected loadingSubject = new BehaviorSubject(false); +} + +export interface RpcStateCallbacks { + onStateValue: (value: V) => void; + validateStateValue: (value: any) => V; + onError: (error: string) => void; +} + +export class RpcStateBehaviorApi extends RpcHasLoading { + + private readonly initialStateGetter: RpcInitialStateGetter; + private readonly stateUpdatersMap: Map>; + + constructor(private state: V, + private ctx: WidgetContext, + private settings: RpcStateBehaviourSettings, + private callbacks: RpcStateCallbacks, + private stateValueType: ValueType) { + super(); + this.initialStateGetter = RpcInitialStateGetter.fromSettings(ctx, settings.initialState, stateValueType, callbacks); + this.stateUpdatersMap = new Map>(); + } + + initState() { + if (this.ctx.defaultSubscription.rpcEnabled) { + this.loadingSubject.next(true); + this.initialStateGetter.initState().subscribe( + { + next: (value) => { + this.state = value; + this.loadingSubject.next(false); + this.callbacks.onStateValue(value); + this.ctx.detectChanges(); + }, + error: (err: any) => { + this.loadingSubject.next(false); + const message = parseError(this.ctx, err); + this.callbacks.onError(message); + } + } + ); + } else { + this.callbacks.onError('Target device is not set!'); + } + } + + updateState(value: V) { + this.callbacks.onError(null); + let updater: RpcStateUpdater; + const updateStateSettings = this.settings.updateStateByValue(value); + if (updateStateSettings) { + updater = this.stateUpdatersMap.get(updateStateSettings); + if (!updater) { + updater = RpcStateUpdater.fromSettings(this.ctx, updateStateSettings); + this.stateUpdatersMap.set(updateStateSettings, updater); + } + } + if (updater) { + this.loadingSubject.next(true); + updater.updateState(value).subscribe( + { + next: () => { + this.state = value; + this.loadingSubject.next(false); + this.ctx.detectChanges(); + }, + error: (err: any) => { + this.loadingSubject.next(false); + const message = parseError(this.ctx, err); + this.callbacks.onStateValue(this.state); + this.callbacks.onError(message); + this.ctx.detectChanges(); + } + }); + } + } + +} + +type RpcDataToStateFunction = (data: any) => V; + +export class RpcDataToStateConverter { + + private readonly dataToStateFunction: RpcDataToStateFunction; + private readonly compareToValue: any; + + constructor(private settings: RpcDataToStateSettings, + private stateValueType: ValueType, + private callbacks: RpcStateCallbacks) { + this.compareToValue = settings.compareToValue; + switch (settings.type) { + case RpcDataToStateType.FUNCTION: + try { + this.dataToStateFunction = new Function('data', settings.dataToStateFunction) as RpcDataToStateFunction; + } catch (e) { + this.dataToStateFunction = (data) => data; + } + break; + case RpcDataToStateType.NONE: + break; + } + } + + dataToStateValue(data: any): V { + let result: V; + switch (this.settings.type) { + case RpcDataToStateType.FUNCTION: + result = data; + try { + result = this.dataToStateFunction(!!data ? JSON.parse(data) : data); + } catch (e) {} + break; + case RpcDataToStateType.NONE: + result = data; + break; + } + if (this.stateValueType === ValueType.BOOLEAN) { + result = (result === this.compareToValue) as any; + } + result = this.callbacks.validateStateValue(result); + return result; + } +} + +export abstract class RpcInitialStateGetter { + + static fromSettings(ctx: WidgetContext, + settings: RpcInitialStateSettings, + stateValueType: ValueType, + callbacks: RpcStateCallbacks): RpcInitialStateGetter { + switch (settings.action) { + case RpcInitialStateAction.DO_NOTHING: + return new RpcDefaultStateGetter(ctx, settings, stateValueType, callbacks); + case RpcInitialStateAction.EXECUTE_RPC: + return new ExecuteRpcStateGetter(ctx, settings, stateValueType, callbacks); + case RpcInitialStateAction.GET_ATTRIBUTE: + return new RpcAttributeStateGetter(ctx, settings, stateValueType, callbacks); + case RpcInitialStateAction.GET_TIME_SERIES: + return new RpcTimeSeriesStateGetter(ctx, settings, stateValueType, callbacks); + } + } + + private readonly isSimulated: boolean; + private readonly dataConverter: RpcDataToStateConverter; + + protected constructor(protected ctx: WidgetContext, + protected settings: RpcInitialStateSettings, + protected stateValueType: ValueType, + protected callbacks: RpcStateCallbacks) { + this.isSimulated = this.ctx.$injector.get(UtilsService).widgetEditMode; + if (this.settings.action !== RpcInitialStateAction.DO_NOTHING) { + this.dataConverter = new RpcDataToStateConverter(settings.dataToState, stateValueType, this.callbacks); + } + } + + initState(): Observable { + const stateObservable: Observable = this.isSimulated ? of(null).pipe(delay(500)) : this.doGetState(); + return stateObservable.pipe( + map((data) => { + if (this.dataConverter) { + return this.dataConverter.dataToStateValue(data); + } else { + return data; + } + }) + ); + } + + protected abstract doGetState(): Observable; +} + +type RpcStateToParamsFunction = (state: V) => any; + +export class RpcStateToParamsConverter { + + private readonly constantValue: any; + private readonly stateToParamsFunction: RpcStateToParamsFunction; + + constructor(protected settings: RpcStateToParamsSettings) { + switch (settings.type) { + case RpcStateToParamsType.CONSTANT: + this.constantValue = this.settings.constantValue; + break; + case RpcStateToParamsType.FUNCTION: + try { + this.stateToParamsFunction = new Function('value', settings.stateToParamsFunction) as RpcStateToParamsFunction; + } catch (e) { + this.stateToParamsFunction = (data) => data; + } + break; + case RpcStateToParamsType.NONE: + break; + } + } + + stateToParams(state: V): any { + switch (this.settings.type) { + case RpcStateToParamsType.CONSTANT: + return this.constantValue; + case RpcStateToParamsType.FUNCTION: + let result = state; + try { + result = this.stateToParamsFunction(state); + } catch (e) {} + return result; + case RpcStateToParamsType.NONE: + return null; + } + } +} + +export abstract class RpcStateUpdater { + + static fromSettings(ctx: WidgetContext, + settings: RpcUpdateStateSettings): RpcStateUpdater { + switch (settings.action) { + case RpcUpdateStateAction.EXECUTE_RPC: + return new ExecuteRpcStateUpdater(ctx, settings); + case RpcUpdateStateAction.SET_ATTRIBUTE: + return new RpcAttributeStateUpdater(ctx, settings); + case RpcUpdateStateAction.ADD_TIME_SERIES: + return new RpcTimeSeriesStateUpdater(ctx, settings); + } + } + + private readonly isSimulated: boolean; + private readonly paramsConverter: RpcStateToParamsConverter; + + protected constructor(protected ctx: WidgetContext, + protected settings: RpcUpdateStateSettings) { + this.isSimulated = this.ctx.$injector.get(UtilsService).widgetEditMode; + this.paramsConverter = new RpcStateToParamsConverter(settings.stateToParams); + } + + updateState(state: V): Observable { + if (this.isSimulated) { + return of(null).pipe(delay(500)); + } else { + return this.doUpdateState(this.paramsConverter.stateToParams(state)); + } + } + + protected abstract doUpdateState(params: any): Observable; +} + +export class RpcDefaultStateGetter extends RpcInitialStateGetter { + + private readonly defaultValue: V; + + constructor(protected ctx: WidgetContext, + protected settings: RpcInitialStateSettings, + protected stateValueType: ValueType, + protected callbacks: RpcStateCallbacks) { + super(ctx, settings, stateValueType, callbacks); + this.defaultValue = settings.defaultValue; + } + + protected doGetState(): Observable { + return of(this.defaultValue); + } +} + +export class ExecuteRpcStateGetter extends RpcInitialStateGetter { + + private readonly executeRpcSettings: RpcSettings; + + constructor(protected ctx: WidgetContext, + protected settings: RpcInitialStateSettings, + protected stateValueType: ValueType, + protected callbacks: RpcStateCallbacks) { + super(ctx, settings, stateValueType, callbacks); + this.executeRpcSettings = settings.executeRpc; + } + + protected doGetState(): Observable { + return this.ctx.controlApi.sendTwoWayCommand(this.executeRpcSettings.method, null, + this.executeRpcSettings.requestTimeout, + this.executeRpcSettings.requestPersistent, + this.executeRpcSettings.persistentPollingInterval).pipe( + catchError(() => { + throw new Error(this.ctx.defaultSubscription.rpcErrorText); + }) + ); + } +} + +export class RpcAttributeStateGetter extends RpcInitialStateGetter { + + private readonly getAttributeSettings: RpcGetAttributeSettings; + + constructor(protected ctx: WidgetContext, + protected settings: RpcInitialStateSettings, + protected stateValueType: ValueType, + protected callbacks: RpcStateCallbacks) { + super(ctx, settings, stateValueType, callbacks); + this.getAttributeSettings = settings.getAttribute; + } + + protected doGetState(): Observable { + if (this.ctx.defaultSubscription.targetEntityId) { + return this.ctx.attributeService.getEntityAttributes(this.ctx.defaultSubscription.targetEntityId, + this.getAttributeSettings.scope, [this.getAttributeSettings.key], {ignoreLoading: true, ignoreErrors: true}) + .pipe( + map((data) => data.find(attr => attr.key === this.getAttributeSettings.key)?.value) + ); + } else { + return of(null); + } + } + +} + +export class RpcTimeSeriesStateGetter extends RpcInitialStateGetter { + + private readonly getTimeSeriesSettings: RpcTelemetrySettings; + + constructor(protected ctx: WidgetContext, + protected settings: RpcInitialStateSettings, + protected stateValueType: ValueType, + protected callbacks: RpcStateCallbacks) { + super(ctx, settings, stateValueType, callbacks); + this.getTimeSeriesSettings = settings.getTimeSeries; + } + + protected doGetState(): Observable { + if (this.ctx.defaultSubscription.targetEntityId) { + return this.ctx.attributeService.getEntityTimeseriesLatest(this.ctx.defaultSubscription.targetEntityId, + [this.getTimeSeriesSettings.key], true, {ignoreLoading: true, ignoreErrors: true}) + .pipe( + map((data) => { + let value: any = null; + if (data[this.getTimeSeriesSettings.key]) { + const dataSet = data[this.getTimeSeriesSettings.key]; + if (dataSet.length) { + value = dataSet[0].value; + } + } + return value; + }) + ); + } else { + return of(null); + } + } + +} + +export class ExecuteRpcStateUpdater extends RpcStateUpdater { + + private readonly executeRpcSettings: RpcSettings; + + constructor(protected ctx: WidgetContext, + protected settings: RpcUpdateStateSettings) { + super(ctx, settings); + this.executeRpcSettings = settings.executeRpc; + } + + protected doUpdateState(params: any): Observable { + return this.ctx.controlApi.sendOneWayCommand(this.executeRpcSettings.method, params, + this.executeRpcSettings.requestTimeout, + this.executeRpcSettings.requestPersistent, + this.executeRpcSettings.persistentPollingInterval).pipe( + catchError(() => { + throw new Error(this.ctx.defaultSubscription.rpcErrorText); + }) + ); + } +} + +export class RpcAttributeStateUpdater extends RpcStateUpdater { + + private readonly setAttributeSettings: RpcSetAttributeSettings; + + constructor(protected ctx: WidgetContext, + protected settings: RpcUpdateStateSettings) { + super(ctx, settings); + this.setAttributeSettings = settings.setAttribute; + } + + protected doUpdateState(params: any): Observable { + if (this.ctx.defaultSubscription.targetEntityId) { + const attributes: Array = [{key: this.setAttributeSettings.key, value: params}]; + return this.ctx.attributeService.saveEntityAttributes(this.ctx.defaultSubscription.targetEntityId, + this.setAttributeSettings.scope, attributes, {ignoreLoading: true, ignoreErrors: true}); + } else { + return of(null); + } + } + +} + +export class RpcTimeSeriesStateUpdater extends RpcStateUpdater { + + private readonly putTimeSeriesSettings: RpcTelemetrySettings; + + constructor(protected ctx: WidgetContext, + protected settings: RpcUpdateStateSettings) { + super(ctx, settings); + this.putTimeSeriesSettings = settings.putTimeSeries; + } + + protected doUpdateState(params: any): Observable { + if (this.ctx.defaultSubscription.targetEntityId) { + const timeSeries: Array = [{key: this.putTimeSeriesSettings.key, value: params}]; + return this.ctx.attributeService.saveEntityTimeseries(this.ctx.defaultSubscription.targetEntityId, + LatestTelemetry.LATEST_TELEMETRY, timeSeries, {ignoreLoading: true, ignoreErrors: true}); + } else { + return of(null); + } + } + +} + +const parseError = (ctx: WidgetContext, err: any): string => + ctx.$injector.get(UtilsService).parseException(err).message || 'Unknown Error'; diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/rpc/single-switch-widget.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/rpc/single-switch-widget.component.html new file mode 100644 index 0000000000..62e6296163 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/lib/rpc/single-switch-widget.component.html @@ -0,0 +1,42 @@ + +
+
+
+ +
+
+
+ {{ icon }} +
{{ label$ | async }}
+
+
+
{{ offLabel }}
+ + +
{{ onLabel }}
+
+
+ +
+
+
{{ error }}
+ +
+
+
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/rpc/single-switch-widget.component.scss b/ui-ngx/src/app/modules/home/components/widget/lib/rpc/single-switch-widget.component.scss new file mode 100644 index 0000000000..15d1e2b0fe --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/lib/rpc/single-switch-widget.component.scss @@ -0,0 +1,204 @@ +/** + * Copyright © 2016-2024 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. + */ +$tumblerColorOn: var(--tb-single-switch-tumbler-color-on, #fff); +$tumblerColorOff: var(--tb-single-switch-tumbler-color-off, #fff); +$tumblerColorDisabled: var(--tb-single-switch-tumbler-color-disabled, #fff); + +$switchColorOn: var(--tb-single-switch-color-on, #5469FF); +$switchColorOff: var(--tb-single-switch-color-off, rgba(84, 105, 255, 0.30)); +$switchColorDisabled: var(--tb-single-switch-color-disabled, #D5D7E5); + +.tb-single-switch-panel { + width: 100%; + height: 100%; + position: relative; + display: flex; + align-items: center; + justify-content: center; + padding: 18px 24px; + > div:not(.tb-single-switch-overlay), > tb-icon { + z-index: 1; + } + .tb-single-switch-overlay { + position: absolute; + top: 12px; + left: 12px; + bottom: 12px; + right: 12px; + } + .tb-single-switch-progress { + position: absolute; + bottom: 0; + left: 0; + right: 0; + } + .tb-single-switch-error-container { + position: absolute; + bottom: 0; + left: 0; + right: 0; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + .tb-single-switch-error-panel { + display: flex; + padding: 4px 4px 4px 12px; + justify-content: center; + align-items: center; + gap: 4px; + border-radius: 4px; + border: 1px solid rgba(209, 39, 48, 0.04); + background: rgba(209, 39, 48, 0.04); + .tb-single-switch-error-text { + font-size: 12px; + font-style: normal; + font-weight: 400; + line-height: 16px; + color: #D12730; + } + .tb-single-switch-error-clear { + color: rgba(209, 39, 48, 1); + } + } + } + > div.tb-single-switch-title-panel { + position: absolute; + top: 12px; + left: 12px; + right: 12px; + z-index: 2; + } + .tb-single-switch-content { + width: 100%; + height: 100%; + position: relative; + display: flex; + align-items: center; + gap: 8px; + &.right { + flex-direction: row; + justify-content: space-between; + } + &.no-label.right { + justify-content: flex-end; + } + &.left { + flex-direction: row-reverse; + justify-content: flex-end; + } + &.centered { + flex-direction: row; + justify-content: center; + } + .tb-single-switch-label-row { + display: flex; + flex-direction: row; + align-items: center; + gap: 8px; + .tb-single-switch-label { + white-space: nowrap; + } + } + &:not(.auto-scale) { + .tb-single-switch-label-row { + overflow: hidden; + .tb-single-switch-label { + overflow: hidden; + text-overflow: ellipsis; + } + } + } + .tb-single-switch-slide-toggle-row { + display: flex; + flex-direction: row; + align-items: center; + gap: 8px; + } + .mat-mdc-slide-toggle { + &.tb-single-switch-toggle { + .mdc-switch { + width: 42px; + height: 22px; + .mdc-switch__track { + height: 22px; + border-radius: 11px; + &::after, &::before { + border: none; + } + } + .mdc-switch__handle-track { + width: calc(100% - 22px); + left: 2px; + } + .mdc-switch__handle { + border-radius: 9px; + width: 18px; + height: 18px; + } + .mdc-switch__ripple { + width: 36px; + height: 36px; + } + .mdc-switch__icons { + display: none; + } + &:disabled { + .mdc-switch__track { + opacity: 1; + &::after, &::before { + background: $switchColorDisabled; + } + } + .mdc-switch__handle::after { + opacity: 1; + background: $tumblerColorDisabled; + } + } + &:enabled, &:enabled:hover { + .mdc-switch__track { + &::after { + background: $switchColorOn; + } + &::before { + background: $switchColorOff; + } + } + &.mdc-switch--selected { + .mdc-switch__handle::after { + background: $tumblerColorOn; + } + .mdc-switch__ripple::after { + background-color: $switchColorOn; + } + } + &.mdc-switch--unselected { + .mdc-switch__handle::after { + background: $tumblerColorOff; + } + .mdc-switch__ripple::after { + background-color: $switchColorOff; + } + } + } + } + .mdc-form-field > label { + display: none; + } + } + } + } +} diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/rpc/single-switch-widget.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/rpc/single-switch-widget.component.ts new file mode 100644 index 0000000000..0fffd67b9f --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/lib/rpc/single-switch-widget.component.ts @@ -0,0 +1,197 @@ +/// +/// Copyright © 2016-2024 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 { + AfterViewInit, + ChangeDetectorRef, + Component, + ElementRef, + OnDestroy, + OnInit, + Renderer2, + ViewChild, + ViewEncapsulation +} from '@angular/core'; +import { BasicRpcStateWidgetComponent } from '@home/components/widget/lib/rpc/rpc-widget.models'; +import { + singleSwitchDefaultSettings, + SingleSwitchLayout, + SingleSwitchWidgetSettings +} from '@home/components/widget/lib/rpc/single-switch-widget.models'; +import { ComponentStyle, iconStyle, textStyle } from '@shared/models/widget-settings.models'; +import { Observable } from 'rxjs'; +import { ResizeObserver } from '@juggle/resize-observer'; +import { ImagePipe } from '@shared/pipe/image.pipe'; +import { DomSanitizer } from '@angular/platform-browser'; +import cssjs from '@core/css/css'; +import { hashCode } from '@core/utils'; +import { RpcUpdateStateSettings } from '@shared/models/rpc-widget-settings.models'; +import { ValueType } from '@shared/models/constants'; + +const horizontalLayoutPadding = 48; +const verticalLayoutPadding = 36; + +@Component({ + selector: 'tb-single-switch-widget', + templateUrl: './single-switch-widget.component.html', + styleUrls: ['./single-switch-widget.component.scss'], + encapsulation: ViewEncapsulation.None +}) +export class SingleSwitchWidgetComponent extends + BasicRpcStateWidgetComponent implements OnInit, AfterViewInit, OnDestroy { + + @ViewChild('singleSwitchPanel', {static: false}) + singleSwitchPanel: ElementRef; + + @ViewChild('singleSwitchContent', {static: false}) + singleSwitchContent: ElementRef; + + @ViewChild('singleSwitchLabelRow', {static: false}) + singleSwitchLabelRow: ElementRef; + + @ViewChild('singleSwitchToggleRow', {static: false}) + singleSwitchToggleRow: ElementRef; + + layout: SingleSwitchLayout; + + showIcon = false; + icon = ''; + iconStyle: ComponentStyle = {}; + + showLabel = true; + label$: Observable; + labelStyle: ComponentStyle = {}; + + showOnLabel = false; + onLabel = ''; + onLabelStyle: ComponentStyle = {}; + + showOffLabel = false; + offLabel = ''; + offLabelStyle: ComponentStyle = {}; + + autoScale = false; + + private panelResize$: ResizeObserver; + + constructor(protected imagePipe: ImagePipe, + protected sanitizer: DomSanitizer, + private renderer: Renderer2, + protected cd: ChangeDetectorRef, + private elementRef: ElementRef) { + super(imagePipe, sanitizer, cd); + } + + ngOnInit(): void { + super.ngOnInit(); + this.layout = this.settings.layout; + + this.autoScale = this.settings.autoScale; + + this.showLabel = this.settings.showLabel; + this.label$ = this.ctx.registerLabelPattern(this.settings.label, this.label$); + this.labelStyle = textStyle(this.settings.labelFont); + this.labelStyle.color = this.settings.labelColor; + + this.showIcon = this.settings.showIcon; + this.icon = this.settings.icon; + this.iconStyle = iconStyle(this.settings.iconSize, this.settings.iconSizeUnit ); + this.iconStyle.color = this.settings.iconColor; + + this.showOnLabel = this.settings.showOnLabel; + this.onLabel = this.settings.onLabel; + this.onLabelStyle = textStyle(this.settings.onLabelFont); + this.onLabelStyle.color = this.settings.onLabelColor; + + this.showOffLabel = this.settings.showOffLabel; + this.offLabel = this.settings.offLabel; + this.offLabelStyle = textStyle(this.settings.offLabelFont); + this.offLabelStyle.color = this.settings.offLabelColor; + const switchVariablesCss = `.tb-single-switch-panel {\n`+ + `--tb-single-switch-tumbler-color-on: ${this.settings.tumblerColorOn};\n`+ + `--tb-single-switch-tumbler-color-off: ${this.settings.tumblerColorOff};\n`+ + `--tb-single-switch-tumbler-color-disabled: ${this.settings.tumblerColorDisabled};\n`+ + `--tb-single-switch-color-on: ${this.settings.switchColorOn};\n`+ + `--tb-single-switch-color-off: ${this.settings.switchColorOff};\n`+ + `--tb-single-switch-color-disabled: ${this.settings.switchColorDisabled};\n`+ + `}`; + const cssParser = new cssjs(); + cssParser.testMode = false; + const namespace = 'single-switch-' + hashCode(switchVariablesCss); + cssParser.cssPreviewNamespace = namespace; + cssParser.createStyleElement(namespace, switchVariablesCss); + this.renderer.addClass(this.elementRef.nativeElement, namespace); + } + + ngAfterViewInit(): void { + if (this.autoScale) { + this.renderer.setStyle(this.singleSwitchContent.nativeElement, 'overflow', 'visible'); + this.renderer.setStyle(this.singleSwitchContent.nativeElement, 'position', 'absolute'); + this.panelResize$ = new ResizeObserver(() => { + this.onResize(); + }); + this.panelResize$.observe(this.singleSwitchPanel.nativeElement); + if (this.showLabel) { + this.panelResize$.observe(this.singleSwitchLabelRow.nativeElement); + } + this.onResize(); + } + super.ngAfterViewInit(); + } + + ngOnDestroy() { + if (this.panelResize$) { + this.panelResize$.disconnect(); + } + } + + protected stateValueType(): ValueType { + return ValueType.BOOLEAN; + } + + protected defaultValue(): boolean { + return false; + } + + protected defaultSettings(): SingleSwitchWidgetSettings { + return {...singleSwitchDefaultSettings}; + } + + protected getUpdateStateSettingsForValue(value: boolean): RpcUpdateStateSettings { + return value ? this.settings.onUpdateState : this.settings.offUpdateState; + } + + protected validateValue(value: any): boolean { + return !!value; + } + + private onResize() { + const panelWidth = this.singleSwitchPanel.nativeElement.getBoundingClientRect().width - horizontalLayoutPadding; + const panelHeight = this.singleSwitchPanel.nativeElement.getBoundingClientRect().height - verticalLayoutPadding; + this.renderer.setStyle(this.singleSwitchContent.nativeElement, 'transform', `scale(1)`); + let contentWidth = this.singleSwitchToggleRow.nativeElement.getBoundingClientRect().width; + let contentHeight = this.singleSwitchToggleRow.nativeElement.getBoundingClientRect().height; + if (this.showIcon || this.showLabel) { + contentWidth += (8 + this.singleSwitchLabelRow.nativeElement.getBoundingClientRect().width); + contentHeight = Math.max(contentHeight, this.singleSwitchLabelRow.nativeElement.getBoundingClientRect().height); + } + const scale = Math.min(panelWidth / contentWidth, panelHeight / contentHeight); + const width = panelWidth / scale; + this.renderer.setStyle(this.singleSwitchContent.nativeElement, 'width', width + 'px'); + this.renderer.setStyle(this.singleSwitchContent.nativeElement, 'transform', `scale(${scale})`); + } + +} diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/rpc/single-switch-widget.models.ts b/ui-ngx/src/app/modules/home/components/widget/lib/rpc/single-switch-widget.models.ts new file mode 100644 index 0000000000..57c2af3b5e --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/lib/rpc/single-switch-widget.models.ts @@ -0,0 +1,202 @@ +/// +/// Copyright © 2016-2024 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 { BackgroundType, cssUnit, Font } from '@shared/models/widget-settings.models'; +import { AttributeScope } from '@shared/models/telemetry/telemetry.models'; +import { + RpcDataToStateType, + RpcInitialStateAction, + RpcStateToParamsType, + RpcStateWidgetSettings, + RpcUpdateStateAction, + RpcUpdateStateSettings +} from '@shared/models/rpc-widget-settings.models'; + +export enum SingleSwitchLayout { + right = 'right', + left = 'left', + centered = 'centered' +} + +export const singleSwitchLayouts = Object.keys(SingleSwitchLayout) as SingleSwitchLayout[]; + +export const singleSwitchLayoutTranslations = new Map( + [ + [SingleSwitchLayout.right, 'widgets.single-switch.layout-right'], + [SingleSwitchLayout.left, 'widgets.single-switch.layout-left'], + [SingleSwitchLayout.centered, 'widgets.single-switch.layout-centered'] + ] +); + +export const singleSwitchLayoutImages = new Map( + [ + [SingleSwitchLayout.right, 'assets/widget/single-switch/right-layout.svg'], + [SingleSwitchLayout.left, 'assets/widget/single-switch/left-layout.svg'], + [SingleSwitchLayout.centered, 'assets/widget/single-switch/centered-layout.svg'] + ] +); + +export interface SingleSwitchWidgetSettings extends RpcStateWidgetSettings { + onUpdateState: RpcUpdateStateSettings; + offUpdateState: RpcUpdateStateSettings; + layout: SingleSwitchLayout; + autoScale: boolean; + showLabel: boolean; + label: string; + labelFont: Font; + labelColor: string; + showIcon: boolean; + icon: string; + iconSize: number; + iconSizeUnit: cssUnit; + iconColor: string; + switchColorOn: string; + switchColorOff: string; + switchColorDisabled: string; + tumblerColorOn: string; + tumblerColorOff: string; + tumblerColorDisabled: string; + showOnLabel: boolean; + onLabel: string; + onLabelFont: Font; + onLabelColor: string; + showOffLabel: boolean; + offLabel: string; + offLabelFont: Font; + offLabelColor: string; +} + +export const singleSwitchDefaultSettings: SingleSwitchWidgetSettings = { + initialState: { + action: RpcInitialStateAction.EXECUTE_RPC, + defaultValue: false, + executeRpc: { + method: 'getState', + requestTimeout: 5000, + requestPersistent: false, + persistentPollingInterval: 1000 + }, + getAttribute: { + key: 'state', + scope: null + }, + getTimeSeries: { + key: 'state' + }, + dataToState: { + type: RpcDataToStateType.NONE, + compareToValue: true, + dataToStateFunction: '/* Should return boolean value */\nreturn data;' + } + }, + onUpdateState: { + action: RpcUpdateStateAction.EXECUTE_RPC, + executeRpc: { + method: 'setState', + requestTimeout: 5000, + requestPersistent: false, + persistentPollingInterval: 1000 + }, + setAttribute: { + key: 'state', + scope: AttributeScope.SHARED_SCOPE + }, + putTimeSeries: { + key: 'state' + }, + stateToParams: { + type: RpcStateToParamsType.CONSTANT, + constantValue: true, + stateToParamsFunction: '/* Convert input boolean value to RPC parameters or attribute/time-series value */\nreturn value;' + } + }, + offUpdateState: { + action: RpcUpdateStateAction.EXECUTE_RPC, + executeRpc: { + method: 'setState', + requestTimeout: 5000, + requestPersistent: false, + persistentPollingInterval: 1000 + }, + setAttribute: { + key: 'state', + scope: AttributeScope.SHARED_SCOPE + }, + putTimeSeries: { + key: 'state' + }, + stateToParams: { + type: RpcStateToParamsType.CONSTANT, + constantValue: false, + stateToParamsFunction: '/* Convert input boolean value to RPC parameters or attribute/time-series value */ \n return value;' + } + }, + layout: SingleSwitchLayout.right, + autoScale: true, + showLabel: true, + label: 'Switch', + labelFont: { + family: 'Roboto', + size: 16, + sizeUnit: 'px', + style: 'normal', + weight: '500', + lineHeight: '24px' + }, + labelColor: 'rgba(0, 0, 0, 0.76)', + showIcon: false, + icon: 'mdi:lightbulb-outline', + iconSize: 24, + iconSizeUnit: 'px', + iconColor: 'rgba(0, 0, 0, 0.76)', + switchColorOn: '#5469FF', + switchColorOff: 'rgba(84, 105, 255, 0.30)', + switchColorDisabled: '#D5D7E5', + tumblerColorOn: '#fff', + tumblerColorOff: '#fff', + tumblerColorDisabled: '#fff', + showOnLabel: false, + onLabel: 'On', + onLabelFont: { + family: 'Roboto', + size: 16, + sizeUnit: 'px', + style: 'normal', + weight: '400', + lineHeight: '24px' + }, + onLabelColor: 'rgba(0, 0, 0, 0.38)', + showOffLabel: false, + offLabel: 'Off', + offLabelFont: { + family: 'Roboto', + size: 16, + sizeUnit: 'px', + style: 'normal', + weight: '400', + lineHeight: '24px' + }, + offLabelColor: 'rgba(0, 0, 0, 0.38)', + background: { + type: BackgroundType.color, + color: '#fff', + overlay: { + enabled: false, + color: 'rgba(255,255,255,0.72)', + blur: 3 + } + } +}; diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/rpc/rpc-initial-state-settings-panel.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/rpc/rpc-initial-state-settings-panel.component.html new file mode 100644 index 0000000000..e290225f08 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/rpc/rpc-initial-state-settings-panel.component.html @@ -0,0 +1,211 @@ + +
+
widgets.rpc-state.initial-state
+
+
+
{{ 'widgets.rpc-state.action' | translate }}
+ + + + {{ rpcInitialStateTranslationsMap.get(action) | translate }} + + + +
+ + +
+
widgets.rpc-state.value
+ +
+
+ +
+
{{ 'widgets.rpc-state.method' | translate }}*
+ + + + warning + + +
+
+ + +
+
{{ 'widgets.rpc-state.attribute-scope' | translate }}
+ + + + {{ 'attribute.scope-any' | translate }} + + + {{ telemetryTypeTranslationsMap.get(scope) | translate }} + + + +
+
+
{{ 'widgets.rpc-state.attribute-key' | translate }}*
+ + +
+
+
+ + +
+
{{ 'widgets.rpc-state.time-series-key' | translate }}*
+ + +
+
+
+
+
+
+
widgets.rpc-state.action-result-converter
+ + {{ 'widgets.rpc-state.converter-none' | translate }} + {{ 'widgets.rpc-state.converter-function' | translate }} + +
+ + +
+
widgets.rpc-state.on-when-result-is
+ + +
+
+
+ + + + + + widget-config.advanced-settings + + + +
+
{{ 'widgets.rpc-state.request-timeout-ms' | translate }}
+ + + + warning + + +
+
+ + + + + {{ 'widgets.rpc-state.request-persistent' | translate }} + + + + +
+
{{ 'widgets.rpc-state.persistent-polling-interval' | translate }}
+ + + + warning + + +
+
+
+
+
+
+
+
+
+ + +
+
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/rpc/rpc-initial-state-settings-panel.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/rpc/rpc-initial-state-settings-panel.component.ts new file mode 100644 index 0000000000..b9f5f9b602 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/rpc/rpc-initial-state-settings-panel.component.ts @@ -0,0 +1,176 @@ +/// +/// Copyright © 2016-2024 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 { Component, EventEmitter, Input, OnInit, Output, ViewEncapsulation } from '@angular/core'; +import { PageComponent } from '@shared/components/page.component'; +import { TbPopoverComponent } from '@shared/components/popover.component'; +import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms'; +import { Store } from '@ngrx/store'; +import { AppState } from '@core/core.state'; +import { merge } from 'rxjs'; +import { + RpcDataToStateType, + RpcInitialStateAction, + rpcInitialStateActions, + RpcInitialStateSettings, + rpcInitialStateTranslations +} from '@shared/models/rpc-widget-settings.models'; +import { ValueType } from '@shared/models/constants'; +import { TargetDevice } from '@shared/models/widget.models'; +import { AttributeScope, DataKeyType, telemetryTypeTranslationsShort } from '@shared/models/telemetry/telemetry.models'; +import { IAliasController } from '@core/api/widget-api.models'; +import { WidgetService } from '@core/http/widget.service'; + +@Component({ + selector: 'tb-rpc-initial-state-settings-panel', + templateUrl: './rpc-initial-state-settings-panel.component.html', + providers: [], + styleUrls: ['./rpc-state-settings-panel.component.scss'], + encapsulation: ViewEncapsulation.None +}) +export class RpcInitialStateSettingsPanelComponent extends PageComponent implements OnInit { + + @Input() + initialState: RpcInitialStateSettings; + + @Input() + stateValueType: ValueType; + + @Input() + aliasController: IAliasController; + + @Input() + targetDevice: TargetDevice; + + @Input() + popover: TbPopoverComponent; + + @Output() + initialStateSettingsApplied = new EventEmitter>(); + + rpcInitialStateAction = RpcInitialStateAction; + + rpcInitialStateActions = rpcInitialStateActions; + + rpcInitialStateTranslationsMap = rpcInitialStateTranslations; + + telemetryTypeTranslationsMap = telemetryTypeTranslationsShort; + + attributeScopes = Object.keys(AttributeScope) as AttributeScope[]; + + dataKeyType = DataKeyType; + + dataToStateType = RpcDataToStateType; + + functionScopeVariables = this.widgetService.getWidgetScopeVariables(); + + valueType = ValueType; + + initialStateSettingsFormGroup: UntypedFormGroup; + + constructor(private fb: UntypedFormBuilder, + private widgetService: WidgetService, + protected store: Store) { + super(store); + } + + ngOnInit(): void { + this.initialStateSettingsFormGroup = this.fb.group( + { + action: [this.initialState?.action, []], + defaultValue: [this.initialState?.defaultValue, [Validators.required]], + executeRpc: this.fb.group({ + method: [this.initialState?.executeRpc?.method, [Validators.required]], + requestTimeout: [this.initialState?.executeRpc?.requestTimeout, [Validators.required, Validators.min(5000)]], + requestPersistent: [this.initialState?.executeRpc?.requestPersistent, []], + persistentPollingInterval: [this.initialState?.executeRpc?.persistentPollingInterval, [Validators.required, Validators.min(1000)]] + }), + getAttribute: this.fb.group({ + scope: [this.initialState?.getAttribute?.scope, []], + key: [this.initialState?.getAttribute?.key, [Validators.required]], + }), + getTimeSeries: this.fb.group({ + key: [this.initialState?.getTimeSeries?.key, [Validators.required]], + }), + dataToState: this.fb.group({ + type: [this.initialState?.dataToState?.type, [Validators.required]], + dataToStateFunction: [this.initialState?.dataToState?.dataToStateFunction, [Validators.required]], + }), + } + ); + if (this.stateValueType === ValueType.BOOLEAN) { + (this.initialStateSettingsFormGroup.get('dataToState') as UntypedFormGroup).addControl( + 'compareToValue', this.fb.control(this.initialState?.dataToState?.compareToValue, [Validators.required]) + ); + } + + merge(this.initialStateSettingsFormGroup.get('action').valueChanges, + this.initialStateSettingsFormGroup.get('dataToState').get('type').valueChanges, + this.initialStateSettingsFormGroup.get('executeRpc').get('requestPersistent').valueChanges).subscribe(() => { + this.updateValidators(); + }); + this.updateValidators(); + } + + cancel() { + this.popover?.hide(); + } + + applyInitialStateSettings() { + const initialStateSettings: RpcInitialStateSettings = this.initialStateSettingsFormGroup.getRawValue(); + this.initialStateSettingsApplied.emit(initialStateSettings); + } + + private updateValidators() { + const action: RpcInitialStateAction = this.initialStateSettingsFormGroup.get('action').value; + const dataToStateType: RpcDataToStateType = this.initialStateSettingsFormGroup.get('dataToState').get('type').value; + + this.initialStateSettingsFormGroup.get('defaultValue').disable({emitEvent: false}); + this.initialStateSettingsFormGroup.get('executeRpc').disable({emitEvent: false}); + this.initialStateSettingsFormGroup.get('getAttribute').disable({emitEvent: false}); + this.initialStateSettingsFormGroup.get('getTimeSeries').disable({emitEvent: false}); + switch (action) { + case RpcInitialStateAction.DO_NOTHING: + this.initialStateSettingsFormGroup.get('defaultValue').enable({emitEvent: false}); + break; + case RpcInitialStateAction.EXECUTE_RPC: + this.initialStateSettingsFormGroup.get('executeRpc').enable({emitEvent: false}); + const requestPersistent: boolean = this.initialStateSettingsFormGroup.get('executeRpc').get('requestPersistent').value; + if (requestPersistent) { + this.initialStateSettingsFormGroup.get('executeRpc').get('persistentPollingInterval').enable({emitEvent: false}); + } else { + this.initialStateSettingsFormGroup.get('executeRpc').get('persistentPollingInterval').disable({emitEvent: false}); + } + break; + case RpcInitialStateAction.GET_ATTRIBUTE: + this.initialStateSettingsFormGroup.get('getAttribute').enable({emitEvent: false}); + break; + case RpcInitialStateAction.GET_TIME_SERIES: + this.initialStateSettingsFormGroup.get('getTimeSeries').enable({emitEvent: false}); + break; + } + if (action === RpcInitialStateAction.DO_NOTHING) { + this.initialStateSettingsFormGroup.get('dataToState').disable({emitEvent: false}); + } else { + this.initialStateSettingsFormGroup.get('dataToState').enable({emitEvent: false}); + if (dataToStateType === RpcDataToStateType.FUNCTION) { + this.initialStateSettingsFormGroup.get('dataToState').get('dataToStateFunction').enable({emitEvent: false}); + } else { + this.initialStateSettingsFormGroup.get('dataToState').get('dataToStateFunction').disable({emitEvent: false}); + } + } + } +} diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/rpc/rpc-initial-state-settings.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/rpc/rpc-initial-state-settings.component.ts new file mode 100644 index 0000000000..61c053d43c --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/rpc/rpc-initial-state-settings.component.ts @@ -0,0 +1,156 @@ +/// +/// Copyright © 2016-2024 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 { + ChangeDetectorRef, + Component, + forwardRef, + HostBinding, + Input, + OnInit, + Renderer2, + ViewContainerRef, + ViewEncapsulation +} from '@angular/core'; +import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; +import { MatButton } from '@angular/material/button'; +import { TbPopoverService } from '@shared/components/popover.service'; +import { RpcInitialStateAction, RpcInitialStateSettings } from '@shared/models/rpc-widget-settings.models'; +import { TranslateService } from '@ngx-translate/core'; +import { ValueType } from '@shared/models/constants'; +import { + RpcInitialStateSettingsPanelComponent +} from '@home/components/widget/lib/settings/common/rpc/rpc-initial-state-settings-panel.component'; +import { IAliasController } from '@core/api/widget-api.models'; +import { TargetDevice } from '@shared/models/widget.models'; + +@Component({ + selector: 'tb-rpc-initial-state-settings', + templateUrl: './rpc-state-settings-button.component.html', + styleUrls: ['./rpc-state-settings-button.scss'], + providers: [ + { + provide: NG_VALUE_ACCESSOR, + useExisting: forwardRef(() => RpcInitialStateSettingsComponent), + multi: true + } + ], + encapsulation: ViewEncapsulation.None +}) +export class RpcInitialStateSettingsComponent implements OnInit, ControlValueAccessor { + + @HostBinding('style.overflow') + overflow = 'hidden'; + + @Input() + stateValueType: ValueType; + + @Input() + aliasController: IAliasController; + + @Input() + targetDevice: TargetDevice; + + @Input() + disabled = false; + + modelValue: RpcInitialStateSettings; + + displayValue: string; + + private propagateChange = null; + + constructor(private translate: TranslateService, + private popoverService: TbPopoverService, + private renderer: Renderer2, + private viewContainerRef: ViewContainerRef, + private cd: ChangeDetectorRef) {} + + ngOnInit(): void { + } + + registerOnChange(fn: any): void { + this.propagateChange = fn; + } + + registerOnTouched(_fn: any): void { + } + + setDisabledState(isDisabled: boolean): void { + if (this.disabled !== isDisabled) { + this.disabled = isDisabled; + } + } + + writeValue(value: RpcInitialStateSettings): void { + this.modelValue = value; + this.updateDisplayValue(); + } + + openRpcStateSettingsPopup($event: Event, matButton: MatButton) { + if ($event) { + $event.stopPropagation(); + } + const trigger = matButton._elementRef.nativeElement; + if (this.popoverService.hasPopover(trigger)) { + this.popoverService.hidePopover(trigger); + } else { + const ctx: any = { + initialState: this.modelValue, + stateValueType: this.stateValueType, + aliasController: this.aliasController, + targetDevice: this.targetDevice + }; + const initialStateSettingsPanelPopover = this.popoverService.displayPopover(trigger, this.renderer, + this.viewContainerRef, RpcInitialStateSettingsPanelComponent, + ['leftTopOnly', 'leftOnly', 'leftBottomOnly'], true, null, + ctx, + {}, + {}, {}, true); + initialStateSettingsPanelPopover.tbComponentRef.instance.popover = initialStateSettingsPanelPopover; + initialStateSettingsPanelPopover.tbComponentRef.instance.initialStateSettingsApplied.subscribe((initialState) => { + initialStateSettingsPanelPopover.hide(); + this.modelValue = initialState; + this.updateDisplayValue(); + this.propagateChange(this.modelValue); + }); + } + } + + private updateDisplayValue() { + switch (this.modelValue.action) { + case RpcInitialStateAction.DO_NOTHING: + if (this.stateValueType === ValueType.BOOLEAN) { + this.displayValue = this.translate.instant(!!this.modelValue.defaultValue ? 'widgets.rpc-state.on' : 'widgets.rpc-state.off'); + } else { + this.displayValue = this.modelValue.defaultValue + ''; + } + break; + case RpcInitialStateAction.EXECUTE_RPC: + const methodName = this.modelValue.executeRpc.method; + this.displayValue = this.translate.instant('widgets.rpc-state.execute-rpc-text', {methodName}); + break; + case RpcInitialStateAction.GET_ATTRIBUTE: + this.displayValue = this.translate.instant('widgets.rpc-state.get-attribute-text', {key: this.modelValue.getAttribute.key}); + break; + case RpcInitialStateAction.GET_TIME_SERIES: + this.displayValue = this.translate.instant('widgets.rpc-state.get-time-series-text', {key: this.modelValue.getTimeSeries.key}); + break; + } + this.cd.markForCheck(); + } + +} diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/rpc/rpc-state-settings-button.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/rpc/rpc-state-settings-button.component.html new file mode 100644 index 0000000000..da24002e31 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/rpc/rpc-state-settings-button.component.html @@ -0,0 +1,26 @@ + + diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/rpc/rpc-state-settings-button.scss b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/rpc/rpc-state-settings-button.scss new file mode 100644 index 0000000000..1a6d454152 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/rpc/rpc-state-settings-button.scss @@ -0,0 +1,34 @@ +/** + * Copyright © 2016-2024 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. + */ +.mdc-button.tb-rpc-state-settings { + width: 100%; + .mdc-button__label { + width: 100%; + & > div { + width: 100%; + display: flex; + flex-direction: row; + gap: 8px; + justify-content: space-between; + align-items: center; + & > span { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } + } + } +} diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/rpc/rpc-state-settings-panel.component.scss b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/rpc/rpc-state-settings-panel.component.scss new file mode 100644 index 0000000000..e2ffae2c84 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/rpc/rpc-state-settings-panel.component.scss @@ -0,0 +1,47 @@ +/** + * Copyright © 2016-2024 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 '../../../../../../../../../scss/constants'; + +.tb-rpc-state-settings-panel { + width: 530px; + display: flex; + flex-direction: column; + gap: 16px; + @media #{$mat-lt-md} { + width: 90vw; + } + .tb-rpc-state-settings-panel-content { + display: flex; + flex-direction: column; + gap: 16px; + overflow: auto; + } + .tb-rpc-state-settings-title { + font-size: 16px; + font-weight: 500; + line-height: 24px; + letter-spacing: 0.25px; + color: rgba(0, 0, 0, 0.87); + } + .tb-rpc-state-settings-panel-buttons { + height: 40px; + display: flex; + flex-direction: row; + gap: 16px; + justify-content: flex-end; + align-items: flex-end; + } +} diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/rpc/rpc-update-state-settings-panel.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/rpc/rpc-update-state-settings-panel.component.html new file mode 100644 index 0000000000..ad70579d1c --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/rpc/rpc-update-state-settings-panel.component.html @@ -0,0 +1,201 @@ + +
+
{{ panelTitle | translate }}
+
+
+
{{ 'widgets.rpc-state.action' | translate }}
+ + + + {{ rpcUpdateStateTranslationsMap.get(action) | translate }} + + + +
+ + +
+
{{ 'widgets.rpc-state.method' | translate }}*
+ + + + warning + + +
+
+ + +
+
{{ 'widgets.rpc-state.attribute-scope' | translate }}
+ + + + {{ telemetryTypeTranslationsMap.get(scope) | translate }} + + + +
+
+
{{ 'widgets.rpc-state.attribute-key' | translate }}*
+ + +
+
+
+ + +
+
{{ 'widgets.rpc-state.time-series-key' | translate }}*
+ + +
+
+
+
+
+
+
{{ (updateStateSettingsFormGroup.get('action').value === rpcUpdateStateAction.EXECUTE_RPC ? + 'widgets.rpc-state.parameters' : 'widgets.rpc-state.value') | translate }}
+ + {{ 'widgets.rpc-state.converter-constant' | translate }} + {{ 'widgets.rpc-state.converter-function' | translate }} + {{ 'widgets.rpc-state.converter-none' | translate }} + +
+ + + + +
+
+ + + + + + widget-config.advanced-settings + + + +
+
{{ 'widgets.rpc-state.request-timeout-ms' | translate }}
+ + + + warning + + +
+
+ + + + + {{ 'widgets.rpc-state.request-persistent' | translate }} + + + + +
+
{{ 'widgets.rpc-state.persistent-polling-interval' | translate }}
+ + + + warning + + +
+
+
+
+
+
+
+
+
+ + +
+
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/rpc/rpc-update-state-settings-panel.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/rpc/rpc-update-state-settings-panel.component.ts new file mode 100644 index 0000000000..78c5c6f44b --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/rpc/rpc-update-state-settings-panel.component.ts @@ -0,0 +1,180 @@ +/// +/// Copyright © 2016-2024 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 { Component, EventEmitter, Input, OnInit, Output, ViewEncapsulation } from '@angular/core'; +import { PageComponent } from '@shared/components/page.component'; +import { TbPopoverComponent } from '@shared/components/popover.component'; +import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms'; +import { Store } from '@ngrx/store'; +import { AppState } from '@core/core.state'; +import { merge } from 'rxjs'; +import { + RpcStateToParamsType, + RpcUpdateStateAction, + rpcUpdateStateActions, + RpcUpdateStateSettings, + rpcUpdateStateTranslations +} from '@shared/models/rpc-widget-settings.models'; +import { ValueType } from '@shared/models/constants'; +import { TargetDevice } from '@shared/models/widget.models'; +import { AttributeScope, DataKeyType, telemetryTypeTranslationsShort } from '@shared/models/telemetry/telemetry.models'; +import { IAliasController } from '@core/api/widget-api.models'; +import { WidgetService } from '@core/http/widget.service'; + +@Component({ + selector: 'tb-rpc-update-state-settings-panel', + templateUrl: './rpc-update-state-settings-panel.component.html', + providers: [], + styleUrls: ['./rpc-state-settings-panel.component.scss'], + encapsulation: ViewEncapsulation.None +}) +export class RpcUpdateStateSettingsPanelComponent extends PageComponent implements OnInit { + + @Input() + panelTitle: string; + + @Input() + updateState: RpcUpdateStateSettings; + + @Input() + stateValueType: ValueType; + + @Input() + aliasController: IAliasController; + + @Input() + targetDevice: TargetDevice; + + @Input() + popover: TbPopoverComponent; + + @Output() + updateStateSettingsApplied = new EventEmitter(); + + rpcUpdateStateAction = RpcUpdateStateAction; + + rpcUpdateStateActions = rpcUpdateStateActions; + + rpcUpdateStateTranslationsMap = rpcUpdateStateTranslations; + + telemetryTypeTranslationsMap = telemetryTypeTranslationsShort; + + attributeScopes = [AttributeScope.SERVER_SCOPE, AttributeScope.SHARED_SCOPE]; + + dataKeyType = DataKeyType; + + stateToParamsType = RpcStateToParamsType; + + functionScopeVariables = this.widgetService.getWidgetScopeVariables(); + + valueType = ValueType; + + updateStateSettingsFormGroup: UntypedFormGroup; + + constructor(private fb: UntypedFormBuilder, + private widgetService: WidgetService, + protected store: Store) { + super(store); + } + + ngOnInit(): void { + this.updateStateSettingsFormGroup = this.fb.group( + { + action: [this.updateState?.action, []], + executeRpc: this.fb.group({ + method: [this.updateState?.executeRpc?.method, [Validators.required]], + requestTimeout: [this.updateState?.executeRpc?.requestTimeout, [Validators.required, Validators.min(5000)]], + requestPersistent: [this.updateState?.executeRpc?.requestPersistent, []], + persistentPollingInterval: [this.updateState?.executeRpc?.persistentPollingInterval, [Validators.required, Validators.min(1000)]] + }), + setAttribute: this.fb.group({ + scope: [this.updateState?.setAttribute?.scope, []], + key: [this.updateState?.setAttribute?.key, [Validators.required]], + }), + putTimeSeries: this.fb.group({ + key: [this.updateState?.putTimeSeries?.key, [Validators.required]], + }), + stateToParams: this.fb.group({ + type: [this.updateState?.stateToParams?.type, [Validators.required]], + constantValue: [this.updateState?.stateToParams?.constantValue, [Validators.required]], + stateToParamsFunction: [this.updateState?.stateToParams?.stateToParamsFunction, [Validators.required]], + }), + } + ); + + merge(this.updateStateSettingsFormGroup.get('action').valueChanges, + this.updateStateSettingsFormGroup.get('stateToParams').get('type').valueChanges, + this.updateStateSettingsFormGroup.get('executeRpc').get('requestPersistent').valueChanges).subscribe(() => { + this.updateValidators(); + }); + this.updateValidators(); + } + + cancel() { + this.popover?.hide(); + } + + applyUpdateStateSettings() { + const updateStateSettings: RpcUpdateStateSettings = this.updateStateSettingsFormGroup.getRawValue(); + this.updateStateSettingsApplied.emit(updateStateSettings); + } + + private updateValidators() { + const action: RpcUpdateStateAction = this.updateStateSettingsFormGroup.get('action').value; + let stateToParamsType: RpcStateToParamsType = this.updateStateSettingsFormGroup.get('stateToParams').get('type').value; + + this.updateStateSettingsFormGroup.get('executeRpc').disable({emitEvent: false}); + this.updateStateSettingsFormGroup.get('setAttribute').disable({emitEvent: false}); + this.updateStateSettingsFormGroup.get('putTimeSeries').disable({emitEvent: false}); + switch (action) { + case RpcUpdateStateAction.EXECUTE_RPC: + this.updateStateSettingsFormGroup.get('executeRpc').enable({emitEvent: false}); + const requestPersistent: boolean = this.updateStateSettingsFormGroup.get('executeRpc').get('requestPersistent').value; + if (requestPersistent) { + this.updateStateSettingsFormGroup.get('executeRpc').get('persistentPollingInterval').enable({emitEvent: false}); + } else { + this.updateStateSettingsFormGroup.get('executeRpc').get('persistentPollingInterval').disable({emitEvent: false}); + } + break; + case RpcUpdateStateAction.SET_ATTRIBUTE: + case RpcUpdateStateAction.ADD_TIME_SERIES: + if (stateToParamsType === RpcStateToParamsType.NONE) { + stateToParamsType = RpcStateToParamsType.CONSTANT; + this.updateStateSettingsFormGroup.get('stateToParams').get('type').patchValue(stateToParamsType, {emitEvent: false}); + } + if (action === RpcUpdateStateAction.SET_ATTRIBUTE) { + this.updateStateSettingsFormGroup.get('setAttribute').enable({emitEvent: false}); + } else { + this.updateStateSettingsFormGroup.get('putTimeSeries').enable({emitEvent: false}); + } + break; + } + switch (stateToParamsType) { + case RpcStateToParamsType.CONSTANT: + this.updateStateSettingsFormGroup.get('stateToParams').get('constantValue').enable({emitEvent: false}); + this.updateStateSettingsFormGroup.get('stateToParams').get('stateToParamsFunction').disable({emitEvent: false}); + break; + case RpcStateToParamsType.FUNCTION: + this.updateStateSettingsFormGroup.get('stateToParams').get('constantValue').disable({emitEvent: false}); + this.updateStateSettingsFormGroup.get('stateToParams').get('stateToParamsFunction').enable({emitEvent: false}); + break; + case RpcStateToParamsType.NONE: + this.updateStateSettingsFormGroup.get('stateToParams').get('constantValue').disable({emitEvent: false}); + this.updateStateSettingsFormGroup.get('stateToParams').get('stateToParamsFunction').disable({emitEvent: false}); + break; + } + } +} diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/rpc/rpc-update-state-settings.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/rpc/rpc-update-state-settings.component.ts new file mode 100644 index 0000000000..8a65861783 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/rpc/rpc-update-state-settings.component.ts @@ -0,0 +1,174 @@ +/// +/// Copyright © 2016-2024 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 { + ChangeDetectorRef, + Component, + forwardRef, + HostBinding, + Input, + OnInit, + Renderer2, + ViewContainerRef, + ViewEncapsulation +} from '@angular/core'; +import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; +import { MatButton } from '@angular/material/button'; +import { TbPopoverService } from '@shared/components/popover.service'; +import { + RpcStateToParamsType, + RpcUpdateStateAction, + RpcUpdateStateSettings +} from '@shared/models/rpc-widget-settings.models'; +import { TranslateService } from '@ngx-translate/core'; +import { ValueType } from '@shared/models/constants'; +import { IAliasController } from '@core/api/widget-api.models'; +import { TargetDevice } from '@shared/models/widget.models'; +import { isDefinedAndNotNull } from '@core/utils'; +import { + RpcUpdateStateSettingsPanelComponent +} from '@home/components/widget/lib/settings/common/rpc/rpc-update-state-settings-panel.component'; + +@Component({ + selector: 'tb-rpc-update-state-settings', + templateUrl: './rpc-state-settings-button.component.html', + styleUrls: ['./rpc-state-settings-button.scss'], + providers: [ + { + provide: NG_VALUE_ACCESSOR, + useExisting: forwardRef(() => RpcUpdateStateSettingsComponent), + multi: true + } + ], + encapsulation: ViewEncapsulation.None +}) +export class RpcUpdateStateSettingsComponent implements OnInit, ControlValueAccessor { + + @HostBinding('style.overflow') + overflow = 'hidden'; + + @Input() + panelTitle: string; + + @Input() + stateValueType: ValueType; + + @Input() + aliasController: IAliasController; + + @Input() + targetDevice: TargetDevice; + + @Input() + disabled = false; + + modelValue: RpcUpdateStateSettings; + + displayValue: string; + + private propagateChange = null; + + constructor(private translate: TranslateService, + private popoverService: TbPopoverService, + private renderer: Renderer2, + private viewContainerRef: ViewContainerRef, + private cd: ChangeDetectorRef) {} + + ngOnInit(): void { + } + + registerOnChange(fn: any): void { + this.propagateChange = fn; + } + + registerOnTouched(_fn: any): void { + } + + setDisabledState(isDisabled: boolean): void { + if (this.disabled !== isDisabled) { + this.disabled = isDisabled; + } + } + + writeValue(value: RpcUpdateStateSettings): void { + this.modelValue = value; + this.updateDisplayValue(); + } + + openRpcStateSettingsPopup($event: Event, matButton: MatButton) { + if ($event) { + $event.stopPropagation(); + } + const trigger = matButton._elementRef.nativeElement; + if (this.popoverService.hasPopover(trigger)) { + this.popoverService.hidePopover(trigger); + } else { + const ctx: any = { + updateState: this.modelValue, + panelTitle: this.panelTitle, + stateValueType: this.stateValueType, + aliasController: this.aliasController, + targetDevice: this.targetDevice + }; + const updateStateSettingsPanelPopover = this.popoverService.displayPopover(trigger, this.renderer, + this.viewContainerRef, RpcUpdateStateSettingsPanelComponent, + ['leftTopOnly', 'leftOnly', 'leftBottomOnly'], true, null, + ctx, + {}, + {}, {}, true); + updateStateSettingsPanelPopover.tbComponentRef.instance.popover = updateStateSettingsPanelPopover; + updateStateSettingsPanelPopover.tbComponentRef.instance.updateStateSettingsApplied.subscribe((updateState) => { + updateStateSettingsPanelPopover.hide(); + this.modelValue = updateState; + this.updateDisplayValue(); + this.propagateChange(this.modelValue); + }); + } + } + + private updateDisplayValue() { + let value: any; + switch (this.modelValue.stateToParams.type) { + case RpcStateToParamsType.CONSTANT: + value = this.modelValue.stateToParams.constantValue; + break; + case RpcStateToParamsType.FUNCTION: + value = 'f(value)'; + break; + case RpcStateToParamsType.NONE: + break; + } + switch (this.modelValue.action) { + case RpcUpdateStateAction.EXECUTE_RPC: + let methodName = this.modelValue.executeRpc.method; + if (isDefinedAndNotNull(value)) { + methodName = `${methodName}(${value})`; + } + this.displayValue = this.translate.instant('widgets.rpc-state.execute-rpc-text', {methodName}); + break; + case RpcUpdateStateAction.SET_ATTRIBUTE: + this.displayValue = this.translate.instant('widgets.rpc-state.set-attribute-to-value-text', + {key: this.modelValue.setAttribute.key, value}); + break; + case RpcUpdateStateAction.ADD_TIME_SERIES: + this.displayValue = this.translate.instant('widgets.rpc-state.add-time-series-value-text', + {key: this.modelValue.setAttribute.key, value}); + break; + } + this.cd.markForCheck(); + } + +} diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/widget-settings-common.module.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/widget-settings-common.module.ts index 5eb9d598ff..ba08a39bb7 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/widget-settings-common.module.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/widget-settings-common.module.ts @@ -51,6 +51,21 @@ import { ColorRangePanelComponent } from '@home/components/widget/lib/settings/c import { ColorRangeSettingsComponent, ColorRangeSettingsComponentService } from '@home/components/widget/lib/settings/common/color-range-settings.component'; +import { + RpcInitialStateSettingsComponent +} from '@home/components/widget/lib/settings/common/rpc/rpc-initial-state-settings.component'; +import { + RpcInitialStateSettingsPanelComponent +} from '@home/components/widget/lib/settings/common/rpc/rpc-initial-state-settings-panel.component'; +import { + DeviceKeyAutocompleteComponent +} from '@home/components/widget/lib/settings/control/device-key-autocomplete.component'; +import { + RpcUpdateStateSettingsComponent +} from '@home/components/widget/lib/settings/common/rpc/rpc-update-state-settings.component'; +import { + RpcUpdateStateSettingsPanelComponent +} from '@home/components/widget/lib/settings/common/rpc/rpc-update-state-settings-panel.component'; @NgModule({ declarations: [ @@ -71,7 +86,12 @@ import { CountWidgetSettingsComponent, ColorRangeListComponent, ColorRangePanelComponent, - ColorRangeSettingsComponent + ColorRangeSettingsComponent, + RpcInitialStateSettingsComponent, + RpcInitialStateSettingsPanelComponent, + DeviceKeyAutocompleteComponent, + RpcUpdateStateSettingsComponent, + RpcUpdateStateSettingsPanelComponent ], imports: [ CommonModule, @@ -96,7 +116,12 @@ import { CountWidgetSettingsComponent, ColorRangeListComponent, ColorRangePanelComponent, - ColorRangeSettingsComponent + ColorRangeSettingsComponent, + RpcInitialStateSettingsComponent, + RpcInitialStateSettingsPanelComponent, + DeviceKeyAutocompleteComponent, + RpcUpdateStateSettingsComponent, + RpcUpdateStateSettingsPanelComponent ], providers: [ ColorSettingsComponentService, diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/device-key-autocomplete.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/device-key-autocomplete.component.html index 5a2d11d3a5..977a493c5f 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/device-key-autocomplete.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/device-key-autocomplete.component.html @@ -15,8 +15,13 @@ limitations under the License. --> - - {{ (keyType === dataKeyType.attribute + + {{ (keyType === dataKeyType.attribute ? attributeLabel : timeseriesLabel) | translate }} close + + warning + @@ -38,4 +52,7 @@ + + {{ requiredText | translate }} + diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/device-key-autocomplete.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/device-key-autocomplete.component.ts index 6255fa6e48..9c0691faed 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/device-key-autocomplete.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/device-key-autocomplete.component.ts @@ -25,15 +25,17 @@ import { import { PageComponent } from '@shared/components/page.component'; import { Store } from '@ngrx/store'; import { AppState } from '@core/core.state'; -import { TranslateService } from '@ngx-translate/core'; -import { DataKeyType } from '@shared/models/telemetry/telemetry.models'; +import { AttributeScope, DataKeyType } from '@shared/models/telemetry/telemetry.models'; import { Observable, of } from 'rxjs'; import { IAliasController } from '@core/api/widget-api.models'; import { catchError, map, mergeMap, publishReplay, refCount, tap } from 'rxjs/operators'; -import { DataKey } from '@shared/models/widget.models'; +import { DataKey, TargetDevice, TargetDeviceType, targetDeviceValid } from '@shared/models/widget.models'; import { EntityService } from '@core/http/entity.service'; import { coerceBooleanProperty } from '@angular/cdk/coercion'; import { EntityType } from '@shared/models/entity-type.models'; +import { EntityFilter, singleEntityFilterFromDeviceId } from '@shared/models/query/query.models'; +import { AliasFilterType } from '@shared/models/alias.models'; +import { coerceBoolean } from '@shared/decorators/coercion'; @Component({ selector: 'tb-device-key-autocomplete', @@ -58,25 +60,30 @@ export class DeviceKeyAutocompleteComponent extends PageComponent implements OnI aliasController: IAliasController; @Input() - targetDeviceAliasId: string; + targetDevice: TargetDevice; @Input() keyType: DataKeyType; + @Input() + attributeScope: AttributeScope; + @Input() attributeLabel = 'widgets.rpc.attribute-value-key'; @Input() timeseriesLabel = 'widgets.rpc.timeseries-value-key'; - private requiredValue: boolean; - get required(): boolean { - return this.requiredValue; - } @Input() - set required(value: boolean) { - this.requiredValue = coerceBooleanProperty(value); - } + requiredText: string; + + @Input() + @coerceBoolean() + required: boolean; + + @Input() + @coerceBoolean() + inlineField: boolean; dataKeyType = DataKeyType; @@ -93,7 +100,6 @@ export class DeviceKeyAutocompleteComponent extends PageComponent implements OnI private keysFetchObservable$: Observable> = null; constructor(protected store: Store, - private translate: TranslateService, private entityService: EntityService, private fb: UntypedFormBuilder) { super(store); @@ -118,7 +124,7 @@ export class DeviceKeyAutocompleteComponent extends PageComponent implements OnI for (const propName of Object.keys(changes)) { const change = changes[propName]; if (!change.firstChange && change.currentValue !== change.previousValue) { - if (propName === 'targetDeviceAliasId' || propName === 'keyType') { + if (propName === 'targetDevice' || propName === 'keyType' || propName === 'attributeScope') { this.clearKeysCache(); } } @@ -186,9 +192,9 @@ export class DeviceKeyAutocompleteComponent extends PageComponent implements OnI private getKeys() { if (this.keysFetchObservable$ === null) { let fetchObservable: Observable>; - if (this.targetDeviceAliasId) { + if (targetDeviceValid(this.targetDevice)) { const dataKeyTypes = [this.keyType]; - fetchObservable = this.fetchEntityKeys(this.targetDeviceAliasId, dataKeyTypes); + fetchObservable = this.fetchEntityKeys(this.targetDevice, dataKeyTypes); } else { fetchObservable = of([]); } @@ -201,17 +207,25 @@ export class DeviceKeyAutocompleteComponent extends PageComponent implements OnI return this.keysFetchObservable$; } - private fetchEntityKeys(entityAliasId: string, dataKeyTypes: Array): Observable> { - return this.aliasController.getAliasInfo(entityAliasId).pipe( - mergeMap((aliasInfo) => { - return this.entityService.getEntityKeysByEntityFilter( - aliasInfo.entityFilter, + private fetchEntityKeys(targetDevice: TargetDevice, dataKeyTypes: Array): Observable> { + let entityFilter$: Observable; + if (targetDevice.type === TargetDeviceType.device) { + entityFilter$ = of(singleEntityFilterFromDeviceId(targetDevice.deviceId)); + } else { + entityFilter$ = this.aliasController.getAliasInfo(targetDevice.entityAliasId).pipe( + map(aliasInfo => aliasInfo.entityFilter) + ); + } + return entityFilter$.pipe( + mergeMap((entityFilter) => + this.entityService.getEntityKeysByEntityFilterAndScope( + entityFilter, dataKeyTypes, [EntityType.DEVICE], + this.attributeScope, {ignoreLoading: true, ignoreErrors: true} ).pipe( catchError(() => of([])) - ); - }), + )), catchError(() => of([] as Array)) ); } diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/led-indicator-widget-settings.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/led-indicator-widget-settings.component.html index 669c9a2fce..fa66dd6be1 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/led-indicator-widget-settings.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/led-indicator-widget-settings.component.html @@ -52,7 +52,7 @@ diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/round-switch-widget-settings.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/round-switch-widget-settings.component.ts index f4c570bf4e..8bf58a9b22 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/round-switch-widget-settings.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/round-switch-widget-settings.component.ts @@ -15,7 +15,7 @@ /// import { Component } from '@angular/core'; -import { WidgetSettings, WidgetSettingsComponent } from '@shared/models/widget.models'; +import { TargetDevice, WidgetSettings, WidgetSettingsComponent } from '@shared/models/widget.models'; import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms'; import { Store } from '@ngrx/store'; import { AppState } from '@core/core.state'; @@ -36,12 +36,8 @@ export class RoundSwitchWidgetSettingsComponent extends WidgetSettingsComponent super(store); } - get targetDeviceAliasId(): string { - const aliasIds = this.widget?.config?.targetDeviceAliasIds; - if (aliasIds && aliasIds.length) { - return aliasIds[0]; - } - return null; + get targetDevice(): TargetDevice { + return this.widget?.config?.targetDevice; } protected settingsForm(): UntypedFormGroup { diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/single-switch-widget-settings.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/single-switch-widget-settings.component.html new file mode 100644 index 0000000000..1006d65f55 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/single-switch-widget-settings.component.html @@ -0,0 +1,198 @@ + + +
+
widgets.single-switch.behavior
+
+
widgets.rpc-state.initial-state
+ +
+
+
widgets.rpc-state.turn-on
+ +
+
+
widgets.rpc-state.turn-off
+ +
+
+
+
widget-config.card-style
+ + + {{ singleSwitchLayoutTranslationMap.get(layout) | translate }} + + +
+ + {{ 'widgets.single-switch.auto-scale' | translate }} + +
+
+ + {{ 'widgets.single-switch.label' | translate }} + +
+ + + + + + + +
+
+
+ + {{ 'widgets.single-switch.icon' | translate }} + +
+ + + + + + + + +
+
+
+
{{ 'widgets.background.background' | translate }}
+ + +
+
+
+
widgets.single-switch.switch
+
+
{{ 'widgets.single-switch.switch-color' | translate }}
+
+
+
widgets.single-switch.on
+ + +
+ +
+
widgets.single-switch.off
+ + +
+ +
+
widgets.single-switch.disabled
+ + +
+
+
+
+
{{ 'widgets.single-switch.tumbler-color' | translate }}
+
+
+
widgets.single-switch.on
+ + +
+ +
+
widgets.single-switch.off
+ + +
+ +
+
widgets.single-switch.disabled
+ + +
+
+
+
+ + {{ 'widgets.single-switch.on-label' | translate }} + +
+ + + + + + + +
+
+
+ + {{ 'widgets.single-switch.off-label' | translate }} + +
+ + + + + + + +
+
+
+
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/single-switch-widget-settings.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/single-switch-widget-settings.component.ts new file mode 100644 index 0000000000..7e4f1d1d96 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/single-switch-widget-settings.component.ts @@ -0,0 +1,157 @@ +/// +/// Copyright © 2016-2024 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 { Component } from '@angular/core'; +import { TargetDevice, WidgetSettings, WidgetSettingsComponent } from '@shared/models/widget.models'; +import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms'; +import { Store } from '@ngrx/store'; +import { AppState } from '@core/core.state'; +import { + singleSwitchDefaultSettings, singleSwitchLayoutImages, + singleSwitchLayouts, + singleSwitchLayoutTranslations +} from '@home/components/widget/lib/rpc/single-switch-widget.models'; +import { ValueType } from '@shared/models/constants'; + +@Component({ + selector: 'tb-single-switch-widget-settings', + templateUrl: './single-switch-widget-settings.component.html', + styleUrls: ['./../widget-settings.scss'] +}) +export class SingleSwitchWidgetSettingsComponent extends WidgetSettingsComponent { + + get targetDevice(): TargetDevice { + return this.widget?.config?.targetDevice; + } + + singleSwitchLayouts = singleSwitchLayouts; + + singleSwitchLayoutTranslationMap = singleSwitchLayoutTranslations; + singleSwitchLayoutImageMap = singleSwitchLayoutImages; + + valueType = ValueType; + + singleSwitchWidgetSettingsForm: UntypedFormGroup; + + constructor(protected store: Store, + private fb: UntypedFormBuilder) { + super(store); + } + + protected settingsForm(): UntypedFormGroup { + return this.singleSwitchWidgetSettingsForm; + } + + protected defaultSettings(): WidgetSettings { + return {...singleSwitchDefaultSettings}; + } + + protected onSettingsSet(settings: WidgetSettings) { + this.singleSwitchWidgetSettingsForm = this.fb.group({ + initialState: [settings.initialState, []], + onUpdateState: [settings.onUpdateState, []], + offUpdateState: [settings.offUpdateState, []], + layout: [settings.layout, []], + autoScale: [settings.autoScale, []], + + showLabel: [settings.showLabel, []], + label: [settings.label, []], + labelFont: [settings.labelFont, []], + labelColor: [settings.labelColor, []], + + showIcon: [settings.showIcon, []], + iconSize: [settings.iconSize, [Validators.min(0)]], + iconSizeUnit: [settings.iconSizeUnit, []], + icon: [settings.icon, []], + iconColor: [settings.iconColor, []], + + switchColorOn: [settings.switchColorOn, []], + switchColorOff: [settings.switchColorOff, []], + switchColorDisabled: [settings.switchColorDisabled, []], + + tumblerColorOn: [settings.tumblerColorOn, []], + tumblerColorOff: [settings.tumblerColorOff, []], + tumblerColorDisabled: [settings.tumblerColorDisabled, []], + + showOnLabel: [settings.showOnLabel, []], + onLabel: [settings.onLabel, []], + onLabelFont: [settings.onLabelFont, []], + onLabelColor: [settings.onLabelColor, []], + + showOffLabel: [settings.showOffLabel, []], + offLabel: [settings.offLabel, []], + offLabelFont: [settings.offLabelFont, []], + offLabelColor: [settings.offLabelColor, []], + + background: [settings.background, []] + }); + } + + protected validatorTriggers(): string[] { + return ['showLabel', 'showIcon', 'showOnLabel', 'showOffLabel']; + } + + protected updateValidators(emitEvent: boolean): void { + const showLabel: boolean = this.singleSwitchWidgetSettingsForm.get('showLabel').value; + const showIcon: boolean = this.singleSwitchWidgetSettingsForm.get('showIcon').value; + const showOnLabel: boolean = this.singleSwitchWidgetSettingsForm.get('showOnLabel').value; + const showOffLabel: boolean = this.singleSwitchWidgetSettingsForm.get('showOffLabel').value; + + if (showLabel) { + this.singleSwitchWidgetSettingsForm.get('label').enable(); + this.singleSwitchWidgetSettingsForm.get('labelFont').enable(); + this.singleSwitchWidgetSettingsForm.get('labelColor').enable(); + } else { + this.singleSwitchWidgetSettingsForm.get('label').disable(); + this.singleSwitchWidgetSettingsForm.get('labelFont').disable(); + this.singleSwitchWidgetSettingsForm.get('labelColor').disable(); + } + + if (showIcon) { + this.singleSwitchWidgetSettingsForm.get('iconSize').enable(); + this.singleSwitchWidgetSettingsForm.get('iconSizeUnit').enable(); + this.singleSwitchWidgetSettingsForm.get('icon').enable(); + this.singleSwitchWidgetSettingsForm.get('iconColor').enable(); + } else { + this.singleSwitchWidgetSettingsForm.get('iconSize').disable(); + this.singleSwitchWidgetSettingsForm.get('iconSizeUnit').disable(); + this.singleSwitchWidgetSettingsForm.get('icon').disable(); + this.singleSwitchWidgetSettingsForm.get('iconColor').disable(); + } + + if (showOnLabel) { + this.singleSwitchWidgetSettingsForm.get('onLabel').enable(); + this.singleSwitchWidgetSettingsForm.get('onLabelFont').enable(); + this.singleSwitchWidgetSettingsForm.get('onLabelColor').enable(); + } else { + this.singleSwitchWidgetSettingsForm.get('onLabel').disable(); + this.singleSwitchWidgetSettingsForm.get('onLabelFont').disable(); + this.singleSwitchWidgetSettingsForm.get('onLabelColor').disable(); + } + + if (showOffLabel) { + this.singleSwitchWidgetSettingsForm.get('offLabel').enable(); + this.singleSwitchWidgetSettingsForm.get('offLabelFont').enable(); + this.singleSwitchWidgetSettingsForm.get('offLabelColor').enable(); + } else { + this.singleSwitchWidgetSettingsForm.get('offLabel').disable(); + this.singleSwitchWidgetSettingsForm.get('offLabelFont').disable(); + this.singleSwitchWidgetSettingsForm.get('offLabelColor').disable(); + } + } + + protected readonly ValueType = ValueType; +} diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/slide-toggle-widget-settings.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/slide-toggle-widget-settings.component.html index 31a9cc25be..1bf741eba7 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/slide-toggle-widget-settings.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/slide-toggle-widget-settings.component.html @@ -51,7 +51,7 @@ diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/slide-toggle-widget-settings.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/slide-toggle-widget-settings.component.ts index 95f8018db9..d14d0fd594 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/slide-toggle-widget-settings.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/slide-toggle-widget-settings.component.ts @@ -15,7 +15,7 @@ /// import { Component } from '@angular/core'; -import { WidgetSettings, WidgetSettingsComponent } from '@shared/models/widget.models'; +import { TargetDevice, WidgetSettings, WidgetSettingsComponent } from '@shared/models/widget.models'; import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms'; import { Store } from '@ngrx/store'; import { AppState } from '@core/core.state'; @@ -36,12 +36,8 @@ export class SlideToggleWidgetSettingsComponent extends WidgetSettingsComponent super(store); } - get targetDeviceAliasId(): string { - const aliasIds = this.widget?.config?.targetDeviceAliasIds; - if (aliasIds && aliasIds.length) { - return aliasIds[0]; - } - return null; + get targetDevice(): TargetDevice { + return this.widget?.config?.targetDevice; } protected settingsForm(): UntypedFormGroup { diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/switch-control-widget-settings.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/switch-control-widget-settings.component.html index 931f077015..f50ec5c903 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/switch-control-widget-settings.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/switch-control-widget-settings.component.html @@ -27,7 +27,7 @@ diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/switch-control-widget-settings.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/switch-control-widget-settings.component.ts index 9e9c46429b..197fc2d229 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/switch-control-widget-settings.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/switch-control-widget-settings.component.ts @@ -15,7 +15,7 @@ /// import { Component } from '@angular/core'; -import { WidgetSettings, WidgetSettingsComponent } from '@shared/models/widget.models'; +import { TargetDevice, WidgetSettings, WidgetSettingsComponent } from '@shared/models/widget.models'; import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms'; import { Store } from '@ngrx/store'; import { AppState } from '@core/core.state'; @@ -36,12 +36,8 @@ export class SwitchControlWidgetSettingsComponent extends WidgetSettingsComponen super(store); } - get targetDeviceAliasId(): string { - const aliasIds = this.widget?.config?.targetDeviceAliasIds; - if (aliasIds && aliasIds.length) { - return aliasIds[0]; - } - return null; + get targetDevice(): TargetDevice { + return this.widget?.config?.targetDevice; } protected settingsForm(): UntypedFormGroup { diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/switch-rpc-settings.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/switch-rpc-settings.component.html index c1d6e4d2c5..12a722c77a 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/switch-rpc-settings.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/switch-rpc-settings.component.html @@ -44,7 +44,7 @@ [fxShow]="switchRpcSettingsFormGroup.get('retrieveValueMethod').value === 'attribute' || switchRpcSettingsFormGroup.get('retrieveValueMethod').value === 'timeseries'" [aliasController]="aliasController" - [targetDeviceAliasId]="targetDeviceAliasId" + [targetDevice]="targetDevice" [keyType]="switchRpcSettingsFormGroup.get('retrieveValueMethod').value === 'attribute' ? dataKeyType.attribute : dataKeyType.timeseries" required formControlName="valueKey"> diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/switch-rpc-settings.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/switch-rpc-settings.component.ts index c069774f8e..764bfcfce9 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/switch-rpc-settings.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/switch-rpc-settings.component.ts @@ -17,11 +17,11 @@ import { Component, ElementRef, forwardRef, Input, OnInit, ViewChild } from '@angular/core'; import { ControlValueAccessor, + NG_VALIDATORS, + NG_VALUE_ACCESSOR, UntypedFormBuilder, UntypedFormControl, UntypedFormGroup, - NG_VALIDATORS, - NG_VALUE_ACCESSOR, Validator, Validators } from '@angular/forms'; @@ -33,6 +33,7 @@ import { DataKeyType } from '@shared/models/telemetry/telemetry.models'; import { WidgetService } from '@core/http/widget.service'; import { IAliasController } from '@core/api/widget-api.models'; import { EntityService } from '@core/http/entity.service'; +import { TargetDevice } from '@shared/models/widget.models'; export declare type RpcRetrieveValueMethod = 'none' | 'rpc' | 'attribute' | 'timeseries'; @@ -49,8 +50,7 @@ export interface SwitchRpcSettings { persistentPollingInterval: number; } -export function switchRpcDefaultSettings(): SwitchRpcSettings { - return { +export const switchRpcDefaultSettings = (): SwitchRpcSettings => ({ initialValue: false, retrieveValueMethod: 'rpc', valueKey: 'value', @@ -61,8 +61,7 @@ export function switchRpcDefaultSettings(): SwitchRpcSettings { requestTimeout: 500, requestPersistent: false, persistentPollingInterval: 5000 - }; -} + }); @Component({ selector: 'tb-switch-rpc-settings', @@ -92,7 +91,7 @@ export class SwitchRpcSettingsComponent extends PageComponent implements OnInit, aliasController: IAliasController; @Input() - targetDeviceAliasId: string; + targetDevice: TargetDevice; dataKeyType = DataKeyType; @@ -185,8 +184,7 @@ export class SwitchRpcSettingsComponent extends PageComponent implements OnInit, } private updateModel() { - const value: SwitchRpcSettings = this.switchRpcSettingsFormGroup.value; - this.modelValue = value; + this.modelValue = this.switchRpcSettingsFormGroup.value; this.propagateChange(this.modelValue); } diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/widget-settings.module.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/widget-settings.module.ts index 7b32a1ca4a..30c1b748de 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/widget-settings.module.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/widget-settings.module.ts @@ -123,9 +123,6 @@ import { import { SendRpcWidgetSettingsComponent } from '@home/components/widget/lib/settings/control/send-rpc-widget-settings.component'; -import { - DeviceKeyAutocompleteComponent -} from '@home/components/widget/lib/settings/control/device-key-autocomplete.component'; import { LedIndicatorWidgetSettingsComponent } from '@home/components/widget/lib/settings/control/led-indicator-widget-settings.component'; @@ -311,6 +308,9 @@ import { import { BarChartWithLabelsWidgetSettingsComponent } from '@home/components/widget/lib/settings/chart/bar-chart-with-labels-widget-settings.component'; +import { + SingleSwitchWidgetSettingsComponent +} from '@home/components/widget/lib/settings/control/single-switch-widget-settings.component'; @NgModule({ declarations: [ @@ -348,7 +348,6 @@ import { FlotPieKeySettingsComponent, ChartWidgetSettingsComponent, DoughnutChartWidgetSettingsComponent, - DeviceKeyAutocompleteComponent, SwitchRpcSettingsComponent, RoundSwitchWidgetSettingsComponent, SwitchControlWidgetSettingsComponent, @@ -424,7 +423,8 @@ import { LiquidLevelCardWidgetSettingsComponent, DoughnutWidgetSettingsComponent, RangeChartWidgetSettingsComponent, - BarChartWithLabelsWidgetSettingsComponent + BarChartWithLabelsWidgetSettingsComponent, + SingleSwitchWidgetSettingsComponent ], imports: [ CommonModule, @@ -467,7 +467,6 @@ import { FlotPieKeySettingsComponent, ChartWidgetSettingsComponent, DoughnutChartWidgetSettingsComponent, - DeviceKeyAutocompleteComponent, SwitchRpcSettingsComponent, RoundSwitchWidgetSettingsComponent, SwitchControlWidgetSettingsComponent, @@ -543,7 +542,8 @@ import { LiquidLevelCardWidgetSettingsComponent, DoughnutWidgetSettingsComponent, RangeChartWidgetSettingsComponent, - BarChartWithLabelsWidgetSettingsComponent + BarChartWithLabelsWidgetSettingsComponent, + SingleSwitchWidgetSettingsComponent ] }) export class WidgetSettingsModule { @@ -628,5 +628,6 @@ export const widgetSettingsComponentsMap: {[key: string]: Type
- + widget-config.advanced-title-style @@ -241,21 +241,13 @@ formControlName="datasources">
-
-
widget-config.target-device
-
- - -
-
+ + + +
+ [formGroup]="dataSettings" class="tb-form-panel">
widget-config.alarm-source
diff --git a/ui-ngx/src/app/modules/home/components/widget/widget-config.component.ts b/ui-ngx/src/app/modules/home/components/widget/widget-config.component.ts index fbdaa1c822..49e4e2ea59 100644 --- a/ui-ngx/src/app/modules/home/components/widget/widget-config.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/widget-config.component.ts @@ -36,6 +36,8 @@ import { GroupInfo, JsonSchema, JsonSettingsSchema, + TargetDevice, + TargetDeviceType, targetDeviceValid, Widget, WidgetConfigMode, widgetType @@ -368,9 +370,8 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, OnDe this.widgetType !== widgetType.static) { this.dataSettings.addControl('datasources', this.fb.control(null)); } else if (this.widgetType === widgetType.rpc) { - this.targetDeviceSettings.addControl('targetDeviceAliasId', - this.fb.control(null, - this.widgetEditMode ? [] : [Validators.required])); + this.targetDeviceSettings.addControl('targetDevice', + this.fb.control(null, [])); } else if (this.widgetType === widgetType.alarm) { this.dataSettings.addControl('alarmSource', this.fb.control(null)); } @@ -534,20 +535,9 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, OnDe this.dataSettings.patchValue({ datasources: config.datasources}, {emitEvent: false}); } else if (this.widgetType === widgetType.rpc) { - let targetDeviceAliasId: string; - if (config.targetDeviceAliasIds && config.targetDeviceAliasIds.length > 0) { - const aliasId = config.targetDeviceAliasIds[0]; - const entityAliases = this.aliasController.getEntityAliases(); - if (entityAliases[aliasId]) { - targetDeviceAliasId = entityAliases[aliasId].id; - } else { - targetDeviceAliasId = null; - } - } else { - targetDeviceAliasId = null; - } + const targetDevice: TargetDevice = config.targetDevice; this.targetDeviceSettings.patchValue({ - targetDeviceAliasId + targetDevice }, {emitEvent: false}); } else if (this.widgetType === widgetType.alarm) { this.dataSettings.patchValue( @@ -650,12 +640,7 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, OnDe private updateTargetDeviceSettings() { if (this.modelValue) { if (this.modelValue.config) { - const targetDeviceAliasId: string = this.targetDeviceSettings.get('targetDeviceAliasId').value; - if (targetDeviceAliasId) { - this.modelValue.config.targetDeviceAliasIds = [targetDeviceAliasId]; - } else { - this.modelValue.config.targetDeviceAliasIds = []; - } + this.modelValue.config.targetDevice = this.targetDeviceSettings.get('targetDevice').value; } this.propagateChange(this.modelValue); } @@ -944,9 +929,9 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, OnDe if (this.modelValue) { const config = this.modelValue.config; if (this.widgetType === widgetType.rpc && this.modelValue.isDataEnabled) { - if (!this.widgetEditMode && (!config.targetDeviceAliasIds || !config.targetDeviceAliasIds.length)) { + if (!this.widgetEditMode && !targetDeviceValid(config.targetDevice)) { return { - targetDeviceAliasIds: { + targetDevice: { valid: false } }; diff --git a/ui-ngx/src/app/modules/home/components/widget/widget.component.ts b/ui-ngx/src/app/modules/home/components/widget/widget.component.ts index 182cd128c9..a7fbc64db7 100644 --- a/ui-ngx/src/app/modules/home/components/widget/widget.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/widget.component.ts @@ -19,7 +19,6 @@ import { ChangeDetectionStrategy, ChangeDetectorRef, Component, - ComponentFactoryResolver, ComponentRef, ElementRef, Inject, @@ -110,12 +109,12 @@ import { MatDialog } from '@angular/material/dialog'; import { ComponentType } from '@angular/cdk/portal'; import { EMBED_DASHBOARD_DIALOG_TOKEN } from '@home/components/widget/dialog/embed-dashboard-dialog-token'; import { MobileService } from '@core/services/mobile.service'; -import { DialogService } from '@core/services/dialog.service'; import { PopoverPlacement } from '@shared/components/popover.models'; import { TbPopoverService } from '@shared/components/popover.service'; import { DASHBOARD_PAGE_COMPONENT_TOKEN } from '@home/components/tokens'; import { MODULES_MAP } from '@shared/models/constants'; import { IModulesMap } from '@modules/common/modules-map.models'; +import { DashboardUtilsService } from '@core/services/dashboard-utils.service'; @Component({ selector: 'tb-widget', @@ -179,7 +178,6 @@ export class WidgetComponent extends PageComponent implements OnInit, AfterViewI private route: ActivatedRoute, private router: Router, private widgetComponentService: WidgetComponentService, - private componentFactoryResolver: ComponentFactoryResolver, private elementRef: ElementRef, private injector: Injector, private dialog: MatDialog, @@ -198,8 +196,8 @@ export class WidgetComponent extends PageComponent implements OnInit, AfterViewI private alarmDataService: AlarmDataService, private translate: TranslateService, private utils: UtilsService, + private dashboardUtils: DashboardUtilsService, private mobileService: MobileService, - private dialogs: DialogService, private raf: RafService, private ngZone: NgZone, private cd: ChangeDetectorRef) { @@ -298,6 +296,7 @@ export class WidgetComponent extends PageComponent implements OnInit, AfterViewI this.subscriptionContext.entityDataService = this.entityDataService; this.subscriptionContext.alarmDataService = this.alarmDataService; this.subscriptionContext.utils = this.utils; + this.subscriptionContext.dashboardUtils = this.dashboardUtils; this.subscriptionContext.raf = this.raf; this.subscriptionContext.widgetUtils = this.widgetContext.utils; this.subscriptionContext.getServerTimeDiff = this.dashboardService.getServerTimeDiff.bind(this.dashboardService); @@ -959,7 +958,7 @@ export class WidgetComponent extends PageComponent implements OnInit, AfterViewI this.loadingData = false; options = { type: this.widget.type, - targetDeviceAliasIds: this.widget.config.targetDeviceAliasIds + targetDevice: this.widget.config.targetDevice }; options.callbacks = { rpcStateChanged: (subscription) => { @@ -974,7 +973,9 @@ export class WidgetComponent extends PageComponent implements OnInit, AfterViewI this.dynamicWidgetComponent.executingRpcRequest = subscription.executingRpcRequest; this.dynamicWidgetComponent.rpcErrorText = subscription.rpcErrorText; this.dynamicWidgetComponent.rpcRejection = subscription.rpcRejection; - this.clearMessage(); + if (this.typeParameters.displayRpcMessageToast) { + this.clearMessage(); + } this.detectChanges(); } }, @@ -983,7 +984,7 @@ export class WidgetComponent extends PageComponent implements OnInit, AfterViewI this.dynamicWidgetComponent.executingRpcRequest = subscription.executingRpcRequest; this.dynamicWidgetComponent.rpcErrorText = subscription.rpcErrorText; this.dynamicWidgetComponent.rpcRejection = subscription.rpcRejection; - if (subscription.rpcErrorText) { + if (subscription.rpcErrorText && this.typeParameters.displayRpcMessageToast) { this.displayMessage('error', subscription.rpcErrorText); } this.detectChanges(); @@ -993,7 +994,9 @@ export class WidgetComponent extends PageComponent implements OnInit, AfterViewI if (this.dynamicWidgetComponent) { this.dynamicWidgetComponent.rpcErrorText = null; this.dynamicWidgetComponent.rpcRejection = null; - this.clearMessage(); + if (this.typeParameters.displayRpcMessageToast) { + this.clearMessage(); + } this.detectChanges(); } } diff --git a/ui-ngx/src/app/modules/home/models/widget-component.models.ts b/ui-ngx/src/app/modules/home/models/widget-component.models.ts index c23bef5b88..950f951415 100644 --- a/ui-ngx/src/app/modules/home/models/widget-component.models.ts +++ b/ui-ngx/src/app/modules/home/models/widget-component.models.ts @@ -53,7 +53,13 @@ import { RafService } from '@core/services/raf.service'; import { WidgetTypeId } from '@shared/models/id/widget-type-id'; import { TenantId } from '@shared/models/id/tenant-id'; import { WidgetLayout } from '@shared/models/dashboard.models'; -import { createLabelFromDatasource, formatValue, hasDatasourceLabelsVariables, isDefined } from '@core/utils'; +import { + createLabelFromDatasource, + createLabelFromSubscriptionEntityInfo, + formatValue, + hasDatasourceLabelsVariables, + isDefined +} from '@core/utils'; import { Store } from '@ngrx/store'; import { AppState } from '@core/core.state'; import { @@ -482,9 +488,14 @@ export class LabelVariablePattern { update() { let label = this.pattern; - const datasource = this.ctx.defaultSubscription?.firstDatasource; - if (this.hasVariables && datasource) { - label = createLabelFromDatasource(datasource, label); + if (this.hasVariables) { + if (this.ctx.defaultSubscription?.type === widgetType.rpc) { + const entityInfo = this.ctx.defaultSubscription.getFirstEntityInfo(); + label = createLabelFromSubscriptionEntityInfo(entityInfo, label); + } else { + const datasource = this.ctx.defaultSubscription?.firstDatasource; + label = createLabelFromDatasource(datasource, label); + } } if (this.labelSubject.value !== label) { this.labelSubject.next(label); diff --git a/ui-ngx/src/app/modules/home/pages/rulechain/rulechain-page.component.html b/ui-ngx/src/app/modules/home/pages/rulechain/rulechain-page.component.html index 86d2700929..c56d09abbb 100644 --- a/ui-ngx/src/app/modules/home/pages/rulechain/rulechain-page.component.html +++ b/ui-ngx/src/app/modules/home/pages/rulechain/rulechain-page.component.html @@ -15,7 +15,7 @@ limitations under the License. --> -
diff --git a/ui-ngx/src/app/modules/home/pages/widget/widget-editor.component.html b/ui-ngx/src/app/modules/home/pages/widget/widget-editor.component.html index 91d89b6445..11329df694 100644 --- a/ui-ngx/src/app/modules/home/pages/widget/widget-editor.component.html +++ b/ui-ngx/src/app/modules/home/pages/widget/widget-editor.component.html @@ -16,7 +16,7 @@ -->
-
+
@@ -25,8 +25,8 @@ placeholder="{{ 'widget.widget-title' | translate }}"/> - + {{ widgetTypesDataMap.get(widgetTypes[type]).name | translate }} @@ -322,7 +322,7 @@
- +
- - {{ (requiredText ? requiredText : 'value.json-value-required') | translate }} - - - {{ 'value.json-value-invalid' | translate }} - + [(ngModel)]="modelValue" (ngModelChange)="onValueChanged()" placeholder="{{ 'value.json-value' | translate }}*"/> + + warning + +
diff --git a/ui-ngx/src/app/shared/components/value-input.component.scss b/ui-ngx/src/app/shared/components/value-input.component.scss index 9e335d813c..88355f4459 100644 --- a/ui-ngx/src/app/shared/components/value-input.component.scss +++ b/ui-ngx/src/app/shared/components/value-input.component.scss @@ -13,14 +13,36 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + +:host { + .tb-boolean-input { + min-width: 210px; + } +} + :host ::ng-deep { .mat-mdc-form-field.tb-value-type { + &.row { + width: 140px; + min-width: 140px; + } + &.column { + flex: 1; + width: auto; + } + .mat-mdc-form-field-infix { + max-height: 40px; + } mat-select-trigger { - .mat-icon { - vertical-align: bottom; - margin-right: 16px; - svg { - vertical-align: initial; + .tb-value-type-row { + display: flex; + flex-direction: row; + align-items: center; + justify-content: flex-start; + gap: 10px; + .mat-icon { + color: rgba(0, 0, 0, 0.38); + vertical-align: bottom; } } } diff --git a/ui-ngx/src/app/shared/components/value-input.component.ts b/ui-ngx/src/app/shared/components/value-input.component.ts index 27c65e2288..cce9a2400f 100644 --- a/ui-ngx/src/app/shared/components/value-input.component.ts +++ b/ui-ngx/src/app/shared/components/value-input.component.ts @@ -14,15 +14,24 @@ /// limitations under the License. /// -import { Component, forwardRef, Input, OnInit, ViewChild } from '@angular/core'; +import { Component, forwardRef, Input, OnDestroy, OnInit, ViewChild } from '@angular/core'; import { ControlValueAccessor, NG_VALUE_ACCESSOR, NgForm } from '@angular/forms'; -import { ValueType, valueTypesMap } from '@shared/models/constants'; +import { resolveBreakpoint, ValueType, valueTypesMap } from '@shared/models/constants'; import { isObject } from '@core/utils'; import { MatDialog } from '@angular/material/dialog'; import { JsonObjectEditDialogComponent, JsonObjectEditDialogData } from '@shared/components/dialog/json-object-edit-dialog.component'; +import { BreakpointObserver } from '@angular/cdk/layout'; +import { Subscription } from 'rxjs'; + +type Layout = 'column' | 'row'; + +export interface ValueInputLayout { + layout: Layout; + breakpoints?: {[breakpoint: string]: Layout}; +} @Component({ selector: 'tb-value-input', @@ -36,33 +45,67 @@ import { } ] }) -export class ValueInputComponent implements OnInit, ControlValueAccessor { +export class ValueInputComponent implements OnInit, OnDestroy, ControlValueAccessor { + + @Input() + disabled: boolean; + + @Input() + requiredText: string; + + @Input() + valueType: ValueType; - @Input() disabled: boolean; + @Input() + trueLabel = 'value.true'; - @Input() requiredText: string; + @Input() + falseLabel = 'value.false'; + + @Input() + layout: ValueInputLayout | Layout = 'row'; @ViewChild('inputForm', {static: true}) inputForm: NgForm; modelValue: any; - valueType: ValueType; - public valueTypeEnum = ValueType; valueTypeKeys = Object.keys(ValueType); valueTypes = valueTypesMap; + showValueType = true; + + computedLayout: Layout; + private propagateChange = null; + private _subscription: Subscription; + constructor( + private breakpointObserver: BreakpointObserver, public dialog: MatDialog, ) { } ngOnInit(): void { + this._subscription = new Subscription(); + this.showValueType = !this.valueType; + this.computedLayout = this._computeLayout(); + if (typeof this.layout === 'object' && this.layout.breakpoints) { + const breakpoints = Object.keys(this.layout.breakpoints); + this._subscription.add(this.breakpointObserver.observe(breakpoints.map(breakpoint => resolveBreakpoint(breakpoint))).subscribe( + () => { + this.computedLayout = this._computeLayout(); + } + )); + } + } + + ngOnDestroy() { + this._subscription.unsubscribe(); } openEditJSONDialog($event: Event) { @@ -100,18 +143,20 @@ export class ValueInputComponent implements OnInit, ControlValueAccessor { writeValue(value: any): void { this.modelValue = value; - if (this.modelValue === true || this.modelValue === false) { - this.valueType = ValueType.BOOLEAN; - } else if (typeof this.modelValue === 'number') { - if (this.modelValue.toString().indexOf('.') === -1) { - this.valueType = ValueType.INTEGER; + if (this.showValueType) { + if (this.modelValue === true || this.modelValue === false) { + this.valueType = ValueType.BOOLEAN; + } else if (typeof this.modelValue === 'number') { + if (this.modelValue.toString().indexOf('.') === -1) { + this.valueType = ValueType.INTEGER; + } else { + this.valueType = ValueType.DOUBLE; + } + } else if (isObject(this.modelValue)) { + this.valueType = ValueType.JSON; } else { - this.valueType = ValueType.DOUBLE; + this.valueType = ValueType.STRING; } - } else if (isObject(this.modelValue)) { - this.valueType = ValueType.JSON; - } else { - this.valueType = ValueType.STRING; } } @@ -140,4 +185,22 @@ export class ValueInputComponent implements OnInit, ControlValueAccessor { this.updateView(); } + private _computeLayout(): Layout { + if (typeof this.layout !== 'object') { + return this.layout; + } else { + let layout = this.layout.layout; + if (this.layout.breakpoints) { + for (const breakpoint of Object.keys(this.layout.breakpoints)) { + const breakpointValue = resolveBreakpoint(breakpoint); + if (this.breakpointObserver.isMatched(breakpointValue)) { + layout = this.layout.breakpoints[breakpoint]; + break; + } + } + } + return layout; + } + } + } diff --git a/ui-ngx/src/app/shared/import-export/import-export.service.ts b/ui-ngx/src/app/shared/import-export/import-export.service.ts index 792b855534..b7d0dd6a25 100644 --- a/ui-ngx/src/app/shared/import-export/import-export.service.ts +++ b/ui-ngx/src/app/shared/import-export/import-export.service.ts @@ -229,11 +229,10 @@ export class ImportExportService { const originalSize = widgetItem.originalSize; const datasourceAliases = aliasesInfo.datasourceAliases; - const targetDeviceAliases = aliasesInfo.targetDeviceAliases; - if (datasourceAliases || targetDeviceAliases) { + if (datasourceAliases || aliasesInfo.targetDeviceAlias) { const entityAliases: EntityAliases = {}; const datasourceAliasesMap: {[aliasId: string]: number} = {}; - const targetDeviceAliasesMap: {[aliasId: string]: number} = {}; + let targetDeviceAliasId: string; let aliasId: string; let datasourceIndex: number; if (datasourceAliases) { @@ -244,13 +243,10 @@ export class ImportExportService { entityAliases[aliasId] = {id: aliasId, ...datasourceAliases[datasourceIndex]}; } } - if (targetDeviceAliases) { - for (const strIndex of Object.keys(targetDeviceAliases)) { - datasourceIndex = Number(strIndex); - aliasId = this.utils.guid(); - targetDeviceAliasesMap[aliasId] = datasourceIndex; - entityAliases[aliasId] = {id: aliasId, ...targetDeviceAliases[datasourceIndex]}; - } + if (aliasesInfo.targetDeviceAlias) { + aliasId = this.utils.guid(); + targetDeviceAliasId = aliasId; + entityAliases[aliasId] = {id: aliasId, ...aliasesInfo.targetDeviceAlias}; } const aliasIds = Object.keys(entityAliases); if (aliasIds.length > 0) { @@ -267,9 +263,8 @@ export class ImportExportService { if (isDefined(datasourceAliasesMap[id])) { index = datasourceAliasesMap[id]; datasourceAliases[index] = entityAlias; - } else if (isDefined(targetDeviceAliasesMap[id])) { - index = targetDeviceAliasesMap[id]; - targetDeviceAliases[index] = entityAlias; + } else if (targetDeviceAliasId === id) { + aliasesInfo.targetDeviceAlias = entityAlias; } } return this.addImportedWidget(dashboard, targetState, targetLayoutFunction, widget, @@ -965,19 +960,15 @@ export class ImportExportService { private prepareAliasesInfo(aliasesInfo: AliasesInfo): AliasesInfo { const datasourceAliases = aliasesInfo.datasourceAliases; - const targetDeviceAliases = aliasesInfo.targetDeviceAliases; - if (datasourceAliases || targetDeviceAliases) { + if (datasourceAliases || aliasesInfo.targetDeviceAlias) { if (datasourceAliases) { for (const strIndex of Object.keys(datasourceAliases)) { const datasourceIndex = Number(strIndex); datasourceAliases[datasourceIndex] = this.prepareEntityAlias(datasourceAliases[datasourceIndex]); } } - if (targetDeviceAliases) { - for (const strIndex of Object.keys(targetDeviceAliases)) { - const datasourceIndex = Number(strIndex); - targetDeviceAliases[datasourceIndex] = this.prepareEntityAlias(targetDeviceAliases[datasourceIndex]); - } + if (aliasesInfo.targetDeviceAlias) { + aliasesInfo.targetDeviceAlias = this.prepareEntityAlias(aliasesInfo.targetDeviceAlias); } } return aliasesInfo; diff --git a/ui-ngx/src/app/shared/models/alias.models.ts b/ui-ngx/src/app/shared/models/alias.models.ts index 06e6a88a2c..084646d290 100644 --- a/ui-ngx/src/app/shared/models/alias.models.ts +++ b/ui-ngx/src/app/shared/models/alias.models.ts @@ -194,7 +194,7 @@ export interface EntityAliasInfo { export interface AliasesInfo { datasourceAliases: {[datasourceIndex: number]: EntityAliasInfo}; - targetDeviceAliases: {[targetDeviceAliasIndex: number]: EntityAliasInfo}; + targetDeviceAlias: EntityAliasInfo; } export interface EntityAlias extends EntityAliasInfo { diff --git a/ui-ngx/src/app/shared/models/rpc-widget-settings.models.ts b/ui-ngx/src/app/shared/models/rpc-widget-settings.models.ts new file mode 100644 index 0000000000..2e5456009a --- /dev/null +++ b/ui-ngx/src/app/shared/models/rpc-widget-settings.models.ts @@ -0,0 +1,121 @@ +/// +/// Copyright © 2016-2024 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 { AttributeScope } from '@shared/models/telemetry/telemetry.models'; +import { BackgroundSettings } from '@shared/models/widget-settings.models'; + +export enum RpcInitialStateAction { + DO_NOTHING = 'DO_NOTHING', + EXECUTE_RPC = 'EXECUTE_RPC', + GET_ATTRIBUTE = 'GET_ATTRIBUTE', + GET_TIME_SERIES = 'GET_TIME_SERIES' +} + +export const rpcInitialStateActions = Object.keys(RpcInitialStateAction) as RpcInitialStateAction[]; + +export const rpcInitialStateTranslations = new Map( + [ + [RpcInitialStateAction.DO_NOTHING, 'widgets.rpc-state.do-nothing'], + [RpcInitialStateAction.EXECUTE_RPC, 'widgets.rpc-state.execute-rpc'], + [RpcInitialStateAction.GET_ATTRIBUTE, 'widgets.rpc-state.get-attribute'], + [RpcInitialStateAction.GET_TIME_SERIES, 'widgets.rpc-state.get-time-series'] + ] +); + +export interface RpcSettings { + method: string; + requestTimeout: number; + requestPersistent: boolean; + persistentPollingInterval: number; +} + +export interface RpcTelemetrySettings { + key: string; +} + +export interface RpcGetAttributeSettings extends RpcTelemetrySettings { + scope: AttributeScope | null; +} + +export interface RpcSetAttributeSettings extends RpcTelemetrySettings { + scope: AttributeScope.SERVER_SCOPE | AttributeScope.SHARED_SCOPE; +} + +export enum RpcDataToStateType { + NONE = 'NONE', + FUNCTION = 'FUNCTION' +} + +export interface RpcDataToStateSettings { + type: RpcDataToStateType; + dataToStateFunction: string; + compareToValue?: any; +} + +export interface RpcInitialStateSettings { + action: RpcInitialStateAction; + defaultValue: V; + executeRpc: RpcSettings; + getAttribute: RpcGetAttributeSettings; + getTimeSeries: RpcTelemetrySettings; + dataToState: RpcDataToStateSettings; +} + +export enum RpcUpdateStateAction { + EXECUTE_RPC = 'EXECUTE_RPC', + SET_ATTRIBUTE = 'SET_ATTRIBUTE', + ADD_TIME_SERIES = 'ADD_TIME_SERIES' +} + +export const rpcUpdateStateActions = Object.keys(RpcUpdateStateAction) as RpcUpdateStateAction[]; + +export const rpcUpdateStateTranslations = new Map( + [ + [RpcUpdateStateAction.EXECUTE_RPC, 'widgets.rpc-state.execute-rpc'], + [RpcUpdateStateAction.SET_ATTRIBUTE, 'widgets.rpc-state.set-attribute'], + [RpcUpdateStateAction.ADD_TIME_SERIES, 'widgets.rpc-state.add-time-series'] + ] +); + +export enum RpcStateToParamsType { + CONSTANT = 'CONSTANT', + FUNCTION = 'FUNCTION', + NONE = 'NONE' +} + +export interface RpcStateToParamsSettings { + type: RpcStateToParamsType; + constantValue: any; + stateToParamsFunction: string; +} + +export interface RpcUpdateStateSettings { + action: RpcUpdateStateAction; + executeRpc: RpcSettings; + setAttribute: RpcSetAttributeSettings; + putTimeSeries: RpcTelemetrySettings; + stateToParams: RpcStateToParamsSettings; +} + +export interface RpcStateBehaviourSettings { + initialState: RpcInitialStateSettings; + updateStateByValue: (value: V) => RpcUpdateStateSettings; +} + +export interface RpcStateWidgetSettings { + initialState: RpcInitialStateSettings; + background: BackgroundSettings; +} diff --git a/ui-ngx/src/app/shared/models/telemetry/telemetry.models.ts b/ui-ngx/src/app/shared/models/telemetry/telemetry.models.ts index 95c8cd4925..e1c6af620b 100644 --- a/ui-ngx/src/app/shared/models/telemetry/telemetry.models.ts +++ b/ui-ngx/src/app/shared/models/telemetry/telemetry.models.ts @@ -88,6 +88,16 @@ export const telemetryTypeTranslations = new Map( ] ); +export const telemetryTypeTranslationsShort = new Map( + [ + [LatestTelemetry.LATEST_TELEMETRY, 'attribute.scope-telemetry-short'], + [AttributeScope.CLIENT_SCOPE, 'attribute.scope-client-short'], + [AttributeScope.SERVER_SCOPE, 'attribute.scope-server-short'], + [AttributeScope.SHARED_SCOPE, 'attribute.scope-shared-short'] + ] +); + + export const isClientSideTelemetryType = new Map( [ [LatestTelemetry.LATEST_TELEMETRY, true], diff --git a/ui-ngx/src/app/shared/models/widget.models.ts b/ui-ngx/src/app/shared/models/widget.models.ts index c8e5699d82..8d7452da89 100644 --- a/ui-ngx/src/app/shared/models/widget.models.ts +++ b/ui-ngx/src/app/shared/models/widget.models.ts @@ -183,6 +183,7 @@ export interface WidgetTypeParameters { hideDataSettings?: boolean; defaultDataKeysFunction?: (configComponent: any, configData: any) => DataKey[]; defaultLatestDataKeysFunction?: (configComponent: any, configData: any) => DataKey[]; + displayRpcMessageToast?: boolean; } export interface WidgetControllerDescriptor { @@ -409,6 +410,22 @@ export interface Datasource { [key: string]: any; } +export enum TargetDeviceType { + device = 'device', + entity = 'entity' +} + +export interface TargetDevice { + type?: TargetDeviceType; + deviceId?: string; + entityAliasId?: string; +} + +export const targetDeviceValid = (targetDevice?: TargetDevice): boolean => + !!targetDevice && !!targetDevice.type && + ((targetDevice.type === TargetDeviceType.device && !!targetDevice.deviceId) || + (targetDevice.type === TargetDeviceType.entity && !!targetDevice.entityAliasId)); + export const datasourcesHasAggregation = (datasources?: Array): boolean => { if (datasources) { const foundDatasource = datasources.find(datasource => { @@ -697,7 +714,7 @@ export interface WidgetConfig { alarmSource?: Datasource; alarmFilterConfig?: AlarmFilterConfig; datasources?: Array; - targetDeviceAliasIds?: Array; + targetDevice?: TargetDevice; [key: string]: any; } diff --git a/ui-ngx/src/assets/locale/locale.constant-en_US.json b/ui-ngx/src/assets/locale/locale.constant-en_US.json index 9140f0071a..0667ec04fe 100644 --- a/ui-ngx/src/assets/locale/locale.constant-en_US.json +++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json @@ -740,6 +740,11 @@ "scope-client": "Client attributes", "scope-server": "Server attributes", "scope-shared": "Shared attributes", + "scope-client-short": "Client", + "scope-server-short": "Server", + "scope-shared-short": "Shared", + "scope-latest-short": "Latest", + "scope-any": "Any", "add": "Add attribute", "key": "Key", "key-max-length": "Key should be less than 256", @@ -5986,6 +5991,55 @@ "min-value": "Minimum value", "max-value": "Maximum value" }, + "rpc-state": { + "initial-state": "Initial state", + "initial-state-hint": "Action to get the initial value of the component.", + "turn-on": "Turn 'On'", + "turn-on-hint": "Action performed to turn ON the component.", + "turn-off": "Turn 'Off'", + "turn-off-hint": "Action performed to turn OFF the component.", + "on": "On", + "off": "Off", + "do-nothing": "Do nothing", + "execute-rpc": "Execute RPC", + "get-attribute": "Get attribute", + "set-attribute": "Set attribute", + "get-time-series": "Get time-series", + "add-time-series": "Add time-series", + "execute-rpc-text": "Execute RPC method '{{methodName}}'", + "get-attribute-text": "Use attribute '{{key}}'", + "get-time-series-text": "Use time-series '{{key}}'", + "set-attribute-to-value-text": "Set '{{key}}' attribute to: {{value}}", + "add-time-series-value-text": "Add '{{key}}' time-series value: {{value}}", + "set-attribute-text": "Set '{{key}}' attribute", + "add-time-series-text": "Add '{{key}}' time-series", + "action": "Action", + "value": "Value", + "init-value-hint": "Value that will be set until device sends data.", + "method": "Method", + "method-name-required": "Method name is required.", + "request-timeout-ms": "RPC request timeout (ms)", + "request-timeout-required": "Request timeout is required.", + "min-request-timeout-error": "Request timeout value should be greater or equal 5000 ms (5 seconds).", + "request-persistent": "RPC request persistent", + "persistent-polling-interval": "Persistent polling interval (ms)", + "persistent-polling-interval-hint": "Polling interval (ms) to get persistent RPC command response", + "persistent-polling-interval-required": "Persistent polling interval is required.", + "min-persistent-polling-interval-error": "Persistent polling interval value should be greater or equal 1000 ms (1 second).", + "attribute-scope": "Attribute scope", + "attribute-key": "Attribute key", + "attribute-key-required": "Attribute key is required.", + "time-series-key": "Time-series key", + "time-series-key-required": "Time-series key is required.", + "action-result-converter": "Action result converter", + "converter-none": "None", + "converter-function": "Function", + "converter-constant": "Constant", + "parse-value-function": "Parse value function", + "on-when-result-is": "'On' when result is", + "parameters": "Parameters", + "convert-value-function": "Convert value function" + }, "maps": { "select-entity": "Select entity", "select-entity-hint": "Hint: after selection click at the map to set position", @@ -6219,6 +6273,24 @@ "label-position-left": "Left", "label-position-top": "Top" }, + "single-switch": { + "behavior": "Behavior", + "layout": "Layout", + "layout-right": "Right", + "layout-left": "Left", + "layout-centered": "Centered", + "auto-scale": "Auto scale", + "label": "Label", + "icon": "Icon", + "switch-color": "Switch color", + "on": "On", + "off": "Off", + "disabled": "Disabled", + "tumbler-color": "Tumbler color", + "on-label": "On label", + "off-label": "Off label", + "switch": "Switch" + }, "value-card": { "layout": "Layout", "layout-square": "Square", diff --git a/ui-ngx/src/assets/widget/single-switch/centered-layout.svg b/ui-ngx/src/assets/widget/single-switch/centered-layout.svg new file mode 100644 index 0000000000..1506dd8eea --- /dev/null +++ b/ui-ngx/src/assets/widget/single-switch/centered-layout.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/ui-ngx/src/assets/widget/single-switch/left-layout.svg b/ui-ngx/src/assets/widget/single-switch/left-layout.svg new file mode 100644 index 0000000000..a788fc7956 --- /dev/null +++ b/ui-ngx/src/assets/widget/single-switch/left-layout.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/ui-ngx/src/assets/widget/single-switch/right-layout.svg b/ui-ngx/src/assets/widget/single-switch/right-layout.svg new file mode 100644 index 0000000000..45a629782b --- /dev/null +++ b/ui-ngx/src/assets/widget/single-switch/right-layout.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/ui-ngx/src/form.scss b/ui-ngx/src/form.scss index ee6d4167cd..67f8c6b641 100644 --- a/ui-ngx/src/form.scss +++ b/ui-ngx/src/form.scss @@ -18,6 +18,9 @@ @mixin form-row-column() { flex-direction: column; align-items: stretch; + &.align-start { + align-items: stretch; + } gap: 12px; padding: 12px 7px 12px 16px; } @@ -76,6 +79,9 @@ } > .mat-expansion-panel { padding: 16px; + &.no-padding { + padding: 0; + } .mat-expansion-panel-header { .mat-slide { margin: 0; @@ -101,8 +107,9 @@ background: none; } .mat-expansion-indicator { - height: 32px; + height: 24px; padding: 2px; + line-height: 14px; } } > .mat-expansion-panel-header-description { @@ -113,9 +120,14 @@ display: flex; flex-direction: column; gap: 16px; - padding: 16px 0 0 !important; + padding: 0 !important; + > :first-child { + margin-top: 16px; + @media #{$mat-xs} { + margin-top: 12px; + } + } @media #{$mat-xs} { - padding: 12px 0 0 !important; gap: 8px; } } @@ -166,10 +178,16 @@ @include form-row-column-breakpoint($mat-lt-md) } } + &.align-start { + align-items: flex-start; + } &.no-border { border: none; border-radius: 0; } + &.no-gap { + gap: 0; + } &.no-padding { padding: 0; } @@ -200,6 +218,10 @@ min-width: fit-content; } } + .fixed-title-height { + min-height: 40px; + line-height: 40px; + } .mat-slide:only-child { margin: 8px 0; } @@ -340,6 +362,15 @@ } } } + &.tb-suffix-absolute { + .mat-mdc-text-field-wrapper { + .mat-mdc-form-field-icon-suffix { + > .mat-icon { + right: 16px; + } + } + } + } } &.tb-chips { &.flex { @@ -385,6 +416,27 @@ } } } + &.tb-suffix-absolute { + .mat-mdc-text-field-wrapper { + .mat-mdc-form-field-icon-suffix { + padding: 0; + > .mat-icon { + position: absolute; + right: 0; + } + } + } + &.mat-mdc-form-field-has-icon-suffix { + .mat-mdc-text-field-wrapper { + padding-right: 12px; + } + &.number { + .mat-mdc-text-field-wrapper { + padding-right: 4px; + } + } + } + } } .tb-form-table { @@ -554,4 +606,29 @@ color: rgba(0, 0, 0, 0.12); } } + + .mat-mdc-chip-listbox.center-stretch { + .mat-mdc-standard-chip { + flex: 1; + &.mdc-evolution-chip--with-primary-graphic { + .mdc-evolution-chip__action--primary { + width: 100%; + padding-right: 0; + gap: 0; + .mdc-evolution-chip__graphic { + padding: 0; + flex: none; + } + } + &.mdc-evolution-chip--selected { + .mdc-evolution-chip__action--primary { + gap: 4px; + } + .mdc-evolution-chip__graphic { + width: 20px; + } + } + } + } + } } diff --git a/ui-ngx/src/styles.scss b/ui-ngx/src/styles.scss index 8ce41f10db..0750de263f 100644 --- a/ui-ngx/src/styles.scss +++ b/ui-ngx/src/styles.scss @@ -364,7 +364,8 @@ mat-icon { .mat-mdc-tooltip.tb-error-tooltip { .mdc-tooltip__surface { - background-color: rgba(209, 39, 48, 0.12); + background-color: #fff2f3; + box-shadow: -2px 2px 4px 0px rgba(0,0,0,0.2); color: rgba(209, 39, 48, 1); } } From d4d019bedac3d9a0ffe7f98c2423c80814066b7c Mon Sep 17 00:00:00 2001 From: Andrii Landiak Date: Wed, 24 Jan 2024 15:21:43 +0200 Subject: [PATCH 130/179] Renaming notifications for edge. Minor refactoring --- .../service/edge/rpc/EdgeGrpcService.java | 4 +- .../service/edge/rpc/EdgeGrpcSession.java | 52 ++++++++++--------- ...CommunicationFailureTriggerProcessor.java} | 26 ++++++---- ...va => EdgeConnectionTriggerProcessor.java} | 18 +++---- .../impl/NotificationRuleExportService.java | 12 ++--- .../impl/NotificationRuleImportService.java | 12 ++--- .../data/notification/NotificationType.java | 4 +- ...CommunicationFailureNotificationInfo.java} | 7 ++- ...va => EdgeConnectionNotificationInfo.java} | 2 +- ...a => EdgeCommunicationFailureTrigger.java} | 11 ++-- ...rigger.java => EdgeConnectionTrigger.java} | 7 ++- ...FailureNotificationRuleTriggerConfig.java} | 4 +- ...nectionNotificationRuleTriggerConfig.java} | 5 +- .../config/NotificationRuleTriggerConfig.java | 4 +- .../config/NotificationRuleTriggerType.java | 4 +- .../common/data/util/TemplateUtils.java | 3 +- .../DefaultNotificationSettingsService.java | 14 ++--- .../notification/DefaultNotifications.java | 39 +++++++------- .../rule-notification-dialog.component.html | 18 +++---- .../rule-notification-dialog.component.ts | 18 +++---- ui-ngx/src/app/shared/models/edge.models.ts | 8 +-- .../app/shared/models/notification.models.ts | 24 ++++----- ...ilure.md => edge_communication_failure.md} | 10 ++-- ...dge_connectivity.md => edge_connection.md} | 17 +----- .../assets/locale/locale.constant-en_US.json | 16 +++--- 25 files changed, 168 insertions(+), 171 deletions(-) rename application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/{EdgeFailureTriggerProcessor.java => EdgeCommunicationFailureTriggerProcessor.java} (65%) rename application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/{EdgeConnectivityTriggerProcessor.java => EdgeConnectionTriggerProcessor.java} (77%) rename common/data/src/main/java/org/thingsboard/server/common/data/notification/info/{EdgeFailureNotificationInfo.java => EdgeCommunicationFailureNotificationInfo.java} (89%) rename common/data/src/main/java/org/thingsboard/server/common/data/notification/info/{EdgeConnectivityNotificationInfo.java => EdgeConnectionNotificationInfo.java} (95%) rename common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/{EdgeFailureTrigger.java => EdgeCommunicationFailureTrigger.java} (84%) rename common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/{EdgeConnectivityTrigger.java => EdgeConnectionTrigger.java} (89%) rename common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/config/{EdgeFailureNotificationRuleTriggerConfig.java => EdgeCommunicationFailureNotificationRuleTriggerConfig.java} (85%) rename common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/config/{EdgeConnectivityNotificationRuleTriggerConfig.java => EdgeConnectionNotificationRuleTriggerConfig.java} (84%) rename ui-ngx/src/assets/help/en_US/notification/{edge_failure.md => edge_communication_failure.md} (78%) rename ui-ngx/src/assets/help/en_US/notification/{edge_connectivity.md => edge_connection.md} (84%) diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcService.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcService.java index 09092d0621..c23fd98d8e 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcService.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcService.java @@ -38,7 +38,7 @@ import org.thingsboard.server.common.data.kv.BasicTsKvEntry; import org.thingsboard.server.common.data.kv.BooleanDataEntry; import org.thingsboard.server.common.data.kv.LongDataEntry; import org.thingsboard.server.common.data.msg.TbMsgType; -import org.thingsboard.server.common.data.notification.rule.trigger.EdgeConnectivityTrigger; +import org.thingsboard.server.common.data.notification.rule.trigger.EdgeConnectionTrigger; import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsgDataType; import org.thingsboard.server.common.msg.TbMsgMetaData; @@ -467,7 +467,7 @@ public class EdgeGrpcService extends EdgeRpcServiceGrpc.EdgeRpcServiceImplBase i edgeState.put(DefaultDeviceStateService.ACTIVITY_STATE, false); edgeState.put(DefaultDeviceStateService.LAST_DISCONNECT_TIME, ts); } - ctx.getNotificationRuleProcessor().process(EdgeConnectivityTrigger.builder() + ctx.getNotificationRuleProcessor().process(EdgeConnectionTrigger.builder() .tenantId(tenantId) .customerId(edge.getCustomerId()) .edgeId(edgeId) diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java index a42a80c318..44bdfcdb1c 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java @@ -35,7 +35,7 @@ import org.thingsboard.server.common.data.kv.AttributeKvEntry; import org.thingsboard.server.common.data.kv.BaseAttributeKvEntry; import org.thingsboard.server.common.data.kv.LongDataEntry; import org.thingsboard.server.common.data.kv.StringDataEntry; -import org.thingsboard.server.common.data.notification.rule.trigger.EdgeFailureTrigger; +import org.thingsboard.server.common.data.notification.rule.trigger.EdgeCommunicationFailureTrigger; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.page.SortOrder; @@ -466,22 +466,24 @@ public final class EdgeGrpcSession implements Closeable { if (isConnected() && sessionState.getPendingMsgsMap().values().size() > 0) { List copy = new ArrayList<>(sessionState.getPendingMsgsMap().values()); if (attempt > 1) { - String errorMsg = String.format("Failed to deliver the batch: {%s}", copy); + String error = "Failed to deliver the batch"; + String failureMsg = String.format("{%s}: {%s}", error, copy); if (attempt == 2) { // Send a failure notification only on the second attempt. // This ensures that failure alerts are sent just once to avoid redundant notifications. - ctx.getNotificationRuleProcessor().process(EdgeFailureTrigger.builder().tenantId(tenantId) - .edgeId(edge.getId()).customerId(edge.getCustomerId()).edgeName(edge.getName()).errorMsg(errorMsg).build()); + ctx.getNotificationRuleProcessor().process(EdgeCommunicationFailureTrigger.builder().tenantId(tenantId) + .edgeId(edge.getId()).customerId(edge.getCustomerId()).edgeName(edge.getName()).failureMsg(failureMsg).error(error).build()); } - log.warn("[{}][{}] {}, attempt: {}", this.tenantId, this.sessionId, errorMsg, attempt); + log.warn("[{}][{}] {}, attempt: {}", this.tenantId, this.sessionId, failureMsg, attempt); } log.trace("[{}][{}][{}] downlink msg(s) are going to be send.", this.tenantId, this.sessionId, copy.size()); for (DownlinkMsg downlinkMsg : copy) { if (this.clientMaxInboundMessageSize != 0 && downlinkMsg.getSerializedSize() > this.clientMaxInboundMessageSize) { - log.error("[{}][{}][{}] Downlink msg size [{}] exceeds client max inbound message size [{}]. Skipping this message. " + - "Please increase value of CLOUD_RPC_MAX_INBOUND_MESSAGE_SIZE env variable on the edge and restart it." + - "Message {}", this.tenantId, edge.getId(), this.sessionId, downlinkMsg.getSerializedSize(), - this.clientMaxInboundMessageSize, downlinkMsg); + String message = String.format("Downlink msg size [{%s}] exceeds client max inbound message size [{%s}]. " + + "Please increase value of CLOUD_RPC_MAX_INBOUND_MESSAGE_SIZE env variable on the edge and restart it.", downlinkMsg.getSerializedSize(), this.clientMaxInboundMessageSize); + log.error("[{}][{}][{}] {} Message {}", this.tenantId, edge.getId(), this.sessionId, message, downlinkMsg); + ctx.getNotificationRuleProcessor().process(EdgeCommunicationFailureTrigger.builder().tenantId(tenantId) + .edgeId(edge.getId()).customerId(edge.getCustomerId()).edgeName(edge.getName()).failureMsg(message).error(message).build()); sessionState.getPendingMsgsMap().remove(downlinkMsg.getDownlinkMsgId()); } else { sendDownlinkMsg(ResponseMsg.newBuilder() @@ -492,11 +494,12 @@ public final class EdgeGrpcSession implements Closeable { if (attempt < MAX_DOWNLINK_ATTEMPTS) { scheduleDownlinkMsgsPackSend(attempt + 1); } else { - String errorMsg = String.format("Failed to deliver messages: %s", copy); + String failureMsg = String.format("Failed to deliver messages: %s", copy); log.warn("[{}][{}] Failed to deliver the batch after {} attempts. Next messages are going to be discarded {}", this.tenantId, this.sessionId, MAX_DOWNLINK_ATTEMPTS, copy); - ctx.getNotificationRuleProcessor().process(EdgeFailureTrigger.builder().tenantId(tenantId).edgeId(edge.getId()) - .customerId(edge.getCustomerId()).edgeName(edge.getName()).errorMsg(errorMsg).build()); + ctx.getNotificationRuleProcessor().process(EdgeCommunicationFailureTrigger.builder().tenantId(tenantId).edgeId(edge.getId()) + .customerId(edge.getCustomerId()).edgeName(edge.getName()).failureMsg(failureMsg) + .error("Failed to deliver messages after " + MAX_DOWNLINK_ATTEMPTS + " attempts").build()); stopCurrentSendDownlinkMsgsTask(false); } } else { @@ -790,10 +793,10 @@ public final class EdgeGrpcSession implements Closeable { } } } catch (Exception e) { - String errorMsg = String.format("Can't process uplink msg [%s] from edge", uplinkMsg); + String failureMsg = String.format("Can't process uplink msg [%s] from edge", uplinkMsg); log.error("[{}][{}] Can't process uplink msg [{}]", this.tenantId, this.sessionId, uplinkMsg, e); - ctx.getNotificationRuleProcessor().process(EdgeFailureTrigger.builder().tenantId(tenantId).edgeId(edge.getId()) - .customerId(edge.getCustomerId()).edgeName(edge.getName()).errorMsg(errorMsg).build()); + ctx.getNotificationRuleProcessor().process(EdgeCommunicationFailureTrigger.builder().tenantId(tenantId).edgeId(edge.getId()) + .customerId(edge.getCustomerId()).edgeName(edge.getName()).failureMsg(failureMsg).error(e.getMessage()).build()); return Futures.immediateFailedFuture(e); } return Futures.allAsList(result); @@ -817,21 +820,22 @@ public final class EdgeGrpcSession implements Closeable { .setMaxInboundMessageSize(maxInboundMessageSize) .build(); } - String errorMsg = String.format("Failed to validate the edge! Provided request secret: %s", request.getEdgeSecret()); - ctx.getNotificationRuleProcessor().process(EdgeFailureTrigger.builder().tenantId(tenantId).edgeId(edge.getId()) - .customerId(edge.getCustomerId()).edgeName(edge.getName()).errorMsg(errorMsg).build()); + String error = "Failed to validate the edge!"; + String failureMsg = String.format("{%s} Provided request secret: %s", error, request.getEdgeSecret()); + ctx.getNotificationRuleProcessor().process(EdgeCommunicationFailureTrigger.builder().tenantId(tenantId).edgeId(edge.getId()) + .customerId(edge.getCustomerId()).edgeName(edge.getName()).failureMsg(failureMsg).error(error).build()); return ConnectResponseMsg.newBuilder() .setResponseCode(ConnectResponseCode.BAD_CREDENTIALS) - .setErrorMsg(errorMsg) + .setErrorMsg(failureMsg) .setConfiguration(EdgeConfiguration.getDefaultInstance()).build(); } catch (Exception e) { - String errorMsg = "Failed to process edge connection!"; - ctx.getNotificationRuleProcessor().process(EdgeFailureTrigger.builder().tenantId(tenantId).edgeId(edge.getId()) - .customerId(edge.getCustomerId()).edgeName(edge.getName()).errorMsg(errorMsg).build()); - log.error(errorMsg, e); + String failureMsg = "Failed to process edge connection!"; + ctx.getNotificationRuleProcessor().process(EdgeCommunicationFailureTrigger.builder().tenantId(tenantId).edgeId(edge.getId()) + .customerId(edge.getCustomerId()).edgeName(edge.getName()).failureMsg(failureMsg).error(e.getMessage()).build()); + log.error(failureMsg, e); return ConnectResponseMsg.newBuilder() .setResponseCode(ConnectResponseCode.SERVER_UNAVAILABLE) - .setErrorMsg(errorMsg) + .setErrorMsg(failureMsg) .setConfiguration(EdgeConfiguration.getDefaultInstance()).build(); } } diff --git a/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/EdgeFailureTriggerProcessor.java b/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/EdgeCommunicationFailureTriggerProcessor.java similarity index 65% rename from application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/EdgeFailureTriggerProcessor.java rename to application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/EdgeCommunicationFailureTriggerProcessor.java index afdfa6eb1f..dc54024eec 100644 --- a/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/EdgeFailureTriggerProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/EdgeCommunicationFailureTriggerProcessor.java @@ -18,18 +18,18 @@ package org.thingsboard.server.service.notification.rule.trigger; import lombok.RequiredArgsConstructor; import org.apache.commons.collections.CollectionUtils; import org.springframework.stereotype.Service; -import org.thingsboard.server.common.data.notification.info.EdgeFailureNotificationInfo; +import org.thingsboard.server.common.data.notification.info.EdgeCommunicationFailureNotificationInfo; import org.thingsboard.server.common.data.notification.info.RuleOriginatedNotificationInfo; -import org.thingsboard.server.common.data.notification.rule.trigger.EdgeFailureTrigger; -import org.thingsboard.server.common.data.notification.rule.trigger.config.EdgeFailureNotificationRuleTriggerConfig; +import org.thingsboard.server.common.data.notification.rule.trigger.EdgeCommunicationFailureTrigger; +import org.thingsboard.server.common.data.notification.rule.trigger.config.EdgeCommunicationFailureNotificationRuleTriggerConfig; import org.thingsboard.server.common.data.notification.rule.trigger.config.NotificationRuleTriggerType; @Service @RequiredArgsConstructor -public class EdgeFailureTriggerProcessor implements NotificationRuleTriggerProcessor { +public class EdgeCommunicationFailureTriggerProcessor implements NotificationRuleTriggerProcessor { @Override - public boolean matchesFilter(EdgeFailureTrigger trigger, EdgeFailureNotificationRuleTriggerConfig triggerConfig) { + public boolean matchesFilter(EdgeCommunicationFailureTrigger trigger, EdgeCommunicationFailureNotificationRuleTriggerConfig triggerConfig) { if (CollectionUtils.isNotEmpty(triggerConfig.getEdges())) { return !triggerConfig.getEdges().contains(trigger.getEdgeId().getId()); } @@ -37,18 +37,26 @@ public class EdgeFailureTriggerProcessor implements NotificationRuleTriggerProce } @Override - public RuleOriginatedNotificationInfo constructNotificationInfo(EdgeFailureTrigger trigger) { - return EdgeFailureNotificationInfo.builder() + public RuleOriginatedNotificationInfo constructNotificationInfo(EdgeCommunicationFailureTrigger trigger) { + return EdgeCommunicationFailureNotificationInfo.builder() .tenantId(trigger.getTenantId()) .edgeId(trigger.getEdgeId()) .customerId(trigger.getCustomerId()) .edgeName(trigger.getEdgeName()) - .errorMsg(trigger.getErrorMsg()) + .failureMsg(truncateFailureMsg(trigger.getFailureMsg())) .build(); } @Override public NotificationRuleTriggerType getTriggerType() { - return NotificationRuleTriggerType.EDGE_FAILURE; + return NotificationRuleTriggerType.EDGE_COMMUNICATION_FAILURE; + } + + private String truncateFailureMsg(String input) { + int maxLength = 800; + if (input != null && input.length() > maxLength) { + return input.substring(0, maxLength); + } + return input; } } diff --git a/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/EdgeConnectivityTriggerProcessor.java b/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/EdgeConnectionTriggerProcessor.java similarity index 77% rename from application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/EdgeConnectivityTriggerProcessor.java rename to application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/EdgeConnectionTriggerProcessor.java index b5418f6abb..ed1ee74622 100644 --- a/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/EdgeConnectivityTriggerProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/EdgeConnectionTriggerProcessor.java @@ -18,19 +18,19 @@ package org.thingsboard.server.service.notification.rule.trigger; import lombok.RequiredArgsConstructor; import org.apache.commons.collections.CollectionUtils; import org.springframework.stereotype.Service; -import org.thingsboard.server.common.data.notification.info.EdgeConnectivityNotificationInfo; +import org.thingsboard.server.common.data.notification.info.EdgeConnectionNotificationInfo; import org.thingsboard.server.common.data.notification.info.RuleOriginatedNotificationInfo; -import org.thingsboard.server.common.data.notification.rule.trigger.EdgeConnectivityTrigger; -import org.thingsboard.server.common.data.notification.rule.trigger.config.EdgeConnectivityNotificationRuleTriggerConfig; -import org.thingsboard.server.common.data.notification.rule.trigger.config.EdgeConnectivityNotificationRuleTriggerConfig.EdgeConnectivityEvent; +import org.thingsboard.server.common.data.notification.rule.trigger.EdgeConnectionTrigger; +import org.thingsboard.server.common.data.notification.rule.trigger.config.EdgeConnectionNotificationRuleTriggerConfig; +import org.thingsboard.server.common.data.notification.rule.trigger.config.EdgeConnectionNotificationRuleTriggerConfig.EdgeConnectivityEvent; import org.thingsboard.server.common.data.notification.rule.trigger.config.NotificationRuleTriggerType; @Service @RequiredArgsConstructor -public class EdgeConnectivityTriggerProcessor implements NotificationRuleTriggerProcessor { +public class EdgeConnectionTriggerProcessor implements NotificationRuleTriggerProcessor { @Override - public boolean matchesFilter(EdgeConnectivityTrigger trigger, EdgeConnectivityNotificationRuleTriggerConfig triggerConfig) { + public boolean matchesFilter(EdgeConnectionTrigger trigger, EdgeConnectionNotificationRuleTriggerConfig triggerConfig) { EdgeConnectivityEvent event = trigger.isConnected() ? EdgeConnectivityEvent.CONNECTED : EdgeConnectivityEvent.DISCONNECTED; if (CollectionUtils.isEmpty(triggerConfig.getNotifyOn()) || !triggerConfig.getNotifyOn().contains(event)) { return false; @@ -42,8 +42,8 @@ public class EdgeConnectivityTriggerProcessor implements NotificationRuleTrigger } @Override - public RuleOriginatedNotificationInfo constructNotificationInfo(EdgeConnectivityTrigger trigger) { - return EdgeConnectivityNotificationInfo.builder() + public RuleOriginatedNotificationInfo constructNotificationInfo(EdgeConnectionTrigger trigger) { + return EdgeConnectionNotificationInfo.builder() .eventType(trigger.isConnected() ? "connected" : "disconnected") .tenantId(trigger.getTenantId()) .customerId(trigger.getCustomerId()) @@ -54,7 +54,7 @@ public class EdgeConnectivityTriggerProcessor implements NotificationRuleTrigger @Override public NotificationRuleTriggerType getTriggerType() { - return NotificationRuleTriggerType.EDGE_CONNECTIVITY; + return NotificationRuleTriggerType.EDGE_CONNECTION; } } diff --git a/application/src/main/java/org/thingsboard/server/service/sync/ie/exporting/impl/NotificationRuleExportService.java b/application/src/main/java/org/thingsboard/server/service/sync/ie/exporting/impl/NotificationRuleExportService.java index 61897aaa55..40d7d7c2b5 100644 --- a/application/src/main/java/org/thingsboard/server/service/sync/ie/exporting/impl/NotificationRuleExportService.java +++ b/application/src/main/java/org/thingsboard/server/service/sync/ie/exporting/impl/NotificationRuleExportService.java @@ -29,8 +29,8 @@ import org.thingsboard.server.common.data.notification.rule.EscalatedNotificatio import org.thingsboard.server.common.data.notification.rule.NotificationRule; import org.thingsboard.server.common.data.notification.rule.NotificationRuleRecipientsConfig; import org.thingsboard.server.common.data.notification.rule.trigger.config.DeviceActivityNotificationRuleTriggerConfig; -import org.thingsboard.server.common.data.notification.rule.trigger.config.EdgeConnectivityNotificationRuleTriggerConfig; -import org.thingsboard.server.common.data.notification.rule.trigger.config.EdgeFailureNotificationRuleTriggerConfig; +import org.thingsboard.server.common.data.notification.rule.trigger.config.EdgeConnectionNotificationRuleTriggerConfig; +import org.thingsboard.server.common.data.notification.rule.trigger.config.EdgeCommunicationFailureNotificationRuleTriggerConfig; import org.thingsboard.server.common.data.notification.rule.trigger.config.NotificationRuleTriggerConfig; import org.thingsboard.server.common.data.notification.rule.trigger.config.RuleEngineComponentLifecycleEventNotificationRuleTriggerConfig; import org.thingsboard.server.common.data.sync.ie.EntityExportData; @@ -75,13 +75,13 @@ public class NotificationRuleExportService getTemplateData() { @@ -47,7 +46,7 @@ public class EdgeFailureNotificationInfo implements RuleOriginatedNotificationIn "tenantId", tenantId.toString(), "edgeId", edgeId.toString(), "edgeName", edgeName, - "errorMsg", errorMsg + "failureMsg", failureMsg ); } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/notification/info/EdgeConnectivityNotificationInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/info/EdgeConnectionNotificationInfo.java similarity index 95% rename from common/data/src/main/java/org/thingsboard/server/common/data/notification/info/EdgeConnectivityNotificationInfo.java rename to common/data/src/main/java/org/thingsboard/server/common/data/notification/info/EdgeConnectionNotificationInfo.java index 3dfe438ada..e7b6494fdb 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/notification/info/EdgeConnectivityNotificationInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/info/EdgeConnectionNotificationInfo.java @@ -32,7 +32,7 @@ import static org.thingsboard.server.common.data.util.CollectionsUtil.mapOf; @NoArgsConstructor @AllArgsConstructor @Builder -public class EdgeConnectivityNotificationInfo implements RuleOriginatedNotificationInfo { +public class EdgeConnectionNotificationInfo implements RuleOriginatedNotificationInfo { private String eventType; private TenantId tenantId; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/EdgeFailureTrigger.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/EdgeCommunicationFailureTrigger.java similarity index 84% rename from common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/EdgeFailureTrigger.java rename to common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/EdgeCommunicationFailureTrigger.java index 98e1db0527..6400a5c67a 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/EdgeFailureTrigger.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/EdgeCommunicationFailureTrigger.java @@ -27,13 +27,14 @@ import java.util.concurrent.TimeUnit; @Data @Builder -public class EdgeFailureTrigger implements NotificationRuleTrigger { +public class EdgeCommunicationFailureTrigger implements NotificationRuleTrigger { private final TenantId tenantId; private final CustomerId customerId; private final EdgeId edgeId; private final String edgeName; - private final String errorMsg; + private final String failureMsg; + private final String error; @Override public boolean deduplicate() { @@ -42,17 +43,17 @@ public class EdgeFailureTrigger implements NotificationRuleTrigger { @Override public String getDeduplicationKey() { - return String.join(":", NotificationRuleTrigger.super.getDeduplicationKey(), edgeName, errorMsg); + return String.join(":", NotificationRuleTrigger.super.getDeduplicationKey(), edgeId.toString(), error); } @Override public long getDefaultDeduplicationDuration() { - return TimeUnit.HOURS.toMillis(2); + return TimeUnit.MINUTES.toMillis(30); } @Override public NotificationRuleTriggerType getType() { - return NotificationRuleTriggerType.EDGE_FAILURE; + return NotificationRuleTriggerType.EDGE_COMMUNICATION_FAILURE; } @Override diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/EdgeConnectivityTrigger.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/EdgeConnectionTrigger.java similarity index 89% rename from common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/EdgeConnectivityTrigger.java rename to common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/EdgeConnectionTrigger.java index dbbf1e3c74..fe5f6fa6b1 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/EdgeConnectivityTrigger.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/EdgeConnectionTrigger.java @@ -23,12 +23,11 @@ import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.notification.rule.trigger.config.NotificationRuleTriggerType; -import java.util.UUID; import java.util.concurrent.TimeUnit; @Data @Builder -public class EdgeConnectivityTrigger implements NotificationRuleTrigger { +public class EdgeConnectionTrigger implements NotificationRuleTrigger { private final TenantId tenantId; private final CustomerId customerId; @@ -48,12 +47,12 @@ public class EdgeConnectivityTrigger implements NotificationRuleTrigger { @Override public long getDefaultDeduplicationDuration() { - return TimeUnit.HOURS.toMillis(3); + return TimeUnit.MINUTES.toMillis(30); } @Override public NotificationRuleTriggerType getType() { - return NotificationRuleTriggerType.EDGE_CONNECTIVITY; + return NotificationRuleTriggerType.EDGE_CONNECTION; } @Override diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/config/EdgeFailureNotificationRuleTriggerConfig.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/config/EdgeCommunicationFailureNotificationRuleTriggerConfig.java similarity index 85% rename from common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/config/EdgeFailureNotificationRuleTriggerConfig.java rename to common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/config/EdgeCommunicationFailureNotificationRuleTriggerConfig.java index 7dda80b652..595b0fa7d5 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/config/EdgeFailureNotificationRuleTriggerConfig.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/config/EdgeCommunicationFailureNotificationRuleTriggerConfig.java @@ -27,13 +27,13 @@ import java.util.UUID; @NoArgsConstructor @AllArgsConstructor @Builder -public class EdgeFailureNotificationRuleTriggerConfig implements NotificationRuleTriggerConfig { +public class EdgeCommunicationFailureNotificationRuleTriggerConfig implements NotificationRuleTriggerConfig { private Set edges; // if empty - all edges @Override public NotificationRuleTriggerType getTriggerType() { - return NotificationRuleTriggerType.EDGE_FAILURE; + return NotificationRuleTriggerType.EDGE_COMMUNICATION_FAILURE; } } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/config/EdgeConnectivityNotificationRuleTriggerConfig.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/config/EdgeConnectionNotificationRuleTriggerConfig.java similarity index 84% rename from common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/config/EdgeConnectivityNotificationRuleTriggerConfig.java rename to common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/config/EdgeConnectionNotificationRuleTriggerConfig.java index e79f9b0968..8c0905cc59 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/config/EdgeConnectivityNotificationRuleTriggerConfig.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/config/EdgeConnectionNotificationRuleTriggerConfig.java @@ -20,7 +20,6 @@ import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; -import javax.validation.constraints.NotEmpty; import java.util.Set; import java.util.UUID; @@ -28,14 +27,14 @@ import java.util.UUID; @NoArgsConstructor @AllArgsConstructor @Builder -public class EdgeConnectivityNotificationRuleTriggerConfig implements NotificationRuleTriggerConfig { +public class EdgeConnectionNotificationRuleTriggerConfig implements NotificationRuleTriggerConfig { private Set edges; // if empty - all edges private Set notifyOn; @Override public NotificationRuleTriggerType getTriggerType() { - return NotificationRuleTriggerType.EDGE_CONNECTIVITY; + return NotificationRuleTriggerType.EDGE_CONNECTION; } public enum EdgeConnectivityEvent { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/config/NotificationRuleTriggerConfig.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/config/NotificationRuleTriggerConfig.java index ae2130a3f6..15a5e59255 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/config/NotificationRuleTriggerConfig.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/config/NotificationRuleTriggerConfig.java @@ -36,8 +36,8 @@ import java.io.Serializable; @Type(value = EntitiesLimitNotificationRuleTriggerConfig.class, name = "ENTITIES_LIMIT"), @Type(value = ApiUsageLimitNotificationRuleTriggerConfig.class, name = "API_USAGE_LIMIT"), @Type(value = RateLimitsNotificationRuleTriggerConfig.class, name = "RATE_LIMITS"), - @Type(value = EdgeConnectivityNotificationRuleTriggerConfig.class, name = "EDGE_CONNECTIVITY"), - @Type(value = EdgeFailureNotificationRuleTriggerConfig.class, name = "EDGE_FAILURE"), + @Type(value = EdgeConnectionNotificationRuleTriggerConfig.class, name = "EDGE_CONNECTION"), + @Type(value = EdgeCommunicationFailureNotificationRuleTriggerConfig.class, name = "EDGE_COMMUNICATION_FAILURE"), }) public interface NotificationRuleTriggerConfig extends Serializable { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/config/NotificationRuleTriggerType.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/config/NotificationRuleTriggerType.java index 93d26140f0..8469fac752 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/config/NotificationRuleTriggerType.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/config/NotificationRuleTriggerType.java @@ -26,8 +26,8 @@ public enum NotificationRuleTriggerType { ALARM_ASSIGNMENT, DEVICE_ACTIVITY, RULE_ENGINE_COMPONENT_LIFECYCLE_EVENT, - EDGE_CONNECTIVITY, - EDGE_FAILURE, + EDGE_CONNECTION, + EDGE_COMMUNICATION_FAILURE, NEW_PLATFORM_VERSION(false), ENTITIES_LIMIT(false), API_USAGE_LIMIT(false), diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/util/TemplateUtils.java b/common/data/src/main/java/org/thingsboard/server/common/data/util/TemplateUtils.java index 3bc2aac1f8..a6b1c11d42 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/util/TemplateUtils.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/util/TemplateUtils.java @@ -19,6 +19,7 @@ import org.apache.commons.lang3.StringUtils; import java.util.Map; import java.util.function.UnaryOperator; +import java.util.regex.Matcher; import java.util.regex.Pattern; import static com.google.common.base.Strings.nullToEmpty; @@ -49,7 +50,7 @@ public class TemplateUtils { value = FUNCTIONS.get(function).apply(value); } } - return value; + return Matcher.quoteReplacement(value); }); } diff --git a/dao/src/main/java/org/thingsboard/server/dao/notification/DefaultNotificationSettingsService.java b/dao/src/main/java/org/thingsboard/server/dao/notification/DefaultNotificationSettingsService.java index 3e02f42cba..b42fdd7645 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/notification/DefaultNotificationSettingsService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/notification/DefaultNotificationSettingsService.java @@ -189,8 +189,8 @@ public class DefaultNotificationSettingsService implements NotificationSettingsS defaultNotifications.create(tenantId, DefaultNotifications.alarmComment, tenantAdmins.getId()); defaultNotifications.create(tenantId, DefaultNotifications.alarmAssignment, affectedUser.getId()); defaultNotifications.create(tenantId, DefaultNotifications.ruleEngineComponentLifecycleFailure, tenantAdmins.getId()); - defaultNotifications.create(tenantId, DefaultNotifications.edgeConnectivity, tenantAdmins.getId()); - defaultNotifications.create(tenantId, DefaultNotifications.edgeFailure, tenantAdmins.getId()); + defaultNotifications.create(tenantId, DefaultNotifications.edgeConnection, tenantAdmins.getId()); + defaultNotifications.create(tenantId, DefaultNotifications.edgeCommunicationFailures, tenantAdmins.getId()); } @Override @@ -210,7 +210,7 @@ public class DefaultNotificationSettingsService implements NotificationSettingsS defaultNotifications.create(tenantId, DefaultNotifications.exceededPerEntityRateLimits, affectedTenantAdmins.getId()); defaultNotifications.create(tenantId, DefaultNotifications.exceededRateLimitsForSysadmin, sysAdmins.getId()); } else { - List requiredNotificationTypes = List.of(NotificationType.EDGE_CONNECTIVITY, NotificationType.EDGE_FAILURE); + List requiredNotificationTypes = List.of(NotificationType.EDGE_CONNECTION, NotificationType.EDGE_COMMUNICATION_FAILURE); List existingNotificationTypes = notificationTemplateService.findNotificationTemplatesByTenantIdAndNotificationTypes( tenantId, requiredNotificationTypes, new PageLink(1)) .getData() @@ -227,11 +227,11 @@ public class DefaultNotificationSettingsService implements NotificationSettingsS for (NotificationType type : requiredNotificationTypes) { if (!existingNotificationTypes.contains(type)) { switch (type) { - case EDGE_CONNECTIVITY: - defaultNotifications.create(tenantId, DefaultNotifications.edgeConnectivity, tenantAdmins.getId()); + case EDGE_CONNECTION: + defaultNotifications.create(tenantId, DefaultNotifications.edgeConnection, tenantAdmins.getId()); break; - case EDGE_FAILURE: - defaultNotifications.create(tenantId, DefaultNotifications.edgeFailure, tenantAdmins.getId()); + case EDGE_COMMUNICATION_FAILURE: + defaultNotifications.create(tenantId, DefaultNotifications.edgeCommunicationFailures, tenantAdmins.getId()); break; } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/notification/DefaultNotifications.java b/dao/src/main/java/org/thingsboard/server/dao/notification/DefaultNotifications.java index 4e2cc5bbad..1ef0006e87 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/notification/DefaultNotifications.java +++ b/dao/src/main/java/org/thingsboard/server/dao/notification/DefaultNotifications.java @@ -40,9 +40,9 @@ import org.thingsboard.server.common.data.notification.rule.trigger.config.Alarm import org.thingsboard.server.common.data.notification.rule.trigger.config.ApiUsageLimitNotificationRuleTriggerConfig; import org.thingsboard.server.common.data.notification.rule.trigger.config.DeviceActivityNotificationRuleTriggerConfig; import org.thingsboard.server.common.data.notification.rule.trigger.config.DeviceActivityNotificationRuleTriggerConfig.DeviceEvent; -import org.thingsboard.server.common.data.notification.rule.trigger.config.EdgeConnectivityNotificationRuleTriggerConfig; -import org.thingsboard.server.common.data.notification.rule.trigger.config.EdgeConnectivityNotificationRuleTriggerConfig.EdgeConnectivityEvent; -import org.thingsboard.server.common.data.notification.rule.trigger.config.EdgeFailureNotificationRuleTriggerConfig; +import org.thingsboard.server.common.data.notification.rule.trigger.config.EdgeConnectionNotificationRuleTriggerConfig; +import org.thingsboard.server.common.data.notification.rule.trigger.config.EdgeConnectionNotificationRuleTriggerConfig.EdgeConnectivityEvent; +import org.thingsboard.server.common.data.notification.rule.trigger.config.EdgeCommunicationFailureNotificationRuleTriggerConfig; import org.thingsboard.server.common.data.notification.rule.trigger.config.EntitiesLimitNotificationRuleTriggerConfig; import org.thingsboard.server.common.data.notification.rule.trigger.config.EntityActionNotificationRuleTriggerConfig; import org.thingsboard.server.common.data.notification.rule.trigger.config.NewPlatformVersionNotificationRuleTriggerConfig; @@ -328,34 +328,33 @@ public class DefaultNotifications { .description("Send notification to tenant admins when any Rule chain or Rule node failed to start, update or stop") .build()) .build(); - public static final DefaultNotification edgeConnectivity = DefaultNotification.builder() - .name("Edge connectivity notification") - .type(NotificationType.EDGE_CONNECTIVITY) - .subject("Edge '${edgeName}' is ${eventType}") + public static final DefaultNotification edgeConnection = DefaultNotification.builder() + .name("Edge connection notification") + .type(NotificationType.EDGE_CONNECTION) + .subject("Edge connection status change") .text("Edge '${edgeName}' is now ${eventType}") .icon("info").color(null) .button("Go to Edge").link("/edgeManagement/instances/${edgeId}") .rule(DefaultRule.builder() - .name("Edge connectivity") - .enabled(false) - .triggerConfig(EdgeConnectivityNotificationRuleTriggerConfig.builder() + .name("Edge connection status change") + .triggerConfig(EdgeConnectionNotificationRuleTriggerConfig.builder() .edges(null) .notifyOn(Set.of(EdgeConnectivityEvent.CONNECTED, EdgeConnectivityEvent.DISCONNECTED)) .build()) - .description("Send notification to tenant admins when Edge changes its connectivity state") + .description("Send notification to tenant admins when the connection status between TB and Edge changes") .build()) .build(); - public static final DefaultNotification edgeFailure = DefaultNotification.builder() - .name("Edge error notification") - .type(NotificationType.EDGE_FAILURE) - .subject("Edge '${edgeName}' received error") - .text("Error message: '${errorMsg}'") - .icon("error").color(null) + public static final DefaultNotification edgeCommunicationFailures = DefaultNotification.builder() + .name("Edge communication failure notification") + .type(NotificationType.EDGE_COMMUNICATION_FAILURE) + .subject("Edge '${edgeName}' communication failure occured") + .text("Failure message: '${failureMsg}'") + .icon("error").color(RED_COLOR) .button("Go to Edge").link("/edgeManagement/instances/${edgeId}") .rule(DefaultRule.builder() - .name("Edge error") - .triggerConfig(EdgeFailureNotificationRuleTriggerConfig.builder().edges(null).build()) - .description("Send notification to tenant admins or to assigned customers to Edge when error occurs") + .name("Edge communication failure") + .triggerConfig(EdgeCommunicationFailureNotificationRuleTriggerConfig.builder().edges(null).build()) + .description("Send notification to tenant admins when communication failures occur") .build()) .build(); diff --git a/ui-ngx/src/app/modules/home/pages/notification/rule/rule-notification-dialog.component.html b/ui-ngx/src/app/modules/home/pages/notification/rule/rule-notification-dialog.component.html index 852cb7a549..f4ae83143f 100644 --- a/ui-ngx/src/app/modules/home/pages/notification/rule/rule-notification-dialog.component.html +++ b/ui-ngx/src/app/modules/home/pages/notification/rule/rule-notification-dialog.component.html @@ -408,10 +408,10 @@ - + {{ 'notification.edge-trigger-settings' | translate }} -
+
notification.filter @@ -426,9 +426,9 @@ notification.notify-on - - {{ edgeConnectivityEventTranslationMap.get(edgeEvent) | translate }} + placeholder="{{ !edgeConnectionTemplateForm.get('triggerConfig.notifyOn').value?.length ? ('event.all-events' | translate) : '' }}"> + + {{ edgeConnectionEventTranslationMap.get(edgeEvent) | translate }} @@ -445,10 +445,10 @@ - + {{ 'notification.edge-trigger-settings' | translate }} -
+
notification.filter diff --git a/ui-ngx/src/app/modules/home/pages/notification/rule/rule-notification-dialog.component.ts b/ui-ngx/src/app/modules/home/pages/notification/rule/rule-notification-dialog.component.ts index 099897af7c..34ff605027 100644 --- a/ui-ngx/src/app/modules/home/pages/notification/rule/rule-notification-dialog.component.ts +++ b/ui-ngx/src/app/modules/home/pages/notification/rule/rule-notification-dialog.component.ts @@ -68,7 +68,7 @@ import { } from '@shared/models/api-usage.models'; import { LimitedApi, LimitedApiTranslationMap } from '@shared/models/limited-api.models'; import { StringItemsOption } from '@shared/components/string-items-list.component'; -import { EdgeConnectivityEvent, EdgeConnectivityEventTranslationMap } from '@shared/models/edge.models'; +import { EdgeConnectionEvent, EdgeConnectionEventTranslationMap } from '@shared/models/edge.models'; export interface RuleNotificationDialogData { rule?: NotificationRule; @@ -99,8 +99,8 @@ export class RuleNotificationDialogComponent extends apiUsageLimitTemplateForm: FormGroup; newPlatformVersionTemplateForm: FormGroup; rateLimitsTemplateForm: FormGroup; - edgeFailureTemplateForm: FormGroup; - edgeConnectivityTemplateForm: FormGroup; + edgeCommunicationFailureTemplateForm: FormGroup; + edgeConnectionTemplateForm: FormGroup; triggerType = TriggerType; triggerTypes: TriggerType[]; @@ -135,8 +135,8 @@ export class RuleNotificationDialogComponent extends apiFeatures: ApiFeature[] = Object.values(ApiFeature); apiFeatureTranslationMap = ApiFeatureTranslationMap; - edgeConnectivityEvents: EdgeConnectivityEvent[] = Object.values(EdgeConnectivityEvent); - edgeConnectivityEventTranslationMap = EdgeConnectivityEventTranslationMap; + edgeConnectionEvents: EdgeConnectionEvent[] = Object.values(EdgeConnectionEvent); + edgeConnectionEventTranslationMap = EdgeConnectionEventTranslationMap; limitedApis: StringItemsOption[]; @@ -227,14 +227,14 @@ export class RuleNotificationDialogComponent extends } }); - this.edgeConnectivityTemplateForm = this.fb.group({ + this.edgeConnectionTemplateForm = this.fb.group({ triggerConfig: this.fb.group({ edges: [null], notifyOn: [null] }) }); - this.edgeFailureTemplateForm = this.fb.group({ + this.edgeCommunicationFailureTemplateForm = this.fb.group({ triggerConfig: this.fb.group({ edges: [null] }) @@ -348,8 +348,8 @@ export class RuleNotificationDialogComponent extends [TriggerType.API_USAGE_LIMIT, this.apiUsageLimitTemplateForm], [TriggerType.NEW_PLATFORM_VERSION, this.newPlatformVersionTemplateForm], [TriggerType.RATE_LIMITS, this.rateLimitsTemplateForm], - [TriggerType.EDGE_FAILURE, this.edgeFailureTemplateForm], - [TriggerType.EDGE_CONNECTIVITY, this.edgeConnectivityTemplateForm] + [TriggerType.EDGE_COMMUNICATION_FAILURE, this.edgeCommunicationFailureTemplateForm], + [TriggerType.EDGE_CONNECTION, this.edgeConnectionTemplateForm] ]); if (data.isAdd || data.isCopy) { diff --git a/ui-ngx/src/app/shared/models/edge.models.ts b/ui-ngx/src/app/shared/models/edge.models.ts index 4da5f089a0..569b2bec8a 100644 --- a/ui-ngx/src/app/shared/models/edge.models.ts +++ b/ui-ngx/src/app/shared/models/edge.models.ts @@ -191,14 +191,14 @@ export enum EdgeInstructionsMethod { export const edgeVersionAttributeKey = 'edgeVersion'; -export enum EdgeConnectivityEvent { +export enum EdgeConnectionEvent { CONNECTED= 'CONNECTED', DISCONNECTED = 'DISCONNECTED' } -export const EdgeConnectivityEventTranslationMap = new Map( +export const EdgeConnectionEventTranslationMap = new Map( [ - [EdgeConnectivityEvent.CONNECTED, 'edge-event.connected'], - [EdgeConnectivityEvent.DISCONNECTED, 'edge-event.disconnected'] + [EdgeConnectionEvent.CONNECTED, 'edge.connected'], + [EdgeConnectionEvent.DISCONNECTED, 'edge.disconnected'] ] ); diff --git a/ui-ngx/src/app/shared/models/notification.models.ts b/ui-ngx/src/app/shared/models/notification.models.ts index d23e6c5f84..ae945b243c 100644 --- a/ui-ngx/src/app/shared/models/notification.models.ts +++ b/ui-ngx/src/app/shared/models/notification.models.ts @@ -475,8 +475,8 @@ export enum NotificationType { NEW_PLATFORM_VERSION = 'NEW_PLATFORM_VERSION', RULE_NODE = 'RULE_NODE', RATE_LIMITS = 'RATE_LIMITS', - EDGE_CONNECTIVITY = 'EDGE_CONNECTIVITY', - EDGE_FAILURE = 'EDGE_FAILURE' + EDGE_CONNECTION = 'EDGE_CONNECTION', + EDGE_COMMUNICATION_FAILURE = 'EDGE_COMMUNICATION_FAILURE' } export const NotificationTypeIcons = new Map([ @@ -588,16 +588,16 @@ export const NotificationTemplateTypeTranslateMap = new Map([ @@ -628,8 +628,8 @@ export const TriggerTypeTranslationMap = new Map([ [TriggerType.API_USAGE_LIMIT, 'notification.trigger.api-usage-limit'], [TriggerType.NEW_PLATFORM_VERSION, 'notification.trigger.new-platform-version'], [TriggerType.RATE_LIMITS, 'notification.trigger.rate-limits'], - [TriggerType.EDGE_CONNECTIVITY, 'notification.trigger.edge-connectivity'], - [TriggerType.EDGE_FAILURE, 'notification.trigger.edge-failure'] + [TriggerType.EDGE_CONNECTION, 'notification.trigger.edge-connection'], + [TriggerType.EDGE_COMMUNICATION_FAILURE, 'notification.trigger.edge-communication-failure'] ]); export interface NotificationUserSettings { diff --git a/ui-ngx/src/assets/help/en_US/notification/edge_failure.md b/ui-ngx/src/assets/help/en_US/notification/edge_communication_failure.md similarity index 78% rename from ui-ngx/src/assets/help/en_US/notification/edge_failure.md rename to ui-ngx/src/assets/help/en_US/notification/edge_communication_failure.md index d0aaba21a0..03f2a2816a 100644 --- a/ui-ngx/src/assets/help/en_US/notification/edge_failure.md +++ b/ui-ngx/src/assets/help/en_US/notification/edge_communication_failure.md @@ -11,7 +11,7 @@ Available template parameters: * `edgeId` - the edge id as uuid string; * `edgeName` - the name of the edge; -* `errorMsg` - the string representation of the error, occurred on the Edge; +* `failureMsg` - the string representation of the failure, occurred on the Edge; Parameter names must be wrapped using `${...}`. For example: `${edgeName}`. You may also modify the value of the parameter with one of the suffixes: @@ -28,14 +28,14 @@ Let's assume the notification about the failing of processing connection to Edge The following template: ```text -Edge '${edgeName}' received error +Edge '${edgeName}' communication failure occurred {:copy-code} ``` will be transformed to: ```text -Edge 'DatacenterEdge' received error +Edge 'DatacenterEdge' communication failure occurred ```
@@ -43,14 +43,14 @@ Edge 'DatacenterEdge' received error The following template: ```text -Error message: '${errorMsg}' +Failure message: '${failureMsg}' {:copy-code} ``` will be transformed to: ```text -Error message: 'Failed to process edge connection!' +Failure message: 'Failed to process edge connection!' ```
diff --git a/ui-ngx/src/assets/help/en_US/notification/edge_connectivity.md b/ui-ngx/src/assets/help/en_US/notification/edge_connection.md similarity index 84% rename from ui-ngx/src/assets/help/en_US/notification/edge_connectivity.md rename to ui-ngx/src/assets/help/en_US/notification/edge_connection.md index 2044ecf708..fed6c0372e 100644 --- a/ui-ngx/src/assets/help/en_US/notification/edge_connectivity.md +++ b/ui-ngx/src/assets/help/en_US/notification/edge_connection.md @@ -28,30 +28,17 @@ Let's assume the notification about the connecting Edge into the ThingsBoard. The following template: ```text -Edge '${edgeName}' is ${eventType} +Edge '${edgeName}' is now ${eventType} {:copy-code} ``` will be transformed to: ```text -Edge 'DatacenterEdge' is connected +Edge 'DatacenterEdge' is now connected ```
-The following template: - -```text -"Edge '${edgeName}' is now ${eventType}" -{:copy-code} -``` - -will be transformed to: - -```text -Edge 'DatacenterEdge' is now connected -``` -

diff --git a/ui-ngx/src/assets/locale/locale.constant-en_US.json b/ui-ngx/src/assets/locale/locale.constant-en_US.json index 63b791a6ef..74879d0420 100644 --- a/ui-ngx/src/assets/locale/locale.constant-en_US.json +++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json @@ -2030,7 +2030,9 @@ "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}}", "upgrade-instructions": "Upgrade Instructions", - "widget-datasource-error": "This widget supports only EDGE entity datasource" + "widget-datasource-error": "This widget supports only EDGE entity datasource", + "connected": "Connected", + "disconnected": "Disconnected" }, "edge-event": { "type-dashboard": "Dashboard", @@ -2073,9 +2075,7 @@ "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", - "connected": "Connected", - "disconnected": "Disconnected" + "action-type-entity-merge-request": "Entity Merge Request" }, "error": { "unable-to-connect": "Unable to connect to the server! Please check your internet connection.", @@ -3430,8 +3430,8 @@ "rule-node": "Rule node", "new-platform-version": "New platform version", "rate-limits": "Exceeded rate limits", - "edge-failure": "Edge error", - "edge-connectivity": "Edge connectivity" + "edge-communication-failure": "Edge communication failure", + "edge-connection": "Edge connection" }, "templates": "Templates", "notification-templates": "Notifications / Templates", @@ -3452,8 +3452,8 @@ "rule-engine-lifecycle-event": "Rule engine lifecycle event", "new-platform-version": "New platform version", "rate-limits": "Exceeded rate limits", - "edge-connectivity": "Edge connectivity", - "edge-failure": "Edge failure", + "edge-connection": "Edge connection", + "edge-communication-failure": "Edge communication failure", "trigger": "Trigger", "trigger-required": "Trigger is required" }, From ebb2bda32f69ffc0501a0ea6bee3a507ff2783d0 Mon Sep 17 00:00:00 2001 From: Igor Kulikov Date: Wed, 24 Jan 2024 15:25:33 +0200 Subject: [PATCH 131/179] UI: Improve RPC state widget error handling. --- .../system/widget_types/single_switch.json | 2 +- .../widget_types/slide_toggle_control.json | 5 +- ui-ngx/angular.json | 3 +- ui-ngx/src/app/core/api/widget-api.models.ts | 16 +- .../src/app/core/api/widget-subscription.ts | 237 ++++++++++-------- .../config/target-device.component.html | 1 - .../widget/dynamic-widget.component.ts | 2 +- .../widget/lib/rpc/rpc-widget.models.ts | 91 ++++++- .../rpc/single-switch-widget.component.html | 2 +- .../rpc/single-switch-widget.component.scss | 6 +- .../lib/rpc/single-switch-widget.component.ts | 9 +- .../home/models/widget-component.models.ts | 4 +- .../app/shared/components/popover.models.ts | 1 + .../models/rpc-widget-settings.models.ts | 8 +- .../assets/locale/locale.constant-en_US.json | 16 +- 15 files changed, 261 insertions(+), 142 deletions(-) diff --git a/application/src/main/data/json/system/widget_types/single_switch.json b/application/src/main/data/json/system/widget_types/single_switch.json index 3e5edd6f82..7e5440b41d 100644 --- a/application/src/main/data/json/system/widget_types/single_switch.json +++ b/application/src/main/data/json/system/widget_types/single_switch.json @@ -3,7 +3,7 @@ "name": "Single Switch", "deprecated": false, "image": "tb-image:c2luZ2xlLXN3aXRjaC5zdmc=:IlNpbmdsZSBTd2l0Y2giIHN5c3RlbSB3aWRnZXQgaW1hZ2U=;data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAxIiBoZWlnaHQ9IjE2MCIgdmlld0JveD0iMCAwIDIwMSAxNjAiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMF8zNjM5XzE1NTY3NCkiPgo8cmVjdCB4PSIwLjUiIHdpZHRoPSIyMDAiIGhlaWdodD0iMTYwIiByeD0iNCIgZmlsbD0id2hpdGUiLz4KPHJlY3QgeD0iMSIgeT0iMC41IiB3aWR0aD0iMTk5IiBoZWlnaHQ9IjE1OSIgcng9IjMuNSIgc3Ryb2tlPSJibGFjayIgc3Ryb2tlLW9wYWNpdHk9IjAuMTIiLz4KPHJlY3QgeD0iNTUiIHk9IjcwIiB3aWR0aD0iMzguMDk1MiIgaGVpZ2h0PSIxOS45NTQ3IiByeD0iOS45NzczMyIgZmlsbD0iIzU0NjlGRiIvPgo8Y2lyY2xlIGN4PSI4My4xMTY0IiBjeT0iNzkuOTc3MiIgcj0iOC4xNjMyNyIgZmlsbD0id2hpdGUiLz4KPHBhdGggZD0iTTEwNi42OTQgODEuNzUzNEMxMDYuNjk0IDgxLjUzMzcgMTA2LjY2IDgxLjMzODQgMTA2LjU5MiA4MS4xNjc1QzEwNi41MjggODAuOTk2NiAxMDYuNDE0IDgwLjg0MDMgMTA2LjI0OCA4MC42OTg3QzEwNi4wODIgODAuNTU3MSAxMDUuODQ3IDgwLjQyMDQgMTA1LjU0NCA4MC4yODg2QzEwNS4yNDcgODAuMTUxOSAxMDQuODY2IDgwLjAxMjcgMTA0LjQwMiA3OS44NzExQzEwMy44OTQgNzkuNzE0OCAxMDMuNDI1IDc5LjU0MTUgMTAyLjk5NiA3OS4zNTExQzEwMi41NzEgNzkuMTU1OCAxMDIuMiA3OC45MzEyIDEwMS44ODIgNzguNjc3MkMxMDEuNTY1IDc4LjQxODUgMTAxLjMxOCA3OC4xMjMgMTAxLjE0MyA3Ny43OTFDMTAwLjk2NyA3Ny40NTQxIDEwMC44NzkgNzcuMDY1OSAxMDAuODc5IDc2LjYyNjVDMTAwLjg3OSA3Ni4xOTE5IDEwMC45NjkgNzUuNzk2NCAxMDEuMTUgNzUuNDM5OUMxMDEuMzM1IDc1LjA4MzUgMTAxLjU5NyA3NC43NzU5IDEwMS45MzQgNzQuNTE3MUMxMDIuMjc1IDc0LjI1MzQgMTAyLjY3OCA3NC4wNTA4IDEwMy4xNDIgNzMuOTA5MkMxMDMuNjA2IDczLjc2MjcgMTA0LjExOSA3My42ODk1IDEwNC42OCA3My42ODk1QzEwNS40NzEgNzMuNjg5NSAxMDYuMTUyIDczLjgzNTkgMTA2LjcyNCA3NC4xMjg5QzEwNy4zIDc0LjQyMTkgMTA3Ljc0MiA3NC44MTQ5IDEwOC4wNDkgNzUuMzA4MUMxMDguMzYyIDc1LjgwMTMgMTA4LjUxOCA3Ni4zNDU3IDEwOC41MTggNzYuOTQxNEgxMDYuNjk0QzEwNi42OTQgNzYuNTg5OCAxMDYuNjE5IDc2LjI3OTggMTA2LjQ2NyA3Ni4wMTEyQzEwNi4zMjEgNzUuNzM3OCAxMDYuMDk2IDc1LjUyMjkgMTA1Ljc5MyA3NS4zNjY3QzEwNS40OTYgNzUuMjEwNCAxMDUuMTE3IDc1LjEzMjMgMTA0LjY1OCA3NS4xMzIzQzEwNC4yMjQgNzUuMTMyMyAxMDMuODYyIDc1LjE5ODIgMTAzLjU3NCA3NS4zMzAxQzEwMy4yODYgNzUuNDYxOSAxMDMuMDcxIDc1LjY0MDEgMTAyLjkzIDc1Ljg2NDdDMTAyLjc4OCA3Ni4wODk0IDEwMi43MTcgNzYuMzQzMyAxMDIuNzE3IDc2LjYyNjVDMTAyLjcxNyA3Ni44MjY3IDEwMi43NjQgNzcuMDA5OCAxMDIuODU2IDc3LjE3NThDMTAyLjk0OSA3Ny4zMzY5IDEwMy4wOTEgNzcuNDg4MyAxMDMuMjgxIDc3LjYyOTlDMTAzLjQ3MiA3Ny43NjY2IDEwMy43MTEgNzcuODk2IDEwMy45OTkgNzguMDE4MUMxMDQuMjg3IDc4LjE0MDEgMTA0LjYyNiA3OC4yNTczIDEwNS4wMTcgNzguMzY5NkMxMDUuNjA4IDc4LjU0NTQgMTA2LjEyMyA3OC43NDA3IDEwNi41NjIgNzguOTU1NkMxMDcuMDAyIDc5LjE2NTUgMTA3LjM2OCA3OS40MDQ4IDEwNy42NjEgNzkuNjczM0MxMDcuOTU0IDc5Ljk0MTkgMTA4LjE3NCA4MC4yNDcxIDEwOC4zMiA4MC41ODg5QzEwOC40NjcgODAuOTI1OCAxMDguNTQgODEuMzA5MSAxMDguNTQgODEuNzM4OEMxMDguNTQgODIuMTg4IDEwOC40NSA4Mi41OTMzIDEwOC4yNjkgODIuOTU0NkMxMDguMDg4IDgzLjMxMSAxMDcuODMgODMuNjE2MiAxMDcuNDkzIDgzLjg3MDFDMTA3LjE2MSA4NC4xMTkxIDEwNi43NiA4NC4zMTIgMTA2LjI5MiA4NC40NDg3QzEwNS44MjggODQuNTgwNiAxMDUuMzEgODQuNjQ2NSAxMDQuNzM5IDg0LjY0NjVDMTA0LjIyNiA4NC42NDY1IDEwMy43MjEgODQuNTc4MSAxMDMuMjIzIDg0LjQ0MTRDMTAyLjcyOSA4NC4zMDQ3IDEwMi4yOCA4NC4wOTcyIDEwMS44NzUgODMuODE4OEMxMDEuNDcgODMuNTM1NiAxMDEuMTQ3IDgzLjE4NDEgMTAwLjkwOCA4Mi43NjQyQzEwMC42NjkgODIuMzM5NCAxMDAuNTQ5IDgxLjg0MzggMTAwLjU0OSA4MS4yNzczSDEwMi4zODhDMTAyLjM4OCA4MS42MjQgMTAyLjQ0NiA4MS45MTk0IDEwMi41NjMgODIuMTYzNkMxMDIuNjg2IDgyLjQwNzcgMTAyLjg1NCA4Mi42MDc5IDEwMy4wNjkgODIuNzY0MkMxMDMuMjg0IDgyLjkxNTUgMTAzLjUzMyA4My4wMjc4IDEwMy44MTYgODMuMTAxMUMxMDQuMTA0IDgzLjE3NDMgMTA0LjQxMiA4My4yMTA5IDEwNC43MzkgODMuMjEwOUMxMDUuMTY4IDgzLjIxMDkgMTA1LjUyNyA4My4xNDk5IDEwNS44MTUgODMuMDI3OEMxMDYuMTA4IDgyLjkwNTggMTA2LjMyOCA4Mi43MzQ5IDEwNi40NzUgODIuNTE1MUMxMDYuNjIxIDgyLjI5NTQgMTA2LjY5NCA4Mi4wNDE1IDEwNi42OTQgODEuNzUzNFpNMTEyLjE0NCA4Mi43NDIyTDExMy45NzUgNzYuNTc1MkgxMTUuMTAzTDExNC43OTUgNzguNDIwOUwxMTIuOTQ5IDg0LjVIMTExLjkzOEwxMTIuMTQ0IDgyLjc0MjJaTTExMS4wNjcgNzYuNTc1MkwxMTIuNDk1IDgyLjc3MTVMMTEyLjYxMiA4NC41SDExMS40ODRMMTA5LjMzOCA3Ni41NzUySDExMS4wNjdaTTExNi44MTYgODIuNjk4MkwxMTguMjAxIDc2LjU3NTJIMTE5LjkyMkwxMTcuNzgzIDg0LjVIMTE2LjY1NUwxMTYuODE2IDgyLjY5ODJaTTExNS4yOTMgNzYuNTc1MkwxMTcuMTAyIDgyLjY2ODlMMTE3LjMyOSA4NC41SDExNi4zMThMMTE0LjQ1MSA3OC40MTM2TDExNC4xNDMgNzYuNTc1MkgxMTUuMjkzWk0xMjMuMDEzIDc2LjU3NTJWODQuNUgxMjEuMjRWNzYuNTc1MkgxMjMuMDEzWk0xMjEuMTIzIDc0LjQ5NTFDMTIxLjEyMyA3NC4yMjY2IDEyMS4yMTEgNzQuMDA0NCAxMjEuMzg3IDczLjgyODZDMTIxLjU2NyA3My42NDc5IDEyMS44MTYgNzMuNTU3NiAxMjIuMTM0IDczLjU1NzZDMTIyLjQ0NiA3My41NTc2IDEyMi42OTMgNzMuNjQ3OSAxMjIuODc0IDczLjgyODZDMTIzLjA1NCA3NC4wMDQ0IDEyMy4xNDUgNzQuMjI2NiAxMjMuMTQ1IDc0LjQ5NTFDMTIzLjE0NSA3NC43NTg4IDEyMy4wNTQgNzQuOTc4NSAxMjIuODc0IDc1LjE1NDNDMTIyLjY5MyA3NS4zMzAxIDEyMi40NDYgNzUuNDE4IDEyMi4xMzQgNzUuNDE4QzEyMS44MTYgNzUuNDE4IDEyMS41NjcgNzUuMzMwMSAxMjEuMzg3IDc1LjE1NDNDMTIxLjIxMSA3NC45Nzg1IDEyMS4xMjMgNzQuNzU4OCAxMjEuMTIzIDc0LjQ5NTFaTTEyOC41NzkgNzYuNTc1MlY3Ny44NjQzSDEyNC4xMTFWNzYuNTc1MkgxMjguNTc5Wk0xMjUuNCA3NC42MzQzSDEyNy4xNjZWODIuMzEwMUMxMjcuMTY2IDgyLjU1NDIgMTI3LjIgODIuNzQyMiAxMjcuMjY4IDgyLjg3NEMxMjcuMzQxIDgzLjAwMSAxMjcuNDQxIDgzLjA4NjQgMTI3LjU2OCA4My4xMzA0QzEyNy42OTUgODMuMTc0MyAxMjcuODQ0IDgzLjE5NjMgMTI4LjAxNSA4My4xOTYzQzEyOC4xMzcgODMuMTk2MyAxMjguMjU0IDgzLjE4OSAxMjguMzY3IDgzLjE3NDNDMTI4LjQ3OSA4My4xNTk3IDEyOC41NjkgODMuMTQ1IDEyOC42MzggODMuMTMwNEwxMjguNjQ1IDg0LjQ3OEMxMjguNDk5IDg0LjUyMiAxMjguMzI4IDg0LjU2MSAxMjguMTMyIDg0LjU5NTJDMTI3Ljk0MiA4NC42Mjk0IDEyNy43MjIgODQuNjQ2NSAxMjcuNDczIDg0LjY0NjVDMTI3LjA2OCA4NC42NDY1IDEyNi43MDkgODQuNTc1NyAxMjYuMzk2IDg0LjQzNDFDMTI2LjA4NCA4NC4yODc2IDEyNS44NCA4NC4wNTA4IDEyNS42NjQgODMuNzIzNkMxMjUuNDg4IDgzLjM5NjUgMTI1LjQgODIuOTYxOSAxMjUuNCA4Mi40MTk5Vjc0LjYzNDNaTTEzMy4xNzkgODMuMjQwMkMxMzMuNDY3IDgzLjI0MDIgMTMzLjcyNiA4My4xODQxIDEzMy45NTUgODMuMDcxOEMxMzQuMTg5IDgyLjk1NDYgMTM0LjM3NyA4Mi43OTM1IDEzNC41MTkgODIuNTg4NEMxMzQuNjY2IDgyLjM4MzMgMTM0Ljc0NiA4Mi4xNDY1IDEzNC43NjEgODEuODc3OUgxMzYuNDIzQzEzNi40MTQgODIuMzkwNiAxMzYuMjYyIDgyLjg1NjkgMTM1Ljk2OSA4My4yNzY5QzEzNS42NzYgODMuNjk2OCAxMzUuMjg4IDg0LjAzMTIgMTM0LjgwNSA4NC4yODAzQzEzNC4zMjEgODQuNTI0NCAxMzMuNzg3IDg0LjY0NjUgMTMzLjIwMSA4NC42NDY1QzEzMi41OTUgODQuNjQ2NSAxMzIuMDY4IDg0LjU0MzkgMTMxLjYxOSA4NC4zMzg5QzEzMS4xNjkgODQuMTI4OSAxMzAuNzk2IDgzLjg0MDggMTMwLjQ5OCA4My40NzQ2QzEzMC4yIDgzLjEwODQgMTI5Ljk3NiA4Mi42ODYgMTI5LjgyNCA4Mi4yMDc1QzEyOS42NzggODEuNzI5IDEyOS42MDQgODEuMjE2MyAxMjkuNjA0IDgwLjY2OTRWODAuNDEzMUMxMjkuNjA0IDc5Ljg2NjIgMTI5LjY3OCA3OS4zNTM1IDEyOS44MjQgNzguODc1QzEyOS45NzYgNzguMzkxNiAxMzAuMiA3Ny45NjY4IDEzMC40OTggNzcuNjAwNkMxMzAuNzk2IDc3LjIzNDQgMTMxLjE2OSA3Ni45NDg3IDEzMS42MTkgNzYuNzQzN0MxMzIuMDY4IDc2LjUzMzcgMTMyLjU5MyA3Ni40Mjg3IDEzMy4xOTMgNzYuNDI4N0MxMzMuODI4IDc2LjQyODcgMTM0LjM4NSA3Ni41NTU3IDEzNC44NjMgNzYuODA5NkMxMzUuMzQyIDc3LjA1ODYgMTM1LjcxOCA3Ny40MDc3IDEzNS45OTEgNzcuODU2OUMxMzYuMjcgNzguMzAxMyAxMzYuNDE0IDc4LjgxODggMTM2LjQyMyA3OS40MDk3SDEzNC43NjFDMTM0Ljc0NiA3OS4xMTY3IDEzNC42NzMgNzguODUzIDEzNC41NDEgNzguNjE4N0MxMzQuNDE0IDc4LjM3OTQgMTM0LjIzMyA3OC4xODkgMTMzLjk5OSA3OC4wNDc0QzEzMy43NyA3Ny45MDU4IDEzMy40OTQgNzcuODM1IDEzMy4xNzEgNzcuODM1QzEzMi44MTUgNzcuODM1IDEzMi41MiA3Ny45MDgyIDEzMi4yODUgNzguMDU0N0MxMzIuMDUxIDc4LjE5NjMgMTMxLjg2OCA3OC4zOTE2IDEzMS43MzYgNzguNjQwNkMxMzEuNjA0IDc4Ljg4NDggMTMxLjUwOSA3OS4xNjA2IDEzMS40NSA3OS40NjgzQzEzMS4zOTYgNzkuNzcxIDEzMS4zNyA4MC4wODU5IDEzMS4zNyA4MC40MTMxVjgwLjY2OTRDMTMxLjM3IDgwLjk5NjYgMTMxLjM5NiA4MS4zMTQgMTMxLjQ1IDgxLjYyMTZDMTMxLjUwNCA4MS45MjkyIDEzMS41OTcgODIuMjA1MSAxMzEuNzI5IDgyLjQ0OTJDMTMxLjg2NSA4Mi42ODg1IDEzMi4wNTEgODIuODgxMyAxMzIuMjg1IDgzLjAyNzhDMTMyLjUyIDgzLjE2OTQgMTMyLjgxNyA4My4yNDAyIDEzMy4xNzkgODMuMjQwMlpNMTM5LjUyMSA3My4yNVY4NC41SDEzNy43NjRWNzMuMjVIMTM5LjUyMVpNMTM5LjIxNCA4MC4yNDQ2TDEzOC42NDMgODAuMjM3M0MxMzguNjQ3IDc5LjY5MDQgMTM4LjcyMyA3OS4xODUxIDEzOC44NyA3OC43MjEyQzEzOS4wMjEgNzguMjU3MyAxMzkuMjMxIDc3Ljg1NDUgMTM5LjUgNzcuNTEyN0MxMzkuNzczIDc3LjE2NiAxNDAuMSA3Ni44OTk5IDE0MC40ODEgNzYuNzE0NEMxNDAuODYyIDc2LjUyMzkgMTQxLjI4NCA3Ni40Mjg3IDE0MS43NDggNzYuNDI4N0MxNDIuMTM5IDc2LjQyODcgMTQyLjQ5IDc2LjQ4MjQgMTQyLjgwMyA3Ni41ODk4QzE0My4xMiA3Ni42OTczIDE0My4zOTQgNzYuODcwNiAxNDMuNjIzIDc3LjEwOTlDMTQzLjg1MyA3Ny4zNDQyIDE0NC4wMjYgNzcuNjUxOSAxNDQuMTQzIDc4LjAzMjdDMTQ0LjI2NSA3OC40MDg3IDE0NC4zMjYgNzguODY3NyAxNDQuMzI2IDc5LjQwOTdWODQuNUgxNDIuNTU0Vjc5LjM5NUMxNDIuNTU0IDc5LjAxNDIgMTQyLjQ5OCA3OC43MTE0IDE0Mi4zODUgNzguNDg2OEMxNDIuMjc4IDc4LjI2MjIgMTQyLjExOSA3OC4xMDExIDE0MS45MDkgNzguMDAzNEMxNDEuNjk5IDc3LjkwMDkgMTQxLjQ0MyA3Ny44NDk2IDE0MS4xNCA3Ny44NDk2QzE0MC44MjMgNzcuODQ5NiAxNDAuNTQyIDc3LjkxMzEgMTQwLjI5OCA3OC4wNEMxNDAuMDU5IDc4LjE2NyAxMzkuODU4IDc4LjM0MDMgMTM5LjY5NyA3OC41NjAxQzEzOS41MzYgNzguNzc5OCAxMzkuNDE0IDc5LjAzMzcgMTM5LjMzMSA3OS4zMjE4QzEzOS4yNTMgNzkuNjA5OSAxMzkuMjE0IDc5LjkxNzUgMTM5LjIxNCA4MC4yNDQ2WiIgZmlsbD0iYmxhY2siIGZpbGwtb3BhY2l0eT0iMC44NyIvPgo8L2c+CjxkZWZzPgo8Y2xpcFBhdGggaWQ9ImNsaXAwXzM2MzlfMTU1Njc0Ij4KPHJlY3QgeD0iMC41IiB3aWR0aD0iMjAwIiBoZWlnaHQ9IjE2MCIgcng9IjQiIGZpbGw9IndoaXRlIi8+CjwvY2xpcFBhdGg+CjwvZGVmcz4KPC9zdmc+Cg==", - "description": "Sends the RPC call to the device or updates attribute/time-series when the user toggles the slider. Widget settings will enable you to configure behavior how to fetch the initial state and what to trigger when turn on/off states.", + "description": "Sends the command to the device or updates attribute/time-series when the user toggles the slider. Widget settings will enable you to configure behavior how to fetch the initial state and what to trigger when turn on/off states.", "descriptor": { "type": "rpc", "sizeX": 3.5, diff --git a/application/src/main/data/json/system/widget_types/slide_toggle_control.json b/application/src/main/data/json/system/widget_types/slide_toggle_control.json index 208c5536c4..5909ba7a9f 100644 --- a/application/src/main/data/json/system/widget_types/slide_toggle_control.json +++ b/application/src/main/data/json/system/widget_types/slide_toggle_control.json @@ -1,8 +1,8 @@ { "fqn": "control_widgets.slide_toggle_control", "name": "Slide Toggle Control", - "deprecated": false, - "image": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAACgCAYAAABJ/yOpAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAFNpJREFUeJzt3Xl0VOX9x/H3bJnJJGEggRhC2EUQgoI/ZNEiUIRqfhyFspt6emqlsQZKldNjW7GgovTElgiCFKlWq4hxQxCU2AK2CKksSRP5AQEiECDNHgLJTGYyy++P6VxnkvBkD/b0+zonJ5M7d577zM39zH2e5y6j8/l8PoQQTdJf7woI8W0mARFCQQIihIIERAgFCYgQChIQIRQkIEIoSECEUJCACKEgARFCQQIihIIERAgFCYgQChIQIRQkIEIoSECEUJCACKEgARFCQQIihIIERAgFCYgQChIQIRQkIEIoSECEUJCACKEgARFCQQIihIIERAgFCYgQChIQIRQkIEIoSECEUJCACKEgARFCQQIihIIERAgFCYgQChIQIRQkIEIoSECEUJCACKEgARFCQQIihIIERAgFCYgQChIQIRQkIEIoSECEUJCACKEgARFCQQIihIIERAgFCYgQChIQIRQkIEIoSECEUJCACKFgvN4VCObz+Vo1v06n66SaCOF33QPSMBQtDYlOpwuZV8IiOsN1C0jwxh147PP5mpweEBwCnU6n/R0Ii4REdLTrEpCGgWj4EzxPQ8GhaPjTcB4h2qtLA6IKhtfrxev1cvmqndxTFzlTWMqlsss4XW4ArJYwEm7owZB+sdx6UwIR4Wb0ej16vR6dTodeHzreICERHaHLAtJUOAKh8Hg8fJFzhg/25nD0RCFer7ofYjLqGT9yIPOnj2HU0L4YDAZ8Pp8WlmASFNEeOl9rh47aIDgcXq9X++3xeDh25hIvv/s3ck9falPZtw3ry5IFk7mpfxwGgyFkrxLcHBOiLTo9IA3DEQhGfX09b31yiFc/Ooi3nVUwGPSkzr2LedPHYDAYtKA01T8RojW6JCANw1FT6+C5Vz/lb9lnOnRZs6bcwtKFUwkLM2E0GiUkot2u2Qdx1bv5+mIZX18qp/JyDbV1LhxOV6sKD+13ePF6PLjd9RzMPcfFsivtq3kTtu3LQwcsfWAqgBaSAAmJaK1GAfF4vOSeusChY2epc9W3ueCG4fB5fXg8HnJPX+qUcAR8uC+Pvjf0YM60MY36IkK0VkhAHE4XO/+ex6XSqo5bgs8HPvB43BSVVnGqsKLjyr6GDe/tZ9TQvtw0oPe3/hjJxYsX2bhxIwCjRo1i7ty52nOnT5/GYrHQt2/fFpW1atUqHA4H4eHhLF++vFPq+5+ioKCA1157DYCxY8dy//33t6kcLSC1dicZnx3mSq2j3ZUL2Xvgw+v14HG7ySsopvPHzMDt8fLKh/t5fvFMLSBNDQF3lpycHLZu3crhw4epqqrCYrGQkJDAPffcwwMPPIDVatXmraioYOvWrQA4HA4tIG+88QZPP/00er2eTZs2MXXq1GaX+8EHH1BdXY3NZvuvD0hJSYm2XvV6ffsC4vF62fn33A4JRwifD5/X30E//68KqmucHVu+QtZX58k5eZ7bEwdrx0kCwe3MoKSlpbFp06aQMwGuXLlCaWkp2dnZvPXWW7z++usMGDBAWc7JkycB8Hq95Ofntyggnekvf/kLn3/+OQALFy4kMTHxutanqxgBsk+c518V1R1acGDv4fN58bjdnLrQ+U2rht757CijhvbDYDB0yd7j448/5g9/+AMAFouF5ORkRowYQU1NDR999BHZ2dkUFhayaNEidu/ejcFguGZZS5cuRafTER4ezoMPPtjpdW/OV199pX0i33HHHf89AXG66jnyf+c6rMCQUWOf/+8rNQ4ud+HeI+DoiUvU1DoICwvT9iCdeWLju+++qz1evXp1yG594cKFzJ07l3/+858UFBSwd+9epk2bds2y4uLieP755zu8jqJ1jAUXynDWuzu+5H+PXnk8bkoqO2/USsXj9XLo2FnunpCoHTzszLN+y8vLtcfDhw8Pec5gMJCcnIzb7V/Xly9fVpa1fft23n//fQBSUlL4zne+oz1XWlrKiy++yBdffIHL5WLkyJEsW7ZMWV5hYSGbN28mKyuLqqoqevXqxXe/+10WLVpEjx49rvm67Oxs0tPTKSws1KatX7+ed955J6ReHo+HjIwMtm/fzvnz59Hr9QwZMoR58+aRlJTU5DrfsWMHb775JufOnSMqKopp06YxZ84cnnnmGQDmz5/PjBkztPkrKyt56aWX2LdvH3a7nYEDB5KSksK5c+fYt28fAK+//rpyzxyQk5PDn/70J3JycqirqyMhIYEZM2bw4IMPEhYWps1n/PpiWbOFtZXP58Pr8VB5tYP7Nq1w9OR5Jt8+LORNd5bBgweTn58P+DeitLQ0zGaz9vzs2bOZPXt2i8q6cOECBw4cAGDWrFna9OLiYr7//e9TXFysTduzZw9ZWVnU1zc9LH/gwAFSUlKw2+3atKqqKk6dOsWOHTvIyMigT58+Tb62srJSq0dAfn4++fn5zJw5E4Da2lp+/OMfc+jQoZD5iouL2b9/P5988gnr1q0L2XDT0tK05ij4Bys2b97M9u3bKS0tBeDOO+/Uni8pKWHu3LlcvHhRm1ZeXs6RI0fo2bMnZWUt347feOMNnnnmmZDWTkVFBbm5uezevZs333wTi8UCgL68uqbFBbeWD39IHHVtP57SXkWlV/B4PK2+WrEtUlJSMJlMgL8/MnXqVF5++eWQf2p7Pfvss1o4hg0bRlpaGk8++SQ2m63JgJSXl7NkyRLsdjt6vZ7FixezYcMGkpOT0el0FBUV8eSTT15zeSNHjmT9+vV873vf06Y99NBDrF+/nnHjxgH+4eVAOBITE1mzZg2rV6+mX79+AHz66afaUDb4P703bdoE+EeYFi1aRHp6OsnJySF74WCrVq3S1uOgQYNYvXo1K1asYOjQoa0KR3Z2Ns8++yw+n4+oqCh+85vfsHbtWiZPngzA0aNH2bBhgza/sdbeOX0DH98M9brc3k5ZRkvU1jmbvcako4wcOZI//vGPPPHEExQXF1NUVMTvfvc71qxZw7hx43jggQeu2dxoicrKSj777DMAbDYbW7Zs0ZpH99xzD1OmTNGacAFbtmzRmnNLly5lyZIlANx7771UV1ezc+dO9u/fT2FhobZBB7vhhhtISkri5MmTZGZmAjB69GiSkpIA/yd7oCkYFxfHli1biIqKAuCuu+7i7rvvxuFw8Oqrr7Jo0SLMZjNbt27V/hePPfYYqampANx///107949ZAMNvO/du3cDEBUVxTvvvEPPnj0BmDt3LhMnTqSqqmXH7jZs2IDX698eg4ORlJTE9OnTOXv2LG+//TaPPfaY/8TXFpXaTtfz0FxX7DmCTZw4kb/+9a88/vjj2gE+r9dLVlYWS5Ys4Yc//GFI86g18vLy8Hg8AEybNi2k79CnTx8iIiIavSYwNAv+Nn2wCRMmAP51lJOT06Y6HTx4UKvTzJkztXAA9O7dm+nTpwNQXV1Nbm4uAIcPHwb8e48f/OAHIeUlJCQ0WkZOTo62jHvvvVcLB4DVaiUmJqZFda2vrycrKwvwh3nSpEnacwaDgfHjxwP+5ue5c+cAMFrDzVTX2BsV1pGMhusXEavF3PxMHb1Mq5XFixeTmprKl19+yYcffsiOHTtwuVx88cUX/OhHP2LHjh1ac6ylgpsS/fv3b9Frgpt3gQ2gKddq2jTn0qVvLlMYPHhwo+cHDRoUUpexY8dq7yMmJgabzdbsMoI/UILLa62ysjLq6uq0Mpuqb0B5eTmDBg3CGN0totMDEm42AV0/zAtwQ3TkdVku+A9Ijh8/nvHjx5OamkpycjJFRUXk5+eTmZkZMkLTEoFPUfCfiNkSTuc36121MTa8IrMtdWoq8MHTAvMGmoEt/YAINIla85qmBK8Lg8FAZGTz24ZxUEIvzhZ1/EiWjm8uVuoW3vY31V4jB8d1yYVTBw4cYPHixYD/QFrDdnT//v1JTk7mhRdeAODEiROtDkhwk6qkpKRFr4mOjqamxj8Qs3///hZtFK0RGxurPQ7emzQ1LTBvdHQ0xcXFlJaW4nK5mh1hDG5CNbWMloqOjtYe9+vXjz179jT7Gv2N/WIxtWDcuC0Cm2OMzdIp5TdHr4Nbboz316WTj6QPHDiQq1evUl1dTVZWVpNNloqKb84mCD4fq6VGjhypvY89e/aEfHrX1taGfEIGjB07VnscOBIe7NixY1qzo6WClxtc/q5du0I+7Z1Op9axDwsLY/To0QDab7fbrXW+g99HQ7feeqv2vnfv3h0yWuf1ekOGr1VsNhtDhw4F4OzZs1p/JNjRo0dD+q36cLOJ24a3rD3bNjoiw01EWrr+Bio3D+iF1WJqc/OhNeLj47WRncuXL7Nw4ULee+898vLyyMrKYu3atfz5z38G/GENjJ60dhmBodULFy7w85//nBMnTnD48GFSUlKa3NAfeugh7fjDCy+8wEsvvcTx48c5deoUGzduZMGCBTzyyCO4XOprfbp166Y9/vTTT8nLy9Pa8XfddRcAx48f5xe/+AWnT5/m+PHjpKSkaB8Us2fP1sqYM2eOVtZTTz3Fzp07OX36NB988AHr1q1rtOw+ffpo/aeioiJ++tOfcuzYMXJzc1m2bBlFRUUtXoc/+clPtMePPvooGRkZnDlzhry8PFauXMn8+fP57W9/q81jBBgzfABnzpdQcaVxetss6Cxavd5Av14RHL/Qsed7Ned/J9yEyWTSzsXq7GtDVq1aRWlpKYcOHaKgoIAnnniiyflSU1MZMWJEm5axfPly5s2bh91uZ9euXezatQvw9yEiIyO15lTAsGHDWLlyJStWrMDtdpOenk56enrIPC1ZLxMmTNBO08nMzCQzM5Nly5aRmprK888/z7x58ygqKmLbtm1s27Yt5LVDhw4NWRdTpkwhKSmJTz75hKtXr/Kzn/1Me+5aR8FXrlzJ7NmzqampYe/evezduzfkNcF7NZVZs2Zx5MgRtm7dSnV1Nb/61a8azRO8LvQAJqOB+6aM/ndnun1Cr73QYzAaMZpM9O0VSYS5c5pyTUkc2ItRN/XBbDaHXH7bsI4dqVu3bmzZsoW0tDTGjBkT0pE2m81MmDCBzZs38/jjj2vTDQYDNpsNm80W0uyyWCza9OA2+vDhw3nrrbe45ZZbtGnx8fGsW7eOyZMnY7PZQj7tAZKTk3n77be58847Q+rUu3dvVqxYwSuvvNJs53fEiBEsX748pA8TOEsgPj6ebdu2sWDBgpBlR0dH8/DDD/Puu+82qtOaNWt45JFHtGFhvV7P1KlTtX5cYN0EDBkyhIyMDG6//Xbt/xcTE8OKFSu0Eb3g/6vRaNTWX+CoeMBzzz1Heno6iYmJIa+5+eab2bhxI7/85S+1aSHXpFdfdbDj85x270m0A3NeL26PG1edA3ttDUWl1eSe7/y9iE4HTz80hRE3JmCz2YiIiGh0jXpXqK+vp6KiAr1eT3R0dItHnlqquroap9NJz549W9yMdLlcVFZWYjabledgXYvb7aasrAyr1drkqJjH49Hec0xMTLPr2u12U15eTrdu3bBarSGnoLz44ovcd999jV5TU1NDTU0NvXr1wuPxcNttt2G324mNjeUf//hHq96Pw+GgoqKCHj16NHkcKWSt2qLCmX/POMYMH4CxIzruOh16nR69wYjRaOKGaCsJMZ3fYZ8z6WZu7NsLi8VCWFjYdbt5g8lkIi4ujtjY2A4PB/g7nbGxsa3qY4WFhREXF9emcID/k7l3797XHDI2GAzExsbSs2dP5bp+7bXXWLlyJW63m7i4OKxWKwUFBWRkZGjLCR4AsNvtLFiwgC+//JLIyEji4uLQ6/WsXbtW66TfcccdrX4/4eHhJCQkNBkOUNzVpMbu5FRhCV9fLKPycg32Nt6wIXA1octZR53DTp3DQXZBJVW1nXN+1vgRfXh01jgiIyO1Zsv12HuIaysuLmbSpEnU19fTvXt3Ro8eTV1dHUeOHNFGqB5++GF+/etfa68J3rMMHz6c+Ph4zpw5ox3xjoyM5KOPPmrXgcSmtPi2P16vj3p3yzpCEBwQ/61+6urqqK2t4cqVq1RUVrPp46PkX6hsW62vYezN8Tw843/o0b0b3bp1IyIigrCwsJBOuvh2eO+99/j973+vnbkbYDKZSElJYenSpSF9kKqqKp566ikyMzMbdchvvPFG0tLSGDVqVIfXs1PvixV8Tyy3243dbufKlSvU1NRQV+fk/c//j8zDZ9u9HJ0OZkwYwsyJw7S2cUREBBaLpctGsETreTweDhw4wJkzZ3C73cTHxzNx4kTlEf/i4mIOHjxISUkJERERJCYmMmrUqE4byu/0gAR+B+6mWFtby9WrV3E4HDidTnJO/4sP/3aSooq2nXY/KL47cycPZ1h/f5/DarUSFRWlNa0kHKI9uuzWo4E7K7pcLux2O7W1tdTV1eF0Oqmvd7M/7zz7ss9xoexq85XWweD4Htw9ZiC3D+uDyWTCYrEQHh6O1WrFYrE0Ov4hRFt06c2rAyGpr6/H6XTidDq1oNTX1+P1eimuqOHE+TIKS6spr3ZQ53Kjw3/CY2wPK/1ibQwf0IsYmxWTyRQSjvDwcK3PEXyjBgmIaKsuCQg0bm4F9iYOh4O6ujpcLhdutxu3260939Q3TOn1egwGAyaTCbPZjMViwWw2hxwQ7IqDguK/Q5cFBBp/R0ig8x4IR2DP4na7G30dG3wTEKPRiNlsJiwsjLCwMC0YgVEPCYfoKF0aEGj83YSBZldgONjtdmt/NyWwhzAajY32GBIM0dG6PCABDYMSvFdpah5ocBLZv4PRcLqEQ3Sk6xaQANW32qrIV62JrnDdvye9PRu2hEJ0tusekGCywYtvmy657Y8Q/6kkIEIoSECEUJCACKEgARFCQQIihIIERAgFCYgQChIQIRQkIEIoSECEUJCACKEgARFCQQIihIIERAgFCYgQChIQIRQkIEIoSECEUJCACKEgARFCQQIihIIERAgFCYgQChIQIRQkIEIoSECEUJCACKEgARFCQQIihIIERAgFCYgQChIQIRQkIEIoSECEUJCACKEgARFCQQIihIIERAgFCYgQChIQIRQkIEIoSECEUJCACKEgARFCQQIihIIERAgFCYgQChIQIRQkIEIoSECEUJCACKEgARFCQQIihIIERAgFCYgQChIQIRQkIEIoSECEUPh/9SyaX938X1QAAAAASUVORK5CYII=", + "deprecated": true, + "image": "tb-image:c2xpZGVfdG9nZ2xlX2NvbnRyb2xfc3lzdGVtX3dpZGdldF9pbWFnZS5wbmc=:IlNsaWRlIFRvZ2dsZSBDb250cm9sIiBzeXN0ZW0gd2lkZ2V0IGltYWdl;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAACgCAYAAABJ/yOpAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAFNpJREFUeJzt3Xl0VOX9x/H3bJnJJGEggRhC2EUQgoI/ZNEiUIRqfhyFspt6emqlsQZKldNjW7GgovTElgiCFKlWq4hxQxCU2AK2CKksSRP5AQEiECDNHgLJTGYyy++P6VxnkvBkD/b0+zonJ5M7d577zM39zH2e5y6j8/l8PoQQTdJf7woI8W0mARFCQQIihIIERAgFCYgQChIQIRQkIEIoSECEUJCACKEgARFCQQIihIIERAgFCYgQChIQIRQkIEIoSECEUJCACKEgARFCQQIihIIERAgFCYgQChIQIRQkIEIoSECEUJCACKEgARFCQQIihIIERAgFCYgQChIQIRQkIEIoSECEUJCACKEgARFCQQIihIIERAgFCYgQChIQIRQkIEIoSECEUJCACKEgARFCQQIihIIERAgFCYgQChIQIRQkIEIoSECEUJCACKEgARFCQQIihIIERAgFCYgQChIQIRQkIEIoSECEUJCACKFgvN4VCObz+Vo1v06n66SaCOF33QPSMBQtDYlOpwuZV8IiOsN1C0jwxh147PP5mpweEBwCnU6n/R0Ii4REdLTrEpCGgWj4EzxPQ8GhaPjTcB4h2qtLA6IKhtfrxev1cvmqndxTFzlTWMqlsss4XW4ArJYwEm7owZB+sdx6UwIR4Wb0ej16vR6dTodeHzreICERHaHLAtJUOAKh8Hg8fJFzhg/25nD0RCFer7ofYjLqGT9yIPOnj2HU0L4YDAZ8Pp8WlmASFNEeOl9rh47aIDgcXq9X++3xeDh25hIvv/s3ck9falPZtw3ry5IFk7mpfxwGgyFkrxLcHBOiLTo9IA3DEQhGfX09b31yiFc/Ooi3nVUwGPSkzr2LedPHYDAYtKA01T8RojW6JCANw1FT6+C5Vz/lb9lnOnRZs6bcwtKFUwkLM2E0GiUkot2u2Qdx1bv5+mIZX18qp/JyDbV1LhxOV6sKD+13ePF6PLjd9RzMPcfFsivtq3kTtu3LQwcsfWAqgBaSAAmJaK1GAfF4vOSeusChY2epc9W3ueCG4fB5fXg8HnJPX+qUcAR8uC+Pvjf0YM60MY36IkK0VkhAHE4XO/+ex6XSqo5bgs8HPvB43BSVVnGqsKLjyr6GDe/tZ9TQvtw0oPe3/hjJxYsX2bhxIwCjRo1i7ty52nOnT5/GYrHQt2/fFpW1atUqHA4H4eHhLF++vFPq+5+ioKCA1157DYCxY8dy//33t6kcLSC1dicZnx3mSq2j3ZUL2Xvgw+v14HG7ySsopvPHzMDt8fLKh/t5fvFMLSBNDQF3lpycHLZu3crhw4epqqrCYrGQkJDAPffcwwMPPIDVatXmraioYOvWrQA4HA4tIG+88QZPP/00er2eTZs2MXXq1GaX+8EHH1BdXY3NZvuvD0hJSYm2XvV6ffsC4vF62fn33A4JRwifD5/X30E//68KqmucHVu+QtZX58k5eZ7bEwdrx0kCwe3MoKSlpbFp06aQMwGuXLlCaWkp2dnZvPXWW7z++usMGDBAWc7JkycB8Hq95Ofntyggnekvf/kLn3/+OQALFy4kMTHxutanqxgBsk+c518V1R1acGDv4fN58bjdnLrQ+U2rht757CijhvbDYDB0yd7j448/5g9/+AMAFouF5ORkRowYQU1NDR999BHZ2dkUFhayaNEidu/ejcFguGZZS5cuRafTER4ezoMPPtjpdW/OV199pX0i33HHHf89AXG66jnyf+c6rMCQUWOf/+8rNQ4ud+HeI+DoiUvU1DoICwvT9iCdeWLju+++qz1evXp1yG594cKFzJ07l3/+858UFBSwd+9epk2bds2y4uLieP755zu8jqJ1jAUXynDWuzu+5H+PXnk8bkoqO2/USsXj9XLo2FnunpCoHTzszLN+y8vLtcfDhw8Pec5gMJCcnIzb7V/Xly9fVpa1fft23n//fQBSUlL4zne+oz1XWlrKiy++yBdffIHL5WLkyJEsW7ZMWV5hYSGbN28mKyuLqqoqevXqxXe/+10WLVpEjx49rvm67Oxs0tPTKSws1KatX7+ed955J6ReHo+HjIwMtm/fzvnz59Hr9QwZMoR58+aRlJTU5DrfsWMHb775JufOnSMqKopp06YxZ84cnnnmGQDmz5/PjBkztPkrKyt56aWX2LdvH3a7nYEDB5KSksK5c+fYt28fAK+//rpyzxyQk5PDn/70J3JycqirqyMhIYEZM2bw4IMPEhYWps1n/PpiWbOFtZXP58Pr8VB5tYP7Nq1w9OR5Jt8+LORNd5bBgweTn58P+DeitLQ0zGaz9vzs2bOZPXt2i8q6cOECBw4cAGDWrFna9OLiYr7//e9TXFysTduzZw9ZWVnU1zc9LH/gwAFSUlKw2+3atKqqKk6dOsWOHTvIyMigT58+Tb62srJSq0dAfn4++fn5zJw5E4Da2lp+/OMfc+jQoZD5iouL2b9/P5988gnr1q0L2XDT0tK05ij4Bys2b97M9u3bKS0tBeDOO+/Uni8pKWHu3LlcvHhRm1ZeXs6RI0fo2bMnZWUt347feOMNnnnmmZDWTkVFBbm5uezevZs333wTi8UCgL68uqbFBbeWD39IHHVtP57SXkWlV/B4PK2+WrEtUlJSMJlMgL8/MnXqVF5++eWQf2p7Pfvss1o4hg0bRlpaGk8++SQ2m63JgJSXl7NkyRLsdjt6vZ7FixezYcMGkpOT0el0FBUV8eSTT15zeSNHjmT9+vV873vf06Y99NBDrF+/nnHjxgH+4eVAOBITE1mzZg2rV6+mX79+AHz66afaUDb4P703bdoE+EeYFi1aRHp6OsnJySF74WCrVq3S1uOgQYNYvXo1K1asYOjQoa0KR3Z2Ns8++yw+n4+oqCh+85vfsHbtWiZPngzA0aNH2bBhgza/sdbeOX0DH98M9brc3k5ZRkvU1jmbvcako4wcOZI//vGPPPHEExQXF1NUVMTvfvc71qxZw7hx43jggQeu2dxoicrKSj777DMAbDYbW7Zs0ZpH99xzD1OmTNGacAFbtmzRmnNLly5lyZIlANx7771UV1ezc+dO9u/fT2FhobZBB7vhhhtISkri5MmTZGZmAjB69GiSkpIA/yd7oCkYFxfHli1biIqKAuCuu+7i7rvvxuFw8Oqrr7Jo0SLMZjNbt27V/hePPfYYqampANx///107949ZAMNvO/du3cDEBUVxTvvvEPPnj0BmDt3LhMnTqSqqmXH7jZs2IDX698eg4ORlJTE9OnTOXv2LG+//TaPPfaY/8TXFpXaTtfz0FxX7DmCTZw4kb/+9a88/vjj2gE+r9dLVlYWS5Ys4Yc//GFI86g18vLy8Hg8AEybNi2k79CnTx8iIiIavSYwNAv+Nn2wCRMmAP51lJOT06Y6HTx4UKvTzJkztXAA9O7dm+nTpwNQXV1Nbm4uAIcPHwb8e48f/OAHIeUlJCQ0WkZOTo62jHvvvVcLB4DVaiUmJqZFda2vrycrKwvwh3nSpEnacwaDgfHjxwP+5ue5c+cAMFrDzVTX2BsV1pGMhusXEavF3PxMHb1Mq5XFixeTmprKl19+yYcffsiOHTtwuVx88cUX/OhHP2LHjh1ac6ylgpsS/fv3b9Frgpt3gQ2gKddq2jTn0qVvLlMYPHhwo+cHDRoUUpexY8dq7yMmJgabzdbsMoI/UILLa62ysjLq6uq0Mpuqb0B5eTmDBg3CGN0totMDEm42AV0/zAtwQ3TkdVku+A9Ijh8/nvHjx5OamkpycjJFRUXk5+eTmZkZMkLTEoFPUfCfiNkSTuc36121MTa8IrMtdWoq8MHTAvMGmoEt/YAINIla85qmBK8Lg8FAZGTz24ZxUEIvzhZ1/EiWjm8uVuoW3vY31V4jB8d1yYVTBw4cYPHixYD/QFrDdnT//v1JTk7mhRdeAODEiROtDkhwk6qkpKRFr4mOjqamxj8Qs3///hZtFK0RGxurPQ7emzQ1LTBvdHQ0xcXFlJaW4nK5mh1hDG5CNbWMloqOjtYe9+vXjz179jT7Gv2N/WIxtWDcuC0Cm2OMzdIp5TdHr4Nbboz316WTj6QPHDiQq1evUl1dTVZWVpNNloqKb84mCD4fq6VGjhypvY89e/aEfHrX1taGfEIGjB07VnscOBIe7NixY1qzo6WClxtc/q5du0I+7Z1Op9axDwsLY/To0QDab7fbrXW+g99HQ7feeqv2vnfv3h0yWuf1ekOGr1VsNhtDhw4F4OzZs1p/JNjRo0dD+q36cLOJ24a3rD3bNjoiw01EWrr+Bio3D+iF1WJqc/OhNeLj47WRncuXL7Nw4ULee+898vLyyMrKYu3atfz5z38G/GENjJ60dhmBodULFy7w85//nBMnTnD48GFSUlKa3NAfeugh7fjDCy+8wEsvvcTx48c5deoUGzduZMGCBTzyyCO4XOprfbp166Y9/vTTT8nLy9Pa8XfddRcAx48f5xe/+AWnT5/m+PHjpKSkaB8Us2fP1sqYM2eOVtZTTz3Fzp07OX36NB988AHr1q1rtOw+ffpo/aeioiJ++tOfcuzYMXJzc1m2bBlFRUUtXoc/+clPtMePPvooGRkZnDlzhry8PFauXMn8+fP57W9/q81jBBgzfABnzpdQcaVxetss6Cxavd5Av14RHL/Qsed7Ned/J9yEyWTSzsXq7GtDVq1aRWlpKYcOHaKgoIAnnniiyflSU1MZMWJEm5axfPly5s2bh91uZ9euXezatQvw9yEiIyO15lTAsGHDWLlyJStWrMDtdpOenk56enrIPC1ZLxMmTNBO08nMzCQzM5Nly5aRmprK888/z7x58ygqKmLbtm1s27Yt5LVDhw4NWRdTpkwhKSmJTz75hKtXr/Kzn/1Me+5aR8FXrlzJ7NmzqampYe/evezduzfkNcF7NZVZs2Zx5MgRtm7dSnV1Nb/61a8azRO8LvQAJqOB+6aM/ndnun1Cr73QYzAaMZpM9O0VSYS5c5pyTUkc2ItRN/XBbDaHXH7bsI4dqVu3bmzZsoW0tDTGjBkT0pE2m81MmDCBzZs38/jjj2vTDQYDNpsNm80W0uyyWCza9OA2+vDhw3nrrbe45ZZbtGnx8fGsW7eOyZMnY7PZQj7tAZKTk3n77be58847Q+rUu3dvVqxYwSuvvNJs53fEiBEsX748pA8TOEsgPj6ebdu2sWDBgpBlR0dH8/DDD/Puu+82qtOaNWt45JFHtGFhvV7P1KlTtX5cYN0EDBkyhIyMDG6//Xbt/xcTE8OKFSu0Eb3g/6vRaNTWX+CoeMBzzz1Heno6iYmJIa+5+eab2bhxI7/85S+1aSHXpFdfdbDj85x270m0A3NeL26PG1edA3ttDUWl1eSe7/y9iE4HTz80hRE3JmCz2YiIiGh0jXpXqK+vp6KiAr1eT3R0dItHnlqquroap9NJz549W9yMdLlcVFZWYjabledgXYvb7aasrAyr1drkqJjH49Hec0xMTLPr2u12U15eTrdu3bBarSGnoLz44ovcd999jV5TU1NDTU0NvXr1wuPxcNttt2G324mNjeUf//hHq96Pw+GgoqKCHj16NHkcKWSt2qLCmX/POMYMH4CxIzruOh16nR69wYjRaOKGaCsJMZ3fYZ8z6WZu7NsLi8VCWFjYdbt5g8lkIi4ujtjY2A4PB/g7nbGxsa3qY4WFhREXF9emcID/k7l3797XHDI2GAzExsbSs2dP5bp+7bXXWLlyJW63m7i4OKxWKwUFBWRkZGjLCR4AsNvtLFiwgC+//JLIyEji4uLQ6/WsXbtW66TfcccdrX4/4eHhJCQkNBkOUNzVpMbu5FRhCV9fLKPycg32Nt6wIXA1octZR53DTp3DQXZBJVW1nXN+1vgRfXh01jgiIyO1Zsv12HuIaysuLmbSpEnU19fTvXt3Ro8eTV1dHUeOHNFGqB5++GF+/etfa68J3rMMHz6c+Ph4zpw5ox3xjoyM5KOPPmrXgcSmtPi2P16vj3p3yzpCEBwQ/61+6urqqK2t4cqVq1RUVrPp46PkX6hsW62vYezN8Tw843/o0b0b3bp1IyIigrCwsJBOuvh2eO+99/j973+vnbkbYDKZSElJYenSpSF9kKqqKp566ikyMzMbdchvvPFG0tLSGDVqVIfXs1PvixV8Tyy3243dbufKlSvU1NRQV+fk/c//j8zDZ9u9HJ0OZkwYwsyJw7S2cUREBBaLpctGsETreTweDhw4wJkzZ3C73cTHxzNx4kTlEf/i4mIOHjxISUkJERERJCYmMmrUqE4byu/0gAR+B+6mWFtby9WrV3E4HDidTnJO/4sP/3aSooq2nXY/KL47cycPZ1h/f5/DarUSFRWlNa0kHKI9uuzWo4E7K7pcLux2O7W1tdTV1eF0Oqmvd7M/7zz7ss9xoexq85XWweD4Htw9ZiC3D+uDyWTCYrEQHh6O1WrFYrE0Ov4hRFt06c2rAyGpr6/H6XTidDq1oNTX1+P1eimuqOHE+TIKS6spr3ZQ53Kjw3/CY2wPK/1ibQwf0IsYmxWTyRQSjvDwcK3PEXyjBgmIaKsuCQg0bm4F9iYOh4O6ujpcLhdutxu3260939Q3TOn1egwGAyaTCbPZjMViwWw2hxwQ7IqDguK/Q5cFBBp/R0ig8x4IR2DP4na7G30dG3wTEKPRiNlsJiwsjLCwMC0YgVEPCYfoKF0aEGj83YSBZldgONjtdmt/NyWwhzAajY32GBIM0dG6PCABDYMSvFdpah5ocBLZv4PRcLqEQ3Sk6xaQANW32qrIV62JrnDdvye9PRu2hEJ0tusekGCywYtvmy657Y8Q/6kkIEIoSECEUJCACKEgARFCQQIihIIERAgFCYgQChIQIRQkIEIoSECEUJCACKEgARFCQQIihIIERAgFCYgQChIQIRQkIEIoSECEUJCACKEgARFCQQIihIIERAgFCYgQChIQIRQkIEIoSECEUJCACKEgARFCQQIihIIERAgFCYgQChIQIRQkIEIoSECEUJCACKEgARFCQQIihIIERAgFCYgQChIQIRQkIEIoSECEUJCACKEgARFCQQIihIIERAgFCYgQChIQIRQkIEIoSECEUJCACKEgARFCQQIihIIERAgFCYgQChIQIRQkIEIoSECEUPh/9SyaX938X1QAAAAASUVORK5CYII=", "description": "Sends the RPC call to the device when the user toggles the slider. Appearance widget settings will enable you to configure how to fetch the initial value of the slider.", "descriptor": { "type": "rpc", @@ -17,7 +17,6 @@ "settingsDirective": "tb-slide-toggle-widget-settings", "defaultConfig": "{\"targetDeviceAliases\":[],\"showTitle\":false,\"backgroundColor\":\"#ffffff\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"0px\",\"settings\":{\"requestTimeout\":500,\"initialValue\":false,\"getValueMethod\":\"getValue\",\"setValueMethod\":\"setValue\",\"title\":\"Slide toggle control\",\"retrieveValueMethod\":\"rpc\",\"valueKey\":\"value\",\"parseValueFunction\":\"return data ? true : false;\",\"convertValueFunction\":\"return value;\",\"requestPersistent\":false,\"labelPosition\":\"after\",\"sliderColor\":\"accent\"},\"title\":\"Slide Toggle Control\",\"dropShadow\":true,\"enableFullscreen\":false,\"widgetStyle\":{},\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"useDashboardTimewindow\":true,\"showLegend\":false,\"actions\":{},\"decimals\":2,\"widgetCss\":\"\",\"noDataDisplayMessage\":\"\"}" }, - "externalId": null, "tags": [ "command", "downlink", diff --git a/ui-ngx/angular.json b/ui-ngx/angular.json index 92981aa90f..36b2b4b2f1 100644 --- a/ui-ngx/angular.json +++ b/ui-ngx/angular.json @@ -158,7 +158,8 @@ "ace-builds", "diff-match-patch", "tv4", - "@messageformat/parser" + "@messageformat/parser", + "sorted-btree" ] }, "configurations": { diff --git a/ui-ngx/src/app/core/api/widget-api.models.ts b/ui-ngx/src/app/core/api/widget-api.models.ts index fa701b315c..548cbc7041 100644 --- a/ui-ngx/src/app/core/api/widget-api.models.ts +++ b/ui-ngx/src/app/core/api/widget-api.models.ts @@ -37,7 +37,7 @@ import { RafService } from '@core/services/raf.service'; import { EntityAliases } from '@shared/models/alias.models'; import { EntityInfo } from '@app/shared/models/entity.models'; import { IDashboardComponent } from '@home/models/dashboard-component.models'; -import * as moment_ from 'moment'; +import moment_ from 'moment'; import { AlarmData, AlarmDataPageLink, @@ -130,12 +130,12 @@ export interface IAliasController { getFilters(): Filters; getFilterInfo(filterId: string): FilterInfo; getKeyFilters(filterId: string): Array; - updateCurrentAliasEntity(aliasId: string, currentEntity: EntityInfo); - updateUserFilter(filter: Filter); - updateEntityAliases(entityAliases: EntityAliases); - updateFilters(filters: Filters); - updateAliases(aliasIds?: Array); - dashboardStateChanged(); + updateCurrentAliasEntity(aliasId: string, currentEntity: EntityInfo): void; + updateUserFilter(filter: Filter): void; + updateEntityAliases(entityAliases: EntityAliases): void; + updateFilters(filters: Filters): void; + updateAliases(aliasIds?: Array): void; + dashboardStateChanged(): void; } export interface StateObject { @@ -315,7 +315,7 @@ export interface IWidgetSubscription { rpcEnabled?: boolean; executingRpcRequest?: boolean; rpcErrorText?: string; - rpcRejection?: HttpErrorResponse; + rpcRejection?: HttpErrorResponse | Error; getFirstEntityInfo(): SubscriptionEntityInfo; diff --git a/ui-ngx/src/app/core/api/widget-subscription.ts b/ui-ngx/src/app/core/api/widget-subscription.ts index ca2fdf21eb..ff16af7740 100644 --- a/ui-ngx/src/app/core/api/widget-subscription.ts +++ b/ui-ngx/src/app/core/api/widget-subscription.ts @@ -55,7 +55,7 @@ import { } from '@app/shared/models/time/time.models'; import { forkJoin, Observable, of, ReplaySubject, Subject, throwError, timer } from 'rxjs'; import { CancelAnimationFrame } from '@core/services/raf.service'; -import { EntityType } from '@shared/models/entity-type.models'; +import { EntityType, entityTypeTranslations } from '@shared/models/entity-type.models'; import { createLabelFromPattern, deepClone, @@ -67,7 +67,7 @@ import { parseHttpErrorMessage } from '@core/utils'; import { EntityId } from '@app/shared/models/id/entity-id'; -import * as moment_ from 'moment'; +import moment_ from 'moment'; import { emptyPageData, PageData } from '@shared/models/page/page-data'; import { EntityDataListener } from '@core/api/entity-data.service'; import { @@ -205,8 +205,9 @@ export class WidgetSubscription implements IWidgetSubscription { executingRpcRequest: boolean; rpcEnabled: boolean; + rpcDisabledReason: string; rpcErrorText: string; - rpcRejection: HttpErrorResponse; + rpcRejection: HttpErrorResponse | Error; init$: Observable; @@ -292,13 +293,15 @@ export class WidgetSubscription implements IWidgetSubscription { this.subscriptionTimewindow = null; this.loadingData = false; this.displayLegend = false; - this.initAlarmSubscription().subscribe(() => { - subscriptionSubject.next(this); - subscriptionSubject.complete(); - }, - () => { - subscriptionSubject.error(null); - }); + this.initAlarmSubscription().subscribe({ + next:() => { + subscriptionSubject.next(this); + subscriptionSubject.complete(); + }, + error: () => { + subscriptionSubject.error(null); + }} + ); } else { this.callbacks.onDataUpdated = this.callbacks.onDataUpdated || (() => {}); this.callbacks.onLatestDataUpdated = this.callbacks.onLatestDataUpdated || (() => {}); @@ -373,13 +376,15 @@ export class WidgetSubscription implements IWidgetSubscription { this.legendConfig.showAvg === true || this.legendConfig.showTotal === true || this.legendConfig.showLatest === true); - this.initDataSubscription().subscribe(() => { + this.initDataSubscription().subscribe({ + next:() => { subscriptionSubject.next(this); subscriptionSubject.complete(); }, - (err) => { - subscriptionSubject.error(err); - }); + error: () => { + subscriptionSubject.error(null); + }} + ); } } @@ -401,6 +406,16 @@ export class WidgetSubscription implements IWidgetSubscription { this.rpcEnabled = true; } else { this.rpcEnabled = this.ctx.utils.widgetEditMode; + if (!this.rpcEnabled) { + if (this.targetEntityId) { + const entityType = + this.ctx.translate.instant(entityTypeTranslations.get(this.targetEntityId.entityType).type); + this.rpcDisabledReason = + this.ctx.translate.instant('rpc.error.invalid-target-entity', {entityType}); + } else { + this.rpcDisabledReason = this.ctx.translate.instant('rpc.error.target-device-is-not-set'); + } + } } this.hasResolvedData = true; this.callbacks.rpcStateChanged(this); @@ -409,6 +424,7 @@ export class WidgetSubscription implements IWidgetSubscription { }, error: () => { this.rpcEnabled = false; + this.rpcDisabledReason = this.ctx.translate.instant('rpc.error.failed-to-resolve-target-device'); this.callbacks.rpcStateChanged(this); initRpcSubject.next(); initRpcSubject.complete(); @@ -427,17 +443,19 @@ export class WidgetSubscription implements IWidgetSubscription { initAlarmSubscriptionSubject.complete(); } else { this.ctx.aliasController.resolveAlarmSource(this.alarmSource).subscribe( - (alarmSource) => { - this.alarmSource = alarmSource; - if (alarmSource) { - this.hasResolvedData = true; + { + next: (alarmSource) => { + this.alarmSource = alarmSource; + if (alarmSource) { + this.hasResolvedData = true; + } + this.configureAlarmsData(); + initAlarmSubscriptionSubject.next(); + initAlarmSubscriptionSubject.complete(); + }, + error: (err) => { + initAlarmSubscriptionSubject.error(err); } - this.configureAlarmsData(); - initAlarmSubscriptionSubject.next(); - initAlarmSubscriptionSubject.complete(); - }, - (err) => { - initAlarmSubscriptionSubject.error(err); } ); } @@ -464,18 +482,20 @@ export class WidgetSubscription implements IWidgetSubscription { ); } else { this.ctx.aliasController.resolveDatasources(this.configuredDatasources, this.singleEntity, this.pageSize).subscribe( - (datasources) => { - this.configuredDatasources = datasources; - this.prepareDataSubscriptions().subscribe( - () => { - initDataSubscriptionSubject.next(); - initDataSubscriptionSubject.complete(); - } - ); - }, - (err) => { - this.notifyDataLoaded(); - initDataSubscriptionSubject.error(err); + { + next: (datasources) => { + this.configuredDatasources = datasources; + this.prepareDataSubscriptions().subscribe( + () => { + initDataSubscriptionSubject.next(); + initDataSubscriptionSubject.complete(); + } + ); + }, + error: (err) => { + this.notifyDataLoaded(); + initDataSubscriptionSubject.error(err); + } } ); } @@ -801,9 +821,11 @@ export class WidgetSubscription implements IWidgetSubscription { persistent?: boolean, persistentPollingInterval?: number, retries?: number, additionalInfo?: any, requestUUID?: string): Observable { if (!this.rpcEnabled) { - return throwError(new Error('Rpc disabled!')); + this.rpcErrorText = this.rpcDisabledReason; + this.rpcRejection = new Error(this.rpcErrorText); + return throwError(() => this.rpcRejection); } else { - if (this.rpcRejection && this.rpcRejection.status !== 504) { + if (this.rpcRejection && (!(this.rpcRejection as any).status || (this.rpcRejection as HttpErrorResponse).status !== 504)) { this.rpcRejection = null; this.rpcErrorText = null; this.callbacks.onRpcErrorCleared(this); @@ -848,9 +870,9 @@ export class WidgetSubscription implements IWidgetSubscription { persistentRespons.status !== RpcStatus.DELIVERED && persistentRespons.status !== RpcStatus.QUEUED), switchMap(persistentResponse => { if ([RpcStatus.TIMEOUT, RpcStatus.EXPIRED].includes(persistentResponse.status)) { - return throwError({status: 504}); + return throwError(() => ({status: 504})); } else if (persistentResponse.status === RpcStatus.FAILED) { - return throwError({status: 502, statusText: persistentResponse.response.error}); + return throwError(() => ({status: 502, statusText: persistentResponse.response.error})); } else { return of(persistentResponse.response); } @@ -861,40 +883,43 @@ export class WidgetSubscription implements IWidgetSubscription { return of(response); }) ) - .subscribe((responseBody) => { - this.rpcRejection = null; - this.rpcErrorText = null; - const index = this.executingSubjects.indexOf(rpcSubject); - if (index >= 0) { - this.executingSubjects.splice( index, 1 ); - } - this.executingRpcRequest = this.executingSubjects.length > 0; - this.callbacks.onRpcSuccess(this); - rpcSubject.next(responseBody); - rpcSubject.complete(); - }, - (rejection: HttpErrorResponse) => { - const index = this.executingSubjects.indexOf(rpcSubject); - if (index >= 0) { - this.executingSubjects.splice( index, 1 ); - } - this.executingRpcRequest = this.executingSubjects.length > 0; - this.callbacks.rpcStateChanged(this); - if (!this.executingRpcRequest || rejection.status === 504) { - this.rpcRejection = rejection; - if (rejection.status === 504) { - this.rpcErrorText = 'Request Timeout.'; - } else { - this.rpcErrorText = 'Error : ' + rejection.status + ' - ' + rejection.statusText; - const error = parseHttpErrorMessage(rejection, this.ctx.translate); - if (error) { - this.rpcErrorText += '
'; - this.rpcErrorText += error.message; + .subscribe({ + next: (responseBody) => { + this.rpcRejection = null; + this.rpcErrorText = null; + const index = this.executingSubjects.indexOf(rpcSubject); + if (index >= 0) { + this.executingSubjects.splice( index, 1 ); + } + this.executingRpcRequest = this.executingSubjects.length > 0; + this.callbacks.onRpcSuccess(this); + rpcSubject.next(responseBody); + rpcSubject.complete(); + }, + error: (rejection: HttpErrorResponse) => { + const index = this.executingSubjects.indexOf(rpcSubject); + if (index >= 0) { + this.executingSubjects.splice( index, 1 ); + } + this.executingRpcRequest = this.executingSubjects.length > 0; + this.callbacks.rpcStateChanged(this); + if (!this.executingRpcRequest || rejection.status === 504) { + this.rpcRejection = rejection; + if (rejection.status === 504) { + this.rpcErrorText = this.ctx.translate.instant('rpc.error.request-timeout'); + } else { + this.rpcErrorText = this.ctx.translate.instant('rpc.error.rpc-http-error', + {status: rejection.status, statusText: rejection.statusText}); + const error = parseHttpErrorMessage(rejection, this.ctx.translate); + if (error) { + this.rpcErrorText += '
'; + this.rpcErrorText += error.message; + } } + this.callbacks.onRpcFailed(this); } - this.callbacks.onRpcFailed(this); + rpcSubject.error(rejection); } - rpcSubject.error(rejection); }); } return rpcSubject.asObservable(); @@ -937,7 +962,7 @@ export class WidgetSubscription implements IWidgetSubscription { subscribeAllForPaginatedData(pageLink: EntityDataPageLink, keyFilters: KeyFilter[]): Observable { const observables: Observable[] = []; - this.configuredDatasources.forEach((datasource, datasourceIndex) => { + this.configuredDatasources.forEach((_datasource, datasourceIndex) => { observables.push(this.subscribeForPaginatedData(datasourceIndex, pageLink, keyFilters)); }); if (observables.length) { @@ -1118,16 +1143,18 @@ export class WidgetSubscription implements IWidgetSubscription { this.updateAlarmDataSubscription(); } else { this.ctx.aliasController.resolveAlarmSource(this.alarmSource).subscribe( - (alarmSource) => { - this.alarmSource = alarmSource; - if (alarmSource) { - this.hasResolvedData = true; + { + next: (alarmSource) => { + this.alarmSource = alarmSource; + if (alarmSource) { + this.hasResolvedData = true; + } + this.configureAlarmsData(); + this.updateAlarmDataSubscription(); + }, + error: () => { + this.notifyDataLoaded(); } - this.configureAlarmsData(); - this.updateAlarmDataSubscription(); - }, - () => { - this.notifyDataLoaded(); } ); } @@ -1193,16 +1220,18 @@ export class WidgetSubscription implements IWidgetSubscription { ); } else { this.ctx.aliasController.resolveDatasources(this.configuredDatasources, this.singleEntity, this.pageSize).subscribe( - (datasources) => { - this.configuredDatasources = datasources; - this.prepareDataSubscriptions().subscribe( - () => { - this.updatePaginatedDataSubscriptions(); - } - ); - }, - () => { - this.notifyDataLoaded(); + { + next: (datasources) => { + this.configuredDatasources = datasources; + this.prepareDataSubscriptions().subscribe( + () => { + this.updatePaginatedDataSubscriptions(); + } + ); + }, + error: () => { + this.notifyDataLoaded(); + } } ); } @@ -1318,7 +1347,7 @@ export class WidgetSubscription implements IWidgetSubscription { private dataLoaded(pageData: PageData, data: Array>, - datasourceIndex: number, pageLink: EntityDataPageLink, isUpdate: boolean) { + datasourceIndex: number, _pageLink: EntityDataPageLink, isUpdate: boolean) { const datasource = this.configuredDatasources[datasourceIndex]; datasource.dataReceived = true; const datasources = pageData.data.map((entityData, index) => @@ -1403,7 +1432,7 @@ export class WidgetSubscription implements IWidgetSubscription { }); if (datasource.latestDataKeys && datasource.latestDataKeys.length) { this.hasLatestData = true; - datasource.latestDataKeys.forEach((dataKey, currentLatestDataKeyIndex) => { + datasource.latestDataKeys.forEach((_dataKey, currentLatestDataKeyIndex) => { const currentDataKeyIndex = datasource.dataKeys.length + currentLatestDataKeyIndex; const datasourceData = datasourceDataPage.data[currentDatasourceIndex][currentDataKeyIndex]; this.latestData.push(datasourceData); @@ -1608,7 +1637,7 @@ export class WidgetSubscription implements IWidgetSubscription { this.onDataUpdated(); } - private alarmsUpdated(updated: Array, alarms: PageData) { + private alarmsUpdated(_updated: Array, alarms: PageData) { this.alarmsLoaded(alarms, 0, 0); } @@ -1639,15 +1668,17 @@ export class WidgetSubscription implements IWidgetSubscription { const loadSubject = new ReplaySubject(1); if (this.ctx.getServerTimeDiff && this.timeWindow) { this.ctx.getServerTimeDiff().subscribe( - (stDiff) => { - this.timeWindow.stDiff = stDiff; - loadSubject.next(); - loadSubject.complete(); - }, - () => { - this.timeWindow.stDiff = 0; - loadSubject.next(); - loadSubject.complete(); + { + next: (stDiff) => { + this.timeWindow.stDiff = stDiff; + loadSubject.next(); + loadSubject.complete(); + }, + error: () => { + this.timeWindow.stDiff = 0; + loadSubject.next(); + loadSubject.complete(); + } } ); } else { diff --git a/ui-ngx/src/app/modules/home/components/widget/config/target-device.component.html b/ui-ngx/src/app/modules/home/components/widget/config/target-device.component.html index b46e5ccc90..ad2728484c 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/target-device.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/config/target-device.component.html @@ -32,7 +32,6 @@ *ngIf="targetDeviceFormGroup.get('type').value === targetDeviceType.entity" [tbRequired]="!widgetEditMode" [aliasController]="aliasController" - [allowedEntityTypes]="[entityType.DEVICE]" [callbacks]="entityAliasSelectCallbacks" formControlName="entityAliasId"> diff --git a/ui-ngx/src/app/modules/home/components/widget/dynamic-widget.component.ts b/ui-ngx/src/app/modules/home/components/widget/dynamic-widget.component.ts index 206adcc588..6cef868e66 100644 --- a/ui-ngx/src/app/modules/home/components/widget/dynamic-widget.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/dynamic-widget.component.ts @@ -57,7 +57,7 @@ export class DynamicWidgetComponent extends PageComponent implements IDynamicWid executingRpcRequest: boolean; rpcEnabled: boolean; rpcErrorText: string; - rpcRejection: HttpErrorResponse; + rpcRejection: HttpErrorResponse | Error; [key: string]: any; diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/rpc/rpc-widget.models.ts b/ui-ngx/src/app/modules/home/components/widget/lib/rpc/rpc-widget.models.ts index 77dbd31ddb..f47e654fdb 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/rpc/rpc-widget.models.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/rpc/rpc-widget.models.ts @@ -14,9 +14,14 @@ /// limitations under the License. /// -import { AttributeData, LatestTelemetry } from '@shared/models/telemetry/telemetry.models'; +import { + AttributeData, + AttributeScope, + LatestTelemetry, + telemetryTypeTranslationsShort +} from '@shared/models/telemetry/telemetry.models'; import { WidgetContext } from '@home/models/widget-component.models'; -import { BehaviorSubject, Observable, of } from 'rxjs'; +import { BehaviorSubject, Observable, of, throwError } from 'rxjs'; import { catchError, delay, map, share } from 'rxjs/operators'; import { UtilsService } from '@core/services/utils.service'; import { AfterViewInit, ChangeDetectorRef, Directive, Input, OnInit, TemplateRef } from '@angular/core'; @@ -24,6 +29,7 @@ import { backgroundStyle, ComponentStyle, overlayStyle } from '@shared/models/wi import { ImagePipe } from '@shared/pipe/image.pipe'; import { DomSanitizer } from '@angular/platform-browser'; import { + RpcActionSettings, RpcGetAttributeSettings, RpcSetAttributeSettings, RpcSettings, @@ -42,6 +48,7 @@ import { RpcUpdateStateSettings } from '@app/shared/models/rpc-widget-settings.models'; import { ValueType } from '@shared/models/constants'; +import { EntityType, entityTypeTranslations } from '@shared/models/entity-type.models'; @Directive() // eslint-disable-next-line @angular-eslint/directive-class-suffix @@ -77,7 +84,7 @@ export abstract class BasicRpcStateWidgetComponent = { - initialState: this.settings.initialState, + initialState: this.initialState(), updateStateByValue: val => this.getUpdateStateSettingsForValue(val) }; @@ -117,6 +124,8 @@ export abstract class BasicRpcStateWidgetComponent; + protected abstract getUpdateStateSettingsForValue(value: V): RpcUpdateStateSettings; protected stateValueType(): ValueType { @@ -161,14 +170,14 @@ export class RpcStateBehaviorApi extends RpcHasLoading { private ctx: WidgetContext, private settings: RpcStateBehaviourSettings, private callbacks: RpcStateCallbacks, - private stateValueType: ValueType) { + stateValueType: ValueType) { super(); this.initialStateGetter = RpcInitialStateGetter.fromSettings(ctx, settings.initialState, stateValueType, callbacks); this.stateUpdatersMap = new Map>(); } initState() { - if (this.ctx.defaultSubscription.rpcEnabled) { + if (this.ctx.defaultSubscription.targetEntityId || this.ctx.defaultSubscription.rpcEnabled) { this.loadingSubject.next(true); this.initialStateGetter.initState().subscribe( { @@ -186,7 +195,7 @@ export class RpcStateBehaviorApi extends RpcHasLoading { } ); } else { - this.callbacks.onError('Target device is not set!'); + this.callbacks.onError(this.ctx.translate.instant('widgets.rpc-state.error.target-entity-is-not-set')); } } @@ -268,7 +277,23 @@ export class RpcDataToStateConverter { } } -export abstract class RpcInitialStateGetter { +export abstract class RpcAction { + + protected constructor(protected ctx: WidgetContext, + protected settings: RpcActionSettings) {} + + handleError(err: any): Error { + const reason = parseError(this.ctx, err); + let errorMessage = this.ctx.translate.instant('widgets.rpc-state.error.failed-to-perform-action', + {actionLabel: this.settings.actionLabel}); + if (reason) { + errorMessage += '
' + reason; + } + return new Error(errorMessage); + } +} + +export abstract class RpcInitialStateGetter extends RpcAction { static fromSettings(ctx: WidgetContext, settings: RpcInitialStateSettings, @@ -293,6 +318,7 @@ export abstract class RpcInitialStateGetter { protected settings: RpcInitialStateSettings, protected stateValueType: ValueType, protected callbacks: RpcStateCallbacks) { + super(ctx, settings); this.isSimulated = this.ctx.$injector.get(UtilsService).widgetEditMode; if (this.settings.action !== RpcInitialStateAction.DO_NOTHING) { this.dataConverter = new RpcDataToStateConverter(settings.dataToState, stateValueType, this.callbacks); @@ -308,6 +334,9 @@ export abstract class RpcInitialStateGetter { } else { return data; } + }), + catchError(err => { + throw this.handleError(err); }) ); } @@ -355,7 +384,7 @@ export class RpcStateToParamsConverter { } } -export abstract class RpcStateUpdater { +export abstract class RpcStateUpdater extends RpcAction { static fromSettings(ctx: WidgetContext, settings: RpcUpdateStateSettings): RpcStateUpdater { @@ -374,6 +403,7 @@ export abstract class RpcStateUpdater { protected constructor(protected ctx: WidgetContext, protected settings: RpcUpdateStateSettings) { + super(ctx, settings); this.isSimulated = this.ctx.$injector.get(UtilsService).widgetEditMode; this.paramsConverter = new RpcStateToParamsConverter(settings.stateToParams); } @@ -382,7 +412,11 @@ export abstract class RpcStateUpdater { if (this.isSimulated) { return of(null).pipe(delay(500)); } else { - return this.doUpdateState(this.paramsConverter.stateToParams(state)); + return this.doUpdateState(this.paramsConverter.stateToParams(state)).pipe( + catchError(err => { + throw this.handleError(err); + }) + ); } } @@ -423,8 +457,8 @@ export class ExecuteRpcStateGetter extends RpcInitialStateGetter { this.executeRpcSettings.requestTimeout, this.executeRpcSettings.requestPersistent, this.executeRpcSettings.persistentPollingInterval).pipe( - catchError(() => { - throw new Error(this.ctx.defaultSubscription.rpcErrorText); + catchError((err) => { + throw handleRpcError(this.ctx, err); }) ); } @@ -444,6 +478,10 @@ export class RpcAttributeStateGetter extends RpcInitialStateGetter { protected doGetState(): Observable { if (this.ctx.defaultSubscription.targetEntityId) { + const err = validateAttributeScope(this.ctx, this.getAttributeSettings.scope); + if (err) { + return throwError(() => err); + } return this.ctx.attributeService.getEntityAttributes(this.ctx.defaultSubscription.targetEntityId, this.getAttributeSettings.scope, [this.getAttributeSettings.key], {ignoreLoading: true, ignoreErrors: true}) .pipe( @@ -506,8 +544,8 @@ export class ExecuteRpcStateUpdater extends RpcStateUpdater { this.executeRpcSettings.requestTimeout, this.executeRpcSettings.requestPersistent, this.executeRpcSettings.persistentPollingInterval).pipe( - catchError(() => { - throw new Error(this.ctx.defaultSubscription.rpcErrorText); + catchError((err) => { + throw handleRpcError(this.ctx, err); }) ); } @@ -525,6 +563,10 @@ export class RpcAttributeStateUpdater extends RpcStateUpdater { protected doUpdateState(params: any): Observable { if (this.ctx.defaultSubscription.targetEntityId) { + const err = validateAttributeScope(this.ctx, this.setAttributeSettings.scope); + if (err) { + return throwError(() => err); + } const attributes: Array = [{key: this.setAttributeSettings.key, value: params}]; return this.ctx.attributeService.saveEntityAttributes(this.ctx.defaultSubscription.targetEntityId, this.setAttributeSettings.scope, attributes, {ignoreLoading: true, ignoreErrors: true}); @@ -559,3 +601,26 @@ export class RpcTimeSeriesStateUpdater extends RpcStateUpdater { const parseError = (ctx: WidgetContext, err: any): string => ctx.$injector.get(UtilsService).parseException(err).message || 'Unknown Error'; + +const handleRpcError = (ctx: WidgetContext, err: any): Error => { + let reason: string; + if (ctx.defaultSubscription.rpcErrorText) { + reason = ctx.defaultSubscription.rpcErrorText; + } else { + reason = parseError(ctx, err); + } + return new Error(reason); +}; + +const validateAttributeScope = (ctx: WidgetContext, scope?: AttributeScope): Error | null => { + if (ctx.defaultSubscription.targetEntityId.entityType !== EntityType.DEVICE && scope && scope !== AttributeScope.SERVER_SCOPE) { + const scopeStr = ctx.translate.instant(telemetryTypeTranslationsShort.get(scope)); + const entityType = + ctx.translate.instant(entityTypeTranslations.get(ctx.defaultSubscription.targetEntityId.entityType).type); + const errorMessage = + ctx.translate.instant('widgets.rpc-state.error.invalid-attribute-scope', {scope: scopeStr, entityType}); + return new Error(errorMessage); + } else { + return null; + } +}; diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/rpc/single-switch-widget.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/rpc/single-switch-widget.component.html index 62e6296163..ee27f83458 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/rpc/single-switch-widget.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/rpc/single-switch-widget.component.html @@ -35,7 +35,7 @@
-
{{ error }}
+
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/rpc/single-switch-widget.component.scss b/ui-ngx/src/app/modules/home/components/widget/lib/rpc/single-switch-widget.component.scss index 15d1e2b0fe..884bea0e43 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/rpc/single-switch-widget.component.scss +++ b/ui-ngx/src/app/modules/home/components/widget/lib/rpc/single-switch-widget.component.scss @@ -61,14 +61,14 @@ $switchColorDisabled: var(--tb-single-switch-color-disabled, #D5D7E5); align-items: center; gap: 4px; border-radius: 4px; - border: 1px solid rgba(209, 39, 48, 0.04); - background: rgba(209, 39, 48, 0.04); + background-color: #fff2f3; + box-shadow: -2px 2px 4px 0px rgba(0,0,0,0.2); .tb-single-switch-error-text { font-size: 12px; font-style: normal; font-weight: 400; line-height: 16px; - color: #D12730; + color: rgba(209, 39, 48, 1); } .tb-single-switch-error-clear { color: rgba(209, 39, 48, 1); diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/rpc/single-switch-widget.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/rpc/single-switch-widget.component.ts index 0fffd67b9f..7794e51ebc 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/rpc/single-switch-widget.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/rpc/single-switch-widget.component.ts @@ -38,7 +38,7 @@ import { ImagePipe } from '@shared/pipe/image.pipe'; import { DomSanitizer } from '@angular/platform-browser'; import cssjs from '@core/css/css'; import { hashCode } from '@core/utils'; -import { RpcUpdateStateSettings } from '@shared/models/rpc-widget-settings.models'; +import { RpcInitialStateSettings, RpcUpdateStateSettings } from '@shared/models/rpc-widget-settings.models'; import { ValueType } from '@shared/models/constants'; const horizontalLayoutPadding = 48; @@ -170,8 +170,13 @@ export class SingleSwitchWidgetComponent extends return {...singleSwitchDefaultSettings}; } + protected initialState(): RpcInitialStateSettings { + return {...this.settings.initialState, actionLabel: this.ctx.translate.instant('widgets.rpc-state.initial-state')}; + } + protected getUpdateStateSettingsForValue(value: boolean): RpcUpdateStateSettings { - return value ? this.settings.onUpdateState : this.settings.offUpdateState; + const targetSettings = value ? this.settings.onUpdateState : this.settings.offUpdateState; + return {...targetSettings, actionLabel: this.ctx.translate.instant(value ? 'widgets.rpc-state.turn-on' : 'widgets.rpc-state.turn-off')}; } protected validateValue(value: any): boolean { diff --git a/ui-ngx/src/app/modules/home/models/widget-component.models.ts b/ui-ngx/src/app/modules/home/models/widget-component.models.ts index 950f951415..4a7fc32502 100644 --- a/ui-ngx/src/app/modules/home/models/widget-component.models.ts +++ b/ui-ngx/src/app/modules/home/models/widget-component.models.ts @@ -122,7 +122,7 @@ export interface WidgetAction extends IWidgetAction { } export interface IDashboardWidget { - updateWidgetParams(); + updateWidgetParams(): void; } export class WidgetContext { @@ -514,7 +514,7 @@ export interface IDynamicWidgetComponent { executingRpcRequest: boolean; rpcEnabled: boolean; rpcErrorText: string; - rpcRejection: HttpErrorResponse; + rpcRejection: HttpErrorResponse | Error; raf: RafService; [key: string]: any; } diff --git a/ui-ngx/src/app/shared/components/popover.models.ts b/ui-ngx/src/app/shared/components/popover.models.ts index b51b440ce3..ce2cf98408 100644 --- a/ui-ngx/src/app/shared/components/popover.models.ts +++ b/ui-ngx/src/app/shared/components/popover.models.ts @@ -80,6 +80,7 @@ export const getPlacementName = (position: ConnectedOverlayPositionChange): Popo }; export interface PropertyMapping { + // @ts-ignore [key: string]: [string, () => unknown]; } diff --git a/ui-ngx/src/app/shared/models/rpc-widget-settings.models.ts b/ui-ngx/src/app/shared/models/rpc-widget-settings.models.ts index 2e5456009a..b912361805 100644 --- a/ui-ngx/src/app/shared/models/rpc-widget-settings.models.ts +++ b/ui-ngx/src/app/shared/models/rpc-widget-settings.models.ts @@ -65,7 +65,11 @@ export interface RpcDataToStateSettings { compareToValue?: any; } -export interface RpcInitialStateSettings { +export interface RpcActionSettings { + actionLabel?: string; +} + +export interface RpcInitialStateSettings extends RpcActionSettings { action: RpcInitialStateAction; defaultValue: V; executeRpc: RpcSettings; @@ -102,7 +106,7 @@ export interface RpcStateToParamsSettings { stateToParamsFunction: string; } -export interface RpcUpdateStateSettings { +export interface RpcUpdateStateSettings extends RpcActionSettings { action: RpcUpdateStateAction; executeRpc: RpcSettings; setAttribute: RpcSetAttributeSettings; diff --git a/ui-ngx/src/assets/locale/locale.constant-en_US.json b/ui-ngx/src/assets/locale/locale.constant-en_US.json index 0667ec04fe..47eaa22385 100644 --- a/ui-ngx/src/assets/locale/locale.constant-en_US.json +++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json @@ -3723,6 +3723,15 @@ "pkcs-12": "PKCS #12" } }, + "rpc": { + "error": { + "target-device-is-not-set": "Target device is not set!", + "invalid-target-entity": "RPC commands are not supported by {{entityType}} entity.", + "failed-to-resolve-target-device": "Failed to resolve target device!", + "request-timeout": "Request Timeout.", + "rpc-http-error": "Error: {{status}} - {{statusText}}" + } + }, "rulechain": { "rulechain": "Rule chain", "rulechain-events": "Rule chain events", @@ -6038,7 +6047,12 @@ "parse-value-function": "Parse value function", "on-when-result-is": "'On' when result is", "parameters": "Parameters", - "convert-value-function": "Convert value function" + "convert-value-function": "Convert value function", + "error": { + "target-entity-is-not-set": "Target entity is not set!", + "failed-to-perform-action": "Failed to perform the {{ actionLabel }} action.", + "invalid-attribute-scope": "{{scope}} attribute scope is not supported by {{entityType}} entity." + } }, "maps": { "select-entity": "Select entity", From a2ab2314653ea021f42be3d52d6215e237e1bbf6 Mon Sep 17 00:00:00 2001 From: dashevchenko Date: Wed, 24 Jan 2024 17:19:05 +0200 Subject: [PATCH 132/179] extended password reset exception from ThingsboardException to Exception --- .../org/thingsboard/server/service/mail/DefaultMailService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/application/src/main/java/org/thingsboard/server/service/mail/DefaultMailService.java b/application/src/main/java/org/thingsboard/server/service/mail/DefaultMailService.java index 9169a37515..969e310e5b 100644 --- a/application/src/main/java/org/thingsboard/server/service/mail/DefaultMailService.java +++ b/application/src/main/java/org/thingsboard/server/service/mail/DefaultMailService.java @@ -181,7 +181,7 @@ public class DefaultMailService implements MailService { passwordResetExecutorService.execute(() -> { try { this.sendResetPasswordEmail(passwordResetLink, email); - } catch (ThingsboardException e) { + } catch (Exception e) { log.error("Error occurred: {} ", e.getMessage()); } }); From 81ec3d8d1444f5e6ae68fc954448eaf1c4141125 Mon Sep 17 00:00:00 2001 From: Igor Kulikov Date: Wed, 24 Jan 2024 18:14:07 +0200 Subject: [PATCH 133/179] Update entities-table.component.html --- .../home/components/entity/entities-table.component.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ui-ngx/src/app/modules/home/components/entity/entities-table.component.html b/ui-ngx/src/app/modules/home/components/entity/entities-table.component.html index 8c4ce9eb2c..5aec80aacb 100644 --- a/ui-ngx/src/app/modules/home/components/entity/entities-table.component.html +++ b/ui-ngx/src/app/modules/home/components/entity/entities-table.component.html @@ -165,8 +165,8 @@ [matTooltip]="cellTooltip(entity, column, row)" matTooltipPosition="above" [ngStyle]="cellStyle(entity, column, row)"> - - + + From ac2da12054266b313b5b56765411cdc242df45f8 Mon Sep 17 00:00:00 2001 From: Artem Dzhereleiko Date: Thu, 25 Jan 2024 12:24:04 +0200 Subject: [PATCH 134/179] UI: Update rule core config --- .../static/rulenode/rulenode-core-config.js | 50 +++++++++---------- 1 file changed, 25 insertions(+), 25 deletions(-) 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 9b31fc9a13..5bfa26ada4 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,25 +1,25 @@ -System.register(["@angular/core","@shared/public-api","@ngrx/store","@angular/forms","@angular/common","@angular/material/checkbox","@angular/material/input","@angular/material/form-field","@angular/flex-layout/flex","@ngx-translate/core","@angular/material/select","@angular/material/core","@angular/material/slide-toggle","@shared/components/hint-tooltip-icon.component","@core/public-api","@shared/components/js-func.component","@angular/material/button","@angular/material/icon","@angular/material/tooltip","@shared/components/script-lang.component","@angular/cdk/keycodes","@angular/material/chips","@shared/pipe/safe.pipe","@shared/components/entity/entity-type-select.component","@shared/components/entity/entity-select.component","@angular/cdk/coercion","@shared/components/tb-error.component","@angular/flex-layout/extended","@angular/material/list","@angular/cdk/drag-drop","rxjs/operators","@angular/material/autocomplete","@shared/pipe/highlight.pipe","@home/components/public-api","tslib","rxjs","@shared/components/help-popup.component","@shared/components/entity/entity-subtype-list.component","@shared/components/relation/relation-type-autocomplete.component","@home/components/relation/relation-filters.component","@angular/material/expansion","@shared/components/file-input.component","@shared/components/button/toggle-password.component","@shared/components/string-items-list.component","@shared/components/toggle-header.component","@shared/components/toggle-select.component","@shared/components/entity/entity-list.component","@shared/components/notification/template-autocomplete.component","@shared/components/tb-checkbox.component","@home/components/sms/sms-provider-configuration.component","@angular/material/radio","@shared/components/slack-conversation-autocomplete.component","@shared/components/entity/entity-autocomplete.component","@shared/components/entity/entity-type-list.component","@angular/cdk/platform"],(function(e){"use strict";var t,n,r,o,a,i,l,s,m,p,d,u,c,f,g,y,x,b,h,v,C,F,k,L,T,I,N,S,q,A,M,E,G,D,w,V,P,R,O,_,B,K,z,U,H,j,$,Q,J,Y,W,Z,X,ee,te,ne,re,oe,ae,ie,le,se,me,pe,de,ue,ce,fe,ge,ye,xe,be,he,ve,Ce,Fe,ke,Le,Te,Ie,Ne,Se,qe,Ae,Me,Ee,Ge,De,we,Ve,Pe,Re,Oe,_e,Be,Ke,ze,Ue,He,je,$e,Qe,Je,Ye,We,Ze,Xe,et,tt,nt,rt,ot,at,it,lt,st,mt,pt;return{setters:[function(e){t=e,n=e.Component,r=e.EventEmitter,o=e.ViewChild,a=e.forwardRef,i=e.Input,l=e.InjectionToken,s=e.Injectable,m=e.Inject,p=e.Optional,d=e.Directive,u=e.Output,c=e.NgModule},function(e){f=e.RuleNodeConfigurationComponent,g=e.AttributeScope,y=e.telemetryTypeTranslations,x=e.ScriptLanguage,b=e.AlarmSeverity,h=e.alarmSeverityTranslations,v=e.EntitySearchDirection,C=e.entitySearchDirectionTranslations,F=e.EntityType,k=e.entityFields,L=e.PageComponent,T=e.coerceBoolean,I=e.MessageType,N=e.messageTypeNames,S=e,q=e.AlarmStatus,A=e.alarmStatusTranslations,M=e.SharedModule,E=e.AggregationType,G=e.aggregationTranslations,D=e.NotificationType,w=e.SlackChanelType,V=e.SlackChanelTypesTranslateMap},function(e){P=e},function(e){R=e,O=e.Validators,_=e.NgControl,B=e.NG_VALUE_ACCESSOR,K=e.NG_VALIDATORS,z=e.FormArray,U=e.FormGroup},function(e){H=e,j=e.DOCUMENT,$=e.CommonModule},function(e){Q=e},function(e){J=e},function(e){Y=e},function(e){W=e},function(e){Z=e},function(e){X=e},function(e){ee=e},function(e){te=e},function(e){ne=e},function(e){re=e.getCurrentAuthState,oe=e,ae=e.isEqual,ie=e.isDefinedAndNotNull,le=e.deepTrim,se=e.isObject,me=e.isNotEmptyStr},function(e){pe=e},function(e){de=e},function(e){ue=e},function(e){ce=e},function(e){fe=e},function(e){ge=e.ENTER,ye=e.COMMA,xe=e.SEMICOLON},function(e){be=e},function(e){he=e},function(e){ve=e},function(e){Ce=e},function(e){Fe=e.coerceBooleanProperty,ke=e.coerceElement,Le=e.coerceNumberProperty},function(e){Te=e},function(e){Ie=e},function(e){Ne=e},function(e){Se=e},function(e){qe=e.tap,Ae=e.map,Me=e.startWith,Ee=e.mergeMap,Ge=e.share,De=e.takeUntil,we=e.auditTime},function(e){Ve=e},function(e){Pe=e},function(e){Re=e.HomeComponentsModule},function(e){Oe=e.__decorate},function(e){_e=e.Subject,Be=e.takeUntil,Ke=e.of,ze=e.EMPTY,Ue=e.fromEvent},function(e){He=e},function(e){je=e},function(e){$e=e},function(e){Qe=e},function(e){Je=e},function(e){Ye=e},function(e){We=e},function(e){Ze=e},function(e){Xe=e},function(e){et=e},function(e){tt=e},function(e){nt=e},function(e){rt=e},function(e){ot=e},function(e){at=e},function(e){it=e},function(e){lt=e},function(e){st=e},function(e){mt=e.normalizePassiveListenerOptions,pt=e}],execute:function(){class dt extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.emptyConfigForm}onConfigurationSet(e){this.emptyConfigForm=this.fb.group({})}}e("EmptyConfigComponent",dt),dt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:dt,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),dt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:dt,selector:"tb-node-empty-config",usesInheritance:!0,ngImport:t,template:"
",isInline:!0}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:dt,decorators:[{type:n,args:[{selector:"tb-node-empty-config",template:"
"}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class ut extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.assignCustomerConfigForm}onConfigurationSet(e){this.assignCustomerConfigForm=this.fb.group({customerNamePattern:[e?e.customerNamePattern:null,[O.required,O.pattern(/.*\S.*/)]],createCustomerIfNotExists:[!!e&&e.createCustomerIfNotExists,[]],customerCacheExpiration:[e?e.customerCacheExpiration:null,[O.required,O.min(0)]]})}prepareOutputConfig(e){return e.customerNamePattern=e.customerNamePattern.trim(),e}}e("AssignCustomerConfigComponent",ut),ut.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ut,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),ut.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:ut,selector:"tb-action-node-assign-to-customer-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.customer-name-pattern\n \n \n {{ \'tb.rulenode.customer-name-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n {{ \'tb.rulenode.create-customer-if-not-exists\' | translate }}\n \n \n tb.rulenode.customer-cache-expiration\n \n \n {{ \'tb.rulenode.customer-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.customer-cache-expiration-range\' | translate }}\n \n tb.rulenode.customer-cache-expiration-hint\n \n
\n',dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Q.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ut,decorators:[{type:n,args:[{selector:"tb-action-node-assign-to-customer-config",template:'
\n \n tb.rulenode.customer-name-pattern\n \n \n {{ \'tb.rulenode.customer-name-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n {{ \'tb.rulenode.create-customer-if-not-exists\' | translate }}\n \n \n tb.rulenode.customer-cache-expiration\n \n \n {{ \'tb.rulenode.customer-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.customer-cache-expiration-range\' | translate }}\n \n tb.rulenode.customer-cache-expiration-hint\n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class ct extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.attributeScopeMap=g,this.attributeScopes=Object.keys(g),this.telemetryTypeTranslationsMap=y}configForm(){return this.attributesConfigForm}onConfigurationSet(e){this.attributesConfigForm=this.fb.group({scope:[e?e.scope:null,[O.required]],notifyDevice:[!e||e.notifyDevice,[]],sendAttributesUpdatedNotification:[!!e&&e.sendAttributesUpdatedNotification,[]],updateAttributesOnlyOnValueChange:[!!e&&e.updateAttributesOnlyOnValueChange,[]]}),this.attributesConfigForm.get("scope").valueChanges.subscribe((e=>{e!==g.SHARED_SCOPE&&this.attributesConfigForm.get("notifyDevice").patchValue(!1,{emitEvent:!1}),e===g.CLIENT_SCOPE&&this.attributesConfigForm.get("sendAttributesUpdatedNotification").patchValue(!1,{emitEvent:!1}),this.attributesConfigForm.get("updateAttributesOnlyOnValueChange").patchValue(!1,{emitEvent:!1})}))}}e("AttributesConfigComponent",ct),ct.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ct,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),ct.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:ct,selector:"tb-action-node-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n
\n \n {{ \'tb.rulenode.update-attributes-only-on-value-change\' | translate }}\n \n
\n
\n \n {{ \'tb.rulenode.send-attributes-updated-notification\' | translate }}\n \n
\n
\n \n {{ \'tb.rulenode.notify-device\' | translate }}\n \n
\n
\n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:te.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:ne.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ct,decorators:[{type:n,args:[{selector:"tb-action-node-attributes-config",template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n
\n \n {{ \'tb.rulenode.update-attributes-only-on-value-change\' | translate }}\n \n
\n
\n \n {{ \'tb.rulenode.send-attributes-updated-notification\' | translate }}\n \n
\n
\n \n {{ \'tb.rulenode.notify-device\' | translate }}\n \n
\n
\n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class ft extends f{constructor(e,t,n,o){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=n,this.translate=o,this.tbelEnabled=re(this.store).tbelEnabled,this.scriptLanguage=x,this.changeScript=new r,this.hasScript=!0,this.testScriptLabel="tb.rulenode.test-details-function"}configForm(){return this.clearAlarmConfigForm}onConfigurationSet(e){this.clearAlarmConfigForm=this.fb.group({scriptLang:[e?e.scriptLang:x.JS,[O.required]],alarmDetailsBuildJs:[e?e.alarmDetailsBuildJs:null,[]],alarmDetailsBuildTbel:[e?e.alarmDetailsBuildTbel:null,[]],alarmType:[e?e.alarmType:null,[O.required]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.clearAlarmConfigForm.get("scriptLang").value;t!==x.TBEL||this.tbelEnabled||(t=x.JS,this.clearAlarmConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.clearAlarmConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.clearAlarmConfigForm.get("alarmDetailsBuildJs").setValidators(t===x.JS?[O.required]:[]),this.clearAlarmConfigForm.get("alarmDetailsBuildJs").updateValueAndValidity({emitEvent:e}),this.clearAlarmConfigForm.get("alarmDetailsBuildTbel").setValidators(t===x.TBEL?[O.required]:[]),this.clearAlarmConfigForm.get("alarmDetailsBuildTbel").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=x.JS)),e}testScript(e){const t=this.clearAlarmConfigForm.get("scriptLang").value,n=t===x.JS?"alarmDetailsBuildJs":"alarmDetailsBuildTbel",r=t===x.JS?"rulenode/clear_alarm_node_script_fn":"rulenode/tbel/clear_alarm_node_script_fn",o=this.clearAlarmConfigForm.get(n).value;this.nodeScriptTestService.testNodeScript(o,"json",this.translate.instant("tb.rulenode.details"),"Details",["msg","metadata","msgType"],this.ruleNodeId,r,t,e).subscribe((e=>{e&&(this.clearAlarmConfigForm.get(n).setValue(e),this.changeScript.emit())}))}onValidate(){this.clearAlarmConfigForm.get("scriptLang").value===x.JS&&this.jsFuncComponent.validateOnSubmit()}}e("ClearAlarmConfigComponent",ft),ft.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ft,deps:[{token:P.Store},{token:R.UntypedFormBuilder},{token:oe.NodeScriptTestService},{token:Z.TranslateService}],target:t.ɵɵFactoryTarget.Component}),ft.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:ft,selector:"tb-action-node-clear-alarm-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n \n \n
\n \n
\n \n tb.rulenode.alarm-type\n \n \n {{ \'tb.rulenode.alarm-type-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n
\n',dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:pe.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:de.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:de.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:fe.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ft,decorators:[{type:n,args:[{selector:"tb-action-node-clear-alarm-config",template:'
\n \n \n \n \n \n \n \n
\n \n
\n \n tb.rulenode.alarm-type\n \n \n {{ \'tb.rulenode.alarm-type-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder},{type:oe.NodeScriptTestService},{type:Z.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}});class gt extends f{constructor(e,t,n,o){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=n,this.translate=o,this.alarmSeverities=Object.keys(b),this.alarmSeverityTranslationMap=h,this.separatorKeysCodes=[ge,ye,xe],this.tbelEnabled=re(this.store).tbelEnabled,this.scriptLanguage=x,this.changeScript=new r,this.hasScript=!0,this.testScriptLabel="tb.rulenode.test-details-function"}configForm(){return this.createAlarmConfigForm}onConfigurationSet(e){this.createAlarmConfigForm=this.fb.group({scriptLang:[e?e.scriptLang:x.JS,[O.required]],alarmDetailsBuildJs:[e?e.alarmDetailsBuildJs:null,[]],alarmDetailsBuildTbel:[e?e.alarmDetailsBuildTbel:null,[]],useMessageAlarmData:[!!e&&e.useMessageAlarmData,[]],overwriteAlarmDetails:[!!e&&e.overwriteAlarmDetails,[]],alarmType:[e?e.alarmType:null,[]],severity:[e?e.severity:null,[]],propagate:[!!e&&e.propagate,[]],relationTypes:[e?e.relationTypes:null,[]],propagateToOwner:[!!e&&e.propagateToOwner,[]],propagateToTenant:[!!e&&e.propagateToTenant,[]],dynamicSeverity:!1}),this.createAlarmConfigForm.get("dynamicSeverity").valueChanges.subscribe((e=>{e?this.createAlarmConfigForm.get("severity").patchValue("",{emitEvent:!1}):this.createAlarmConfigForm.get("severity").patchValue(this.alarmSeverities[0],{emitEvent:!1})}))}validatorTriggers(){return["useMessageAlarmData","overwriteAlarmDetails","scriptLang"]}updateValidators(e){const t=this.createAlarmConfigForm.get("useMessageAlarmData").value,n=this.createAlarmConfigForm.get("overwriteAlarmDetails").value;t?(this.createAlarmConfigForm.get("alarmType").setValidators([]),this.createAlarmConfigForm.get("severity").setValidators([])):(this.createAlarmConfigForm.get("alarmType").setValidators([O.required]),this.createAlarmConfigForm.get("severity").setValidators([O.required])),this.createAlarmConfigForm.get("alarmType").updateValueAndValidity({emitEvent:e}),this.createAlarmConfigForm.get("severity").updateValueAndValidity({emitEvent:e});let r=this.createAlarmConfigForm.get("scriptLang").value;r!==x.TBEL||this.tbelEnabled||(r=x.JS,this.createAlarmConfigForm.get("scriptLang").patchValue(r,{emitEvent:!1}),setTimeout((()=>{this.createAlarmConfigForm.updateValueAndValidity({emitEvent:!0})})));const o=!1===t||!0===n;this.createAlarmConfigForm.get("alarmDetailsBuildJs").setValidators(o&&r===x.JS?[O.required]:[]),this.createAlarmConfigForm.get("alarmDetailsBuildTbel").setValidators(o&&r===x.TBEL?[O.required]:[]),this.createAlarmConfigForm.get("alarmDetailsBuildJs").updateValueAndValidity({emitEvent:e}),this.createAlarmConfigForm.get("alarmDetailsBuildTbel").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=x.JS)),e}testScript(e){const t=this.createAlarmConfigForm.get("scriptLang").value,n=t===x.JS?"alarmDetailsBuildJs":"alarmDetailsBuildTbel",r=t===x.JS?"rulenode/create_alarm_node_script_fn":"rulenode/tbel/create_alarm_node_script_fn",o=this.createAlarmConfigForm.get(n).value;this.nodeScriptTestService.testNodeScript(o,"json",this.translate.instant("tb.rulenode.details"),"Details",["msg","metadata","msgType"],this.ruleNodeId,r,t,e).subscribe((e=>{e&&(this.createAlarmConfigForm.get(n).setValue(e),this.changeScript.emit())}))}removeKey(e,t){const n=this.createAlarmConfigForm.get(t).value,r=n.indexOf(e);r>=0&&(n.splice(r,1),this.createAlarmConfigForm.get(t).setValue(n,{emitEvent:!0}))}addKey(e,t){const n=e.input;let r=e.value;if((r||"").trim()){r=r.trim();let e=this.createAlarmConfigForm.get(t).value;e&&-1!==e.indexOf(r)||(e||(e=[]),e.push(r),this.createAlarmConfigForm.get(t).setValue(e,{emitEvent:!0}))}n&&(n.value="")}onValidate(){const e=this.createAlarmConfigForm.get("useMessageAlarmData").value,t=this.createAlarmConfigForm.get("overwriteAlarmDetails").value;if(!e||t){this.createAlarmConfigForm.get("scriptLang").value===x.JS&&this.jsFuncComponent.validateOnSubmit()}}}e("CreateAlarmConfigComponent",gt),gt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:gt,deps:[{token:P.Store},{token:R.UntypedFormBuilder},{token:oe.NodeScriptTestService},{token:Z.TranslateService}],target:t.ɵɵFactoryTarget.Component}),gt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:gt,selector:"tb-action-node-create-alarm-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.use-message-alarm-data\' | translate }}\n \n \n {{ \'tb.rulenode.overwrite-alarm-details\' | translate }}\n \n
\n \n \n \n \n \n \n \n
\n \n
\n
\n
\n \n tb.rulenode.alarm-type\n \n \n {{ \'tb.rulenode.alarm-type-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n {{ \'tb.rulenode.use-alarm-severity-pattern\' | translate }}\n \n \n tb.rulenode.alarm-severity\n \n \n {{ alarmSeverityTranslationMap.get(severity) | translate }}\n \n \n \n {{ \'tb.rulenode.alarm-severity-required\' | translate }}\n \n \n \n tb.rulenode.alarm-severity-pattern\n \n \n {{ \'tb.rulenode.alarm-severity-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.propagate\' | translate }}\n \n
\n \n tb.rulenode.relation-types-list\n \n \n {{key}}\n close\n \n \n \n tb.rulenode.relation-types-list-hint\n \n
\n \n {{ \'tb.rulenode.propagate-to-owner\' | translate }}\n \n \n {{ \'tb.rulenode.propagate-to-tenant\' | translate }}\n \n
\n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:pe.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:de.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:de.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:Q.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:be.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:be.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:be.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:be.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:fe.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:he.SafePipe,name:"safe"},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:gt,decorators:[{type:n,args:[{selector:"tb-action-node-create-alarm-config",template:'
\n \n {{ \'tb.rulenode.use-message-alarm-data\' | translate }}\n \n \n {{ \'tb.rulenode.overwrite-alarm-details\' | translate }}\n \n
\n \n \n \n \n \n \n \n
\n \n
\n
\n
\n \n tb.rulenode.alarm-type\n \n \n {{ \'tb.rulenode.alarm-type-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n {{ \'tb.rulenode.use-alarm-severity-pattern\' | translate }}\n \n \n tb.rulenode.alarm-severity\n \n \n {{ alarmSeverityTranslationMap.get(severity) | translate }}\n \n \n \n {{ \'tb.rulenode.alarm-severity-required\' | translate }}\n \n \n \n tb.rulenode.alarm-severity-pattern\n \n \n {{ \'tb.rulenode.alarm-severity-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.propagate\' | translate }}\n \n
\n \n tb.rulenode.relation-types-list\n \n \n {{key}}\n close\n \n \n \n tb.rulenode.relation-types-list-hint\n \n
\n \n {{ \'tb.rulenode.propagate-to-owner\' | translate }}\n \n \n {{ \'tb.rulenode.propagate-to-tenant\' | translate }}\n \n
\n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder},{type:oe.NodeScriptTestService},{type:Z.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}});class yt extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.directionTypes=Object.keys(v),this.directionTypeTranslations=C,this.entityType=F}configForm(){return this.createRelationConfigForm}onConfigurationSet(e){this.createRelationConfigForm=this.fb.group({direction:[e?e.direction:null,[O.required]],entityType:[e?e.entityType:null,[O.required]],entityNamePattern:[e?e.entityNamePattern:null,[]],entityTypePattern:[e?e.entityTypePattern:null,[]],relationType:[e?e.relationType:null,[O.required]],createEntityIfNotExists:[!!e&&e.createEntityIfNotExists,[]],removeCurrentRelations:[!!e&&e.removeCurrentRelations,[]],changeOriginatorToRelatedEntity:[!!e&&e.changeOriginatorToRelatedEntity,[]],entityCacheExpiration:[e?e.entityCacheExpiration:null,[O.required,O.min(0)]]})}validatorTriggers(){return["entityType"]}updateValidators(e){const t=this.createRelationConfigForm.get("entityType").value;t?this.createRelationConfigForm.get("entityNamePattern").setValidators([O.required,O.pattern(/.*\S.*/)]):this.createRelationConfigForm.get("entityNamePattern").setValidators([]),!t||t!==F.DEVICE&&t!==F.ASSET?this.createRelationConfigForm.get("entityTypePattern").setValidators([]):this.createRelationConfigForm.get("entityTypePattern").setValidators([O.required,O.pattern(/.*\S.*/)]),this.createRelationConfigForm.get("entityNamePattern").updateValueAndValidity({emitEvent:e}),this.createRelationConfigForm.get("entityTypePattern").updateValueAndValidity({emitEvent:e})}prepareOutputConfig(e){return e.entityNamePattern=e.entityNamePattern?e.entityNamePattern.trim():null,e.entityTypePattern=e.entityTypePattern?e.entityTypePattern.trim():null,e}}e("CreateRelationConfigComponent",yt),yt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:yt,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),yt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:yt,selector:"tb-action-node-create-relation-config",usesInheritance:!0,ngImport:t,template:'
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.entity-type-pattern\n \n \n {{ \'tb.rulenode.entity-type-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n
\n \n tb.rulenode.relation-type-pattern\n \n \n {{ \'tb.rulenode.relation-type-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n
\n \n {{ \'tb.rulenode.create-entity-if-not-exists\' | translate }}\n \n
tb.rulenode.create-entity-if-not-exists-hint
\n
\n \n {{ \'tb.rulenode.remove-current-relations\' | translate }}\n \n
tb.rulenode.remove-current-relations-hint
\n \n {{ \'tb.rulenode.change-originator-to-related-entity\' | translate }}\n \n
tb.rulenode.change-originator-to-related-entity-hint
\n \n tb.rulenode.entity-cache-expiration\n \n \n {{ \'tb.rulenode.entity-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.entity-cache-expiration-range\' | translate }}\n \n tb.rulenode.entity-cache-expiration-hint\n \n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ve.EntityTypeSelectComponent,selector:"tb-entity-type-select",inputs:["allowedEntityTypes","useAliasEntityTypes","filterAllowedEntityTypes","showLabel","required","disabled"]},{kind:"component",type:Q.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:yt,decorators:[{type:n,args:[{selector:"tb-action-node-create-relation-config",template:'
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.entity-type-pattern\n \n \n {{ \'tb.rulenode.entity-type-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n
\n \n tb.rulenode.relation-type-pattern\n \n \n {{ \'tb.rulenode.relation-type-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n
\n \n {{ \'tb.rulenode.create-entity-if-not-exists\' | translate }}\n \n
tb.rulenode.create-entity-if-not-exists-hint
\n
\n \n {{ \'tb.rulenode.remove-current-relations\' | translate }}\n \n
tb.rulenode.remove-current-relations-hint
\n \n {{ \'tb.rulenode.change-originator-to-related-entity\' | translate }}\n \n
tb.rulenode.change-originator-to-related-entity-hint
\n \n tb.rulenode.entity-cache-expiration\n \n \n {{ \'tb.rulenode.entity-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.entity-cache-expiration-range\' | translate }}\n \n tb.rulenode.entity-cache-expiration-hint\n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class xt extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.directionTypes=Object.keys(v),this.directionTypeTranslations=C,this.entityType=F}configForm(){return this.deleteRelationConfigForm}onConfigurationSet(e){this.deleteRelationConfigForm=this.fb.group({deleteForSingleEntity:[!!e&&e.deleteForSingleEntity,[]],direction:[e?e.direction:null,[O.required]],entityType:[e?e.entityType:null,[]],entityNamePattern:[e?e.entityNamePattern:null,[]],relationType:[e?e.relationType:null,[O.required]],entityCacheExpiration:[e?e.entityCacheExpiration:null,[O.required,O.min(0)]]})}validatorTriggers(){return["deleteForSingleEntity","entityType"]}updateValidators(e){const t=this.deleteRelationConfigForm.get("deleteForSingleEntity").value,n=this.deleteRelationConfigForm.get("entityType").value;t?this.deleteRelationConfigForm.get("entityType").setValidators([O.required]):this.deleteRelationConfigForm.get("entityType").setValidators([]),t&&n?this.deleteRelationConfigForm.get("entityNamePattern").setValidators([O.required,O.pattern(/.*\S.*/)]):this.deleteRelationConfigForm.get("entityNamePattern").setValidators([]),this.deleteRelationConfigForm.get("entityType").updateValueAndValidity({emitEvent:!1}),this.deleteRelationConfigForm.get("entityNamePattern").updateValueAndValidity({emitEvent:e})}prepareOutputConfig(e){return e.entityNamePattern=e.entityNamePattern?e.entityNamePattern.trim():null,e}}e("DeleteRelationConfigComponent",xt),xt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:xt,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),xt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:xt,selector:"tb-action-node-delete-relation-config",usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.delete-relation-to-specific-entity\' | translate }}\n \n
tb.rulenode.delete-relation-hint
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n
\n \n tb.rulenode.relation-type-pattern\n \n \n {{ \'tb.rulenode.relation-type-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.entity-cache-expiration\n \n \n {{ \'tb.rulenode.entity-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.entity-cache-expiration-range\' | translate }}\n \n tb.rulenode.entity-cache-expiration-hint\n \n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ve.EntityTypeSelectComponent,selector:"tb-entity-type-select",inputs:["allowedEntityTypes","useAliasEntityTypes","filterAllowedEntityTypes","showLabel","required","disabled"]},{kind:"component",type:Q.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:xt,decorators:[{type:n,args:[{selector:"tb-action-node-delete-relation-config",template:'
\n \n {{ \'tb.rulenode.delete-relation-to-specific-entity\' | translate }}\n \n
tb.rulenode.delete-relation-hint
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n
\n \n tb.rulenode.relation-type-pattern\n \n \n {{ \'tb.rulenode.relation-type-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.entity-cache-expiration\n \n \n {{ \'tb.rulenode.entity-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.entity-cache-expiration-range\' | translate }}\n \n tb.rulenode.entity-cache-expiration-hint\n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class bt extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.deviceProfile}onConfigurationSet(e){this.deviceProfile=this.fb.group({persistAlarmRulesState:[!!e&&e.persistAlarmRulesState,O.required],fetchAlarmRulesStateOnStart:[!!e&&e.fetchAlarmRulesStateOnStart,O.required]})}}e("DeviceProfileConfigComponent",bt),bt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:bt,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),bt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:bt,selector:"tb-device-profile-config",usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.persist-alarm-rules\' | translate }}\n \n \n {{ \'tb.rulenode.fetch-alarm-rules\' | translate }}\n \n
\n',dependencies:[{kind:"component",type:Q.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:bt,decorators:[{type:n,args:[{selector:"tb-device-profile-config",template:'
\n \n {{ \'tb.rulenode.persist-alarm-rules\' | translate }}\n \n \n {{ \'tb.rulenode.fetch-alarm-rules\' | translate }}\n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class ht extends f{constructor(e,t,n,o){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=n,this.translate=o,this.tbelEnabled=re(this.store).tbelEnabled,this.scriptLanguage=x,this.changeScript=new r,this.hasScript=!0,this.testScriptLabel="tb.rulenode.test-generator-function"}configForm(){return this.generatorConfigForm}onConfigurationSet(e){this.generatorConfigForm=this.fb.group({msgCount:[e?e.msgCount:null,[O.required,O.min(0)]],periodInSeconds:[e?e.periodInSeconds:null,[O.required,O.min(1)]],originator:[e?e.originator:null,[]],scriptLang:[e?e.scriptLang:x.JS,[O.required]],jsScript:[e?e.jsScript:null,[]],tbelScript:[e?e.tbelScript:null,[]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.generatorConfigForm.get("scriptLang").value;t!==x.TBEL||this.tbelEnabled||(t=x.JS,this.generatorConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.generatorConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.generatorConfigForm.get("jsScript").setValidators(t===x.JS?[O.required]:[]),this.generatorConfigForm.get("jsScript").updateValueAndValidity({emitEvent:e}),this.generatorConfigForm.get("tbelScript").setValidators(t===x.TBEL?[O.required]:[]),this.generatorConfigForm.get("tbelScript").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=x.JS),e.originatorId&&e.originatorType?e.originator={id:e.originatorId,entityType:e.originatorType}:e.originator=null,delete e.originatorId,delete e.originatorType),e}prepareOutputConfig(e){return e.originator?(e.originatorId=e.originator.id,e.originatorType=e.originator.entityType):(e.originatorId=null,e.originatorType=null),delete e.originator,e}testScript(e){const t=this.generatorConfigForm.get("scriptLang").value,n=t===x.JS?"jsScript":"tbelScript",r=t===x.JS?"rulenode/generator_node_script_fn":"rulenode/tbel/generator_node_script_fn",o=this.generatorConfigForm.get(n).value;this.nodeScriptTestService.testNodeScript(o,"generate",this.translate.instant("tb.rulenode.generator"),"Generate",["prevMsg","prevMetadata","prevMsgType"],this.ruleNodeId,r,t,e).subscribe((e=>{e&&(this.generatorConfigForm.get(n).setValue(e),this.changeScript.emit())}))}onValidate(){this.generatorConfigForm.get("scriptLang").value===x.JS&&this.jsFuncComponent.validateOnSubmit()}}var vt;e("GeneratorConfigComponent",ht),ht.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ht,deps:[{token:P.Store},{token:R.UntypedFormBuilder},{token:oe.NodeScriptTestService},{token:Z.TranslateService}],target:t.ɵɵFactoryTarget.Component}),ht.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:ht,selector:"tb-action-node-generator-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.message-count\n \n \n {{ \'tb.rulenode.message-count-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-message-count-message\' | translate }}\n \n \n \n tb.rulenode.period-seconds\n \n \n {{ \'tb.rulenode.period-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-period-seconds-message\' | translate }}\n \n \n
\n \n \n \n
\n\n \n \n \n \n \n \n \n
\n \n
\n
\n',dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Ce.EntitySelectComponent,selector:"tb-entity-select",inputs:["allowedEntityTypes","useAliasEntityTypes","required","disabled"]},{kind:"component",type:pe.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:de.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:de.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:fe.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ht,decorators:[{type:n,args:[{selector:"tb-action-node-generator-config",template:'
\n \n tb.rulenode.message-count\n \n \n {{ \'tb.rulenode.message-count-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-message-count-message\' | translate }}\n \n \n \n tb.rulenode.period-seconds\n \n \n {{ \'tb.rulenode.period-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-period-seconds-message\' | translate }}\n \n \n
\n \n \n \n
\n\n \n \n \n \n \n \n \n
\n \n
\n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder},{type:oe.NodeScriptTestService},{type:Z.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}}),function(e){e.CUSTOMER="CUSTOMER",e.TENANT="TENANT",e.RELATED="RELATED",e.ALARM_ORIGINATOR="ALARM_ORIGINATOR",e.ENTITY="ENTITY"}(vt||(vt={}));const Ct=new Map([[vt.CUSTOMER,"tb.rulenode.originator-customer"],[vt.TENANT,"tb.rulenode.originator-tenant"],[vt.RELATED,"tb.rulenode.originator-related"],[vt.ALARM_ORIGINATOR,"tb.rulenode.originator-alarm-originator"],[vt.ENTITY,"tb.rulenode.originator-entity"]]),Ft=new Map([[vt.CUSTOMER,"tb.rulenode.originator-customer-desc"],[vt.TENANT,"tb.rulenode.originator-tenant-desc"],[vt.RELATED,"tb.rulenode.originator-related-entity-desc"],[vt.ALARM_ORIGINATOR,"tb.rulenode.originator-alarm-originator-desc"],[vt.ENTITY,"tb.rulenode.originator-entity-by-name-pattern-desc"]]),kt=[k.createdTime,k.name,{value:"type",name:"tb.rulenode.profile-name",keyName:"originatorProfileName"},k.firstName,k.lastName,k.email,k.title,k.country,k.state,k.city,k.address,k.address2,k.zip,k.phone,k.label,{value:"id",name:"tb.rulenode.id",keyName:"id"},{value:"additionalInfo",name:"tb.rulenode.additional-info",keyName:"additionalInfo"}],Lt=new Map([["type","profileName"],["createdTime","createdTime"],["name","name"],["firstName","firstName"],["lastName","lastName"],["email","email"],["title","title"],["country","country"],["state","state"],["city","city"],["address","address"],["address2","address2"],["zip","zip"],["phone","phone"],["label","label"],["id","id"],["additionalInfo","additionalInfo"]]);var Tt;!function(e){e.CIRCLE="CIRCLE",e.POLYGON="POLYGON"}(Tt||(Tt={}));const It=new Map([[Tt.CIRCLE,"tb.rulenode.perimeter-circle"],[Tt.POLYGON,"tb.rulenode.perimeter-polygon"]]);var Nt;!function(e){e.MILLISECONDS="MILLISECONDS",e.SECONDS="SECONDS",e.MINUTES="MINUTES",e.HOURS="HOURS",e.DAYS="DAYS"}(Nt||(Nt={}));const St=new Map([[Nt.MILLISECONDS,"tb.rulenode.time-unit-milliseconds"],[Nt.SECONDS,"tb.rulenode.time-unit-seconds"],[Nt.MINUTES,"tb.rulenode.time-unit-minutes"],[Nt.HOURS,"tb.rulenode.time-unit-hours"],[Nt.DAYS,"tb.rulenode.time-unit-days"]]);var qt;!function(e){e.METER="METER",e.KILOMETER="KILOMETER",e.FOOT="FOOT",e.MILE="MILE",e.NAUTICAL_MILE="NAUTICAL_MILE"}(qt||(qt={}));const At=new Map([[qt.METER,"tb.rulenode.range-unit-meter"],[qt.KILOMETER,"tb.rulenode.range-unit-kilometer"],[qt.FOOT,"tb.rulenode.range-unit-foot"],[qt.MILE,"tb.rulenode.range-unit-mile"],[qt.NAUTICAL_MILE,"tb.rulenode.range-unit-nautical-mile"]]);var Mt;!function(e){e.ID="ID",e.TITLE="TITLE",e.COUNTRY="COUNTRY",e.STATE="STATE",e.CITY="CITY",e.ZIP="ZIP",e.ADDRESS="ADDRESS",e.ADDRESS2="ADDRESS2",e.PHONE="PHONE",e.EMAIL="EMAIL",e.ADDITIONAL_INFO="ADDITIONAL_INFO"}(Mt||(Mt={}));const Et=new Map([[Mt.ID,"tb.rulenode.entity-details-id"],[Mt.TITLE,"tb.rulenode.entity-details-title"],[Mt.COUNTRY,"tb.rulenode.entity-details-country"],[Mt.STATE,"tb.rulenode.entity-details-state"],[Mt.CITY,"tb.rulenode.entity-details-city"],[Mt.ZIP,"tb.rulenode.entity-details-zip"],[Mt.ADDRESS,"tb.rulenode.entity-details-address"],[Mt.ADDRESS2,"tb.rulenode.entity-details-address2"],[Mt.PHONE,"tb.rulenode.entity-details-phone"],[Mt.EMAIL,"tb.rulenode.entity-details-email"],[Mt.ADDITIONAL_INFO,"tb.rulenode.entity-details-additional_info"]]);var Gt;!function(e){e.FIRST="FIRST",e.LAST="LAST",e.ALL="ALL"}(Gt||(Gt={}));const Dt=new Map([[Gt.FIRST,"tb.rulenode.first"],[Gt.LAST,"tb.rulenode.last"],[Gt.ALL,"tb.rulenode.all"]]),wt=new Map([[Gt.FIRST,"tb.rulenode.first-mode-hint"],[Gt.LAST,"tb.rulenode.last-mode-hint"],[Gt.ALL,"tb.rulenode.all-mode-hint"]]);var Vt,Pt;!function(e){e.ASC="ASC",e.DESC="DESC"}(Vt||(Vt={})),function(e){e.ATTRIBUTES="ATTRIBUTES",e.LATEST_TELEMETRY="LATEST_TELEMETRY",e.FIELDS="FIELDS"}(Pt||(Pt={}));const Rt=new Map([[Pt.ATTRIBUTES,"tb.rulenode.attributes"],[Pt.LATEST_TELEMETRY,"tb.rulenode.latest-telemetry"],[Pt.FIELDS,"tb.rulenode.fields"]]),Ot=new Map([[Pt.ATTRIBUTES,"tb.rulenode.add-mapped-attribute-to"],[Pt.LATEST_TELEMETRY,"tb.rulenode.add-mapped-latest-telemetry-to"],[Pt.FIELDS,"tb.rulenode.add-mapped-fields-to"]]),_t=new Map([[Vt.ASC,"tb.rulenode.ascending"],[Vt.DESC,"tb.rulenode.descending"]]);var Bt;!function(e){e.STANDARD="STANDARD",e.FIFO="FIFO"}(Bt||(Bt={}));const Kt=new Map([[Bt.STANDARD,"tb.rulenode.sqs-queue-standard"],[Bt.FIFO,"tb.rulenode.sqs-queue-fifo"]]),zt=["anonymous","basic","cert.PEM"],Ut=new Map([["anonymous","tb.rulenode.credentials-anonymous"],["basic","tb.rulenode.credentials-basic"],["cert.PEM","tb.rulenode.credentials-pem"]]),Ht=["sas","cert.PEM"],jt=new Map([["sas","tb.rulenode.credentials-sas"],["cert.PEM","tb.rulenode.credentials-pem"]]);var $t;!function(e){e.GET="GET",e.POST="POST",e.PUT="PUT",e.DELETE="DELETE"}($t||($t={}));const Qt=["US-ASCII","ISO-8859-1","UTF-8","UTF-16BE","UTF-16LE","UTF-16"],Jt=new Map([["US-ASCII","tb.rulenode.charset-us-ascii"],["ISO-8859-1","tb.rulenode.charset-iso-8859-1"],["UTF-8","tb.rulenode.charset-utf-8"],["UTF-16BE","tb.rulenode.charset-utf-16be"],["UTF-16LE","tb.rulenode.charset-utf-16le"],["UTF-16","tb.rulenode.charset-utf-16"]]);var Yt;!function(e){e.CUSTOM="CUSTOM",e.ADD="ADD",e.SUB="SUB",e.MULT="MULT",e.DIV="DIV",e.SIN="SIN",e.SINH="SINH",e.COS="COS",e.COSH="COSH",e.TAN="TAN",e.TANH="TANH",e.ACOS="ACOS",e.ASIN="ASIN",e.ATAN="ATAN",e.ATAN2="ATAN2",e.EXP="EXP",e.EXPM1="EXPM1",e.SQRT="SQRT",e.CBRT="CBRT",e.GET_EXP="GET_EXP",e.HYPOT="HYPOT",e.LOG="LOG",e.LOG10="LOG10",e.LOG1P="LOG1P",e.CEIL="CEIL",e.FLOOR="FLOOR",e.FLOOR_DIV="FLOOR_DIV",e.FLOOR_MOD="FLOOR_MOD",e.ABS="ABS",e.MIN="MIN",e.MAX="MAX",e.POW="POW",e.SIGNUM="SIGNUM",e.RAD="RAD",e.DEG="DEG"}(Yt||(Yt={}));const Wt=new Map([[Yt.CUSTOM,{value:Yt.CUSTOM,name:"Custom Function",description:"Use this function to specify complex mathematical expression.",minArgs:1,maxArgs:16}],[Yt.ADD,{value:Yt.ADD,name:"Addition",description:"x + y",minArgs:2,maxArgs:2}],[Yt.SUB,{value:Yt.SUB,name:"Subtraction",description:"x - y",minArgs:2,maxArgs:2}],[Yt.MULT,{value:Yt.MULT,name:"Multiplication",description:"x * y",minArgs:2,maxArgs:2}],[Yt.DIV,{value:Yt.DIV,name:"Division",description:"x / y",minArgs:2,maxArgs:2}],[Yt.SIN,{value:Yt.SIN,name:"Sine",description:"Returns the trigonometric sine of an angle in radians.",minArgs:1,maxArgs:1}],[Yt.SINH,{value:Yt.SINH,name:"Hyperbolic sine",description:"Returns the hyperbolic sine of an argument.",minArgs:1,maxArgs:1}],[Yt.COS,{value:Yt.COS,name:"Cosine",description:"Returns the trigonometric cosine of an angle in radians.",minArgs:1,maxArgs:1}],[Yt.COSH,{value:Yt.COSH,name:"Hyperbolic cosine",description:"Returns the hyperbolic cosine of an argument.",minArgs:1,maxArgs:1}],[Yt.TAN,{value:Yt.TAN,name:"Tangent",description:"Returns the trigonometric tangent of an angle in radians",minArgs:1,maxArgs:1}],[Yt.TANH,{value:Yt.TANH,name:"Hyperbolic tangent",description:"Returns the hyperbolic tangent of an argument",minArgs:1,maxArgs:1}],[Yt.ACOS,{value:Yt.ACOS,name:"Arc cosine",description:"Returns the arc cosine of an argument",minArgs:1,maxArgs:1}],[Yt.ASIN,{value:Yt.ASIN,name:"Arc sine",description:"Returns the arc sine of an argument",minArgs:1,maxArgs:1}],[Yt.ATAN,{value:Yt.ATAN,name:"Arc tangent",description:"Returns the arc tangent of an argument",minArgs:1,maxArgs:1}],[Yt.ATAN2,{value:Yt.ATAN2,name:"2-argument arc tangent",description:"Returns the angle theta from the conversion of rectangular coordinates (x, y) to polar coordinates (r, theta)",minArgs:2,maxArgs:2}],[Yt.EXP,{value:Yt.EXP,name:"Exponential",description:"Returns Euler's number e raised to the power of an argument",minArgs:1,maxArgs:1}],[Yt.EXPM1,{value:Yt.EXPM1,name:"Exponential minus one",description:"Returns Euler's number e raised to the power of an argument minus one",minArgs:1,maxArgs:1}],[Yt.SQRT,{value:Yt.SQRT,name:"Square",description:"Returns the correctly rounded positive square root of an argument",minArgs:1,maxArgs:1}],[Yt.CBRT,{value:Yt.CBRT,name:"Cube root",description:"Returns the cube root of an argument",minArgs:1,maxArgs:1}],[Yt.GET_EXP,{value:Yt.GET_EXP,name:"Get exponent",description:"Returns the unbiased exponent used in the representation of an argument",minArgs:1,maxArgs:1}],[Yt.HYPOT,{value:Yt.HYPOT,name:"Square root",description:"Returns the square root of the squares of the arguments",minArgs:2,maxArgs:2}],[Yt.LOG,{value:Yt.LOG,name:"Logarithm",description:"Returns the natural logarithm of an argument",minArgs:1,maxArgs:1}],[Yt.LOG10,{value:Yt.LOG10,name:"Base 10 logarithm",description:"Returns the base 10 logarithm of an argument",minArgs:1,maxArgs:1}],[Yt.LOG1P,{value:Yt.LOG1P,name:"Logarithm of the sum",description:"Returns the natural logarithm of the sum of an argument",minArgs:1,maxArgs:1}],[Yt.CEIL,{value:Yt.CEIL,name:"Ceiling",description:"Returns the smallest (closest to negative infinity) of an argument",minArgs:1,maxArgs:1}],[Yt.FLOOR,{value:Yt.FLOOR,name:"Floor",description:"Returns the largest (closest to positive infinity) of an argument",minArgs:1,maxArgs:1}],[Yt.FLOOR_DIV,{value:Yt.FLOOR_DIV,name:"Floor division",description:"Returns the largest (closest to positive infinity) of the arguments",minArgs:2,maxArgs:2}],[Yt.FLOOR_MOD,{value:Yt.FLOOR_MOD,name:"Floor modulus",description:"Returns the floor modulus of the arguments",minArgs:2,maxArgs:2}],[Yt.ABS,{value:Yt.ABS,name:"Absolute",description:"Returns the absolute value of an argument",minArgs:1,maxArgs:1}],[Yt.MIN,{value:Yt.MIN,name:"Min",description:"Returns the smaller of the arguments",minArgs:2,maxArgs:2}],[Yt.MAX,{value:Yt.MAX,name:"Max",description:"Returns the greater of the arguments",minArgs:2,maxArgs:2}],[Yt.POW,{value:Yt.POW,name:"Raise to a power",description:"Returns the value of the first argument raised to the power of the second argument",minArgs:2,maxArgs:2}],[Yt.SIGNUM,{value:Yt.SIGNUM,name:"Sign of a real number",description:"Returns the signum function of the argument",minArgs:1,maxArgs:1}],[Yt.RAD,{value:Yt.RAD,name:"Radian",description:"Converts an angle measured in degrees to an approximately equivalent angle measured in radians",minArgs:1,maxArgs:1}],[Yt.DEG,{value:Yt.DEG,name:"Degrees",description:"Converts an angle measured in radians to an approximately equivalent angle measured in degrees.",minArgs:1,maxArgs:1}]]);var Zt,Xt,en;!function(e){e.MESSAGE_BODY="MESSAGE_BODY",e.MESSAGE_METADATA="MESSAGE_METADATA",e.ATTRIBUTE="ATTRIBUTE",e.TIME_SERIES="TIME_SERIES",e.CONSTANT="CONSTANT"}(Zt||(Zt={})),function(e){e.MESSAGE_BODY="MESSAGE_BODY",e.MESSAGE_METADATA="MESSAGE_METADATA",e.ATTRIBUTE="ATTRIBUTE",e.TIME_SERIES="TIME_SERIES"}(Xt||(Xt={})),function(e){e.DATA="DATA",e.METADATA="METADATA"}(en||(en={}));const tn=new Map([[en.DATA,"tb.rulenode.message-to-metadata"],[en.METADATA,"tb.rulenode.metadata-to-message"]]),nn=(new Map([[en.DATA,"tb.rulenode.from-message"],[en.METADATA,"tb.rulenode.from-metadata"]]),new Map([[en.DATA,"tb.rulenode.message"],[en.METADATA,"tb.rulenode.metadata"]])),rn=new Map([[en.DATA,"tb.rulenode.message"],[en.METADATA,"tb.rulenode.message-metadata"]]),on=new Map([[Zt.MESSAGE_BODY,{name:"tb.rulenode.message-body-type",description:"Fetch argument value from incoming message"}],[Zt.MESSAGE_METADATA,{name:"tb.rulenode.message-metadata-type",description:"Fetch argument value from incoming message metadata"}],[Zt.ATTRIBUTE,{name:"tb.rulenode.attribute-type",description:"Fetch attribute value from database"}],[Zt.TIME_SERIES,{name:"tb.rulenode.time-series-type",description:"Fetch latest time-series value from database"}],[Zt.CONSTANT,{name:"tb.rulenode.constant-type",description:"Define constant value"}]]),an=new Map([[Xt.MESSAGE_BODY,{name:"tb.rulenode.message-body-type",description:"Add result to the outgoing message"}],[Xt.MESSAGE_METADATA,{name:"tb.rulenode.message-metadata-type",description:"Add result to the outgoing message metadata"}],[Xt.ATTRIBUTE,{name:"tb.rulenode.attribute-type",description:"Store result as an entity attribute in the database"}],[Xt.TIME_SERIES,{name:"tb.rulenode.time-series-type",description:"Store result as an entity time-series in the database"}]]),ln=["x","y","z","a","b","c","d","k","l","m","n","o","p","r","s","t"];var sn,mn;!function(e){e.SHARED_SCOPE="SHARED_SCOPE",e.SERVER_SCOPE="SERVER_SCOPE",e.CLIENT_SCOPE="CLIENT_SCOPE"}(sn||(sn={})),function(e){e.SHARED_SCOPE="SHARED_SCOPE",e.SERVER_SCOPE="SERVER_SCOPE"}(mn||(mn={}));const pn=new Map([[sn.SHARED_SCOPE,"tb.rulenode.shared-scope"],[sn.SERVER_SCOPE,"tb.rulenode.server-scope"],[sn.CLIENT_SCOPE,"tb.rulenode.client-scope"]]);class dn extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.perimeterType=Tt,this.perimeterTypes=Object.keys(Tt),this.perimeterTypeTranslationMap=It,this.rangeUnits=Object.keys(qt),this.rangeUnitTranslationMap=At,this.timeUnits=Object.keys(Nt),this.timeUnitsTranslationMap=St}configForm(){return this.geoActionConfigForm}onConfigurationSet(e){this.geoActionConfigForm=this.fb.group({latitudeKeyName:[e?e.latitudeKeyName:null,[O.required]],longitudeKeyName:[e?e.longitudeKeyName:null,[O.required]],perimeterType:[e?e.perimeterType:null,[O.required]],fetchPerimeterInfoFromMessageMetadata:[!!e&&e.fetchPerimeterInfoFromMessageMetadata,[]],perimeterKeyName:[e?e.perimeterKeyName:null,[]],centerLatitude:[e?e.centerLatitude:null,[]],centerLongitude:[e?e.centerLatitude:null,[]],range:[e?e.range:null,[]],rangeUnit:[e?e.rangeUnit:null,[]],polygonsDefinition:[e?e.polygonsDefinition:null,[]],minInsideDuration:[e?e.minInsideDuration:null,[O.required,O.min(1),O.max(2147483647)]],minInsideDurationTimeUnit:[e?e.minInsideDurationTimeUnit:null,[O.required]],minOutsideDuration:[e?e.minOutsideDuration:null,[O.required,O.min(1),O.max(2147483647)]],minOutsideDurationTimeUnit:[e?e.minOutsideDurationTimeUnit:null,[O.required]]})}validatorTriggers(){return["fetchPerimeterInfoFromMessageMetadata","perimeterType"]}updateValidators(e){const t=this.geoActionConfigForm.get("fetchPerimeterInfoFromMessageMetadata").value,n=this.geoActionConfigForm.get("perimeterType").value;t?this.geoActionConfigForm.get("perimeterKeyName").setValidators([O.required]):this.geoActionConfigForm.get("perimeterKeyName").setValidators([]),t||n!==Tt.CIRCLE?(this.geoActionConfigForm.get("centerLatitude").setValidators([]),this.geoActionConfigForm.get("centerLongitude").setValidators([]),this.geoActionConfigForm.get("range").setValidators([]),this.geoActionConfigForm.get("rangeUnit").setValidators([])):(this.geoActionConfigForm.get("centerLatitude").setValidators([O.required,O.min(-90),O.max(90)]),this.geoActionConfigForm.get("centerLongitude").setValidators([O.required,O.min(-180),O.max(180)]),this.geoActionConfigForm.get("range").setValidators([O.required,O.min(0)]),this.geoActionConfigForm.get("rangeUnit").setValidators([O.required])),t||n!==Tt.POLYGON?this.geoActionConfigForm.get("polygonsDefinition").setValidators([]):this.geoActionConfigForm.get("polygonsDefinition").setValidators([O.required]),this.geoActionConfigForm.get("perimeterKeyName").updateValueAndValidity({emitEvent:e}),this.geoActionConfigForm.get("centerLatitude").updateValueAndValidity({emitEvent:e}),this.geoActionConfigForm.get("centerLongitude").updateValueAndValidity({emitEvent:e}),this.geoActionConfigForm.get("range").updateValueAndValidity({emitEvent:e}),this.geoActionConfigForm.get("rangeUnit").updateValueAndValidity({emitEvent:e}),this.geoActionConfigForm.get("polygonsDefinition").updateValueAndValidity({emitEvent:e})}}e("GpsGeoActionConfigComponent",dn),dn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:dn,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),dn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:dn,selector:"tb-action-node-gps-geofencing-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.latitude-key-name\n \n \n {{ \'tb.rulenode.latitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.longitude-key-name\n \n \n {{ \'tb.rulenode.longitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.perimeter-type\n \n \n {{ perimeterTypeTranslationMap.get(type) | translate }}\n \n \n \n \n {{ \'tb.rulenode.fetch-perimeter-info-from-metadata\' | translate }}\n \n \n tb.rulenode.perimeter-key-name\n \n \n {{ \'tb.rulenode.perimeter-key-name-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.circle-center-latitude\n \n \n {{ \'tb.rulenode.circle-center-latitude-required\' | translate }}\n \n \n \n tb.rulenode.circle-center-longitude\n \n \n {{ \'tb.rulenode.circle-center-longitude-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.range\n \n \n {{ \'tb.rulenode.range-required\' | translate }}\n \n \n \n tb.rulenode.range-units\n \n \n {{ rangeUnitTranslationMap.get(type) | translate }}\n \n \n \n
\n
\n
\n \n tb.rulenode.polygon-definition\n \n \n {{ \'tb.rulenode.polygon-definition-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.min-inside-duration\n \n \n {{ \'tb.rulenode.min-inside-duration-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n tb.rulenode.min-inside-duration-time-unit\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n \n tb.rulenode.min-outside-duration\n \n \n {{ \'tb.rulenode.min-outside-duration-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n tb.rulenode.min-outside-duration-time-unit\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Q.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:dn,decorators:[{type:n,args:[{selector:"tb-action-node-gps-geofencing-config",template:'
\n \n tb.rulenode.latitude-key-name\n \n \n {{ \'tb.rulenode.latitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.longitude-key-name\n \n \n {{ \'tb.rulenode.longitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.perimeter-type\n \n \n {{ perimeterTypeTranslationMap.get(type) | translate }}\n \n \n \n \n {{ \'tb.rulenode.fetch-perimeter-info-from-metadata\' | translate }}\n \n \n tb.rulenode.perimeter-key-name\n \n \n {{ \'tb.rulenode.perimeter-key-name-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.circle-center-latitude\n \n \n {{ \'tb.rulenode.circle-center-latitude-required\' | translate }}\n \n \n \n tb.rulenode.circle-center-longitude\n \n \n {{ \'tb.rulenode.circle-center-longitude-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.range\n \n \n {{ \'tb.rulenode.range-required\' | translate }}\n \n \n \n tb.rulenode.range-units\n \n \n {{ rangeUnitTranslationMap.get(type) | translate }}\n \n \n \n
\n
\n
\n \n tb.rulenode.polygon-definition\n \n \n {{ \'tb.rulenode.polygon-definition-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.min-inside-duration\n \n \n {{ \'tb.rulenode.min-inside-duration-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n tb.rulenode.min-inside-duration-time-unit\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n \n tb.rulenode.min-outside-duration\n \n \n {{ \'tb.rulenode.min-outside-duration-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n tb.rulenode.min-outside-duration-time-unit\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class un extends f{constructor(e,t,n,o){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=n,this.translate=o,this.tbelEnabled=re(this.store).tbelEnabled,this.scriptLanguage=x,this.changeScript=new r,this.hasScript=!0,this.testScriptLabel="tb.rulenode.test-to-string-function"}configForm(){return this.logConfigForm}onConfigurationSet(e){this.logConfigForm=this.fb.group({scriptLang:[e?e.scriptLang:x.JS,[O.required]],jsScript:[e?e.jsScript:null,[]],tbelScript:[e?e.tbelScript:null,[]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.logConfigForm.get("scriptLang").value;t!==x.TBEL||this.tbelEnabled||(t=x.JS,this.logConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.logConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.logConfigForm.get("jsScript").setValidators(t===x.JS?[O.required]:[]),this.logConfigForm.get("jsScript").updateValueAndValidity({emitEvent:e}),this.logConfigForm.get("tbelScript").setValidators(t===x.TBEL?[O.required]:[]),this.logConfigForm.get("tbelScript").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=x.JS)),e}testScript(e){const t=this.logConfigForm.get("scriptLang").value,n=t===x.JS?"jsScript":"tbelScript",r=t===x.JS?"rulenode/log_node_script_fn":"rulenode/tbel/log_node_script_fn",o=this.logConfigForm.get(n).value;this.nodeScriptTestService.testNodeScript(o,"string",this.translate.instant("tb.rulenode.to-string"),"ToString",["msg","metadata","msgType"],this.ruleNodeId,r,t,e).subscribe((e=>{e&&(this.logConfigForm.get(n).setValue(e),this.changeScript.emit())}))}onValidate(){this.logConfigForm.get("scriptLang").value===x.JS&&this.jsFuncComponent.validateOnSubmit()}}e("LogConfigComponent",un),un.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:un,deps:[{token:P.Store},{token:R.UntypedFormBuilder},{token:oe.NodeScriptTestService},{token:Z.TranslateService}],target:t.ɵɵFactoryTarget.Component}),un.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:un,selector:"tb-action-node-log-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n \n \n
\n \n
\n
\n',dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:pe.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:de.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:de.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:fe.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:un,decorators:[{type:n,args:[{selector:"tb-action-node-log-config",template:'
\n \n \n \n \n \n \n \n
\n \n
\n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder},{type:oe.NodeScriptTestService},{type:Z.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}});class cn extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.msgCountConfigForm}onConfigurationSet(e){this.msgCountConfigForm=this.fb.group({interval:[e?e.interval:null,[O.required,O.min(1)]],telemetryPrefix:[e?e.telemetryPrefix:null,[O.required]]})}}e("MsgCountConfigComponent",cn),cn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:cn,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),cn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:cn,selector:"tb-action-node-msg-count-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.interval-seconds\n \n \n {{ \'tb.rulenode.interval-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-interval-seconds-message\' | translate }}\n \n \n \n tb.rulenode.output-timeseries-key-prefix\n \n \n {{ \'tb.rulenode.output-timeseries-key-prefix-required\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:cn,decorators:[{type:n,args:[{selector:"tb-action-node-msg-count-config",template:'
\n \n tb.rulenode.interval-seconds\n \n \n {{ \'tb.rulenode.interval-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-interval-seconds-message\' | translate }}\n \n \n \n tb.rulenode.output-timeseries-key-prefix\n \n \n {{ \'tb.rulenode.output-timeseries-key-prefix-required\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class fn extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.msgDelayConfigForm}onConfigurationSet(e){this.msgDelayConfigForm=this.fb.group({useMetadataPeriodInSecondsPatterns:[!!e&&e.useMetadataPeriodInSecondsPatterns,[]],periodInSeconds:[e?e.periodInSeconds:null,[]],periodInSecondsPattern:[e?e.periodInSecondsPattern:null,[]],maxPendingMsgs:[e?e.maxPendingMsgs:null,[O.required,O.min(1),O.max(1e5)]]})}validatorTriggers(){return["useMetadataPeriodInSecondsPatterns"]}updateValidators(e){this.msgDelayConfigForm.get("useMetadataPeriodInSecondsPatterns").value?(this.msgDelayConfigForm.get("periodInSecondsPattern").setValidators([O.required]),this.msgDelayConfigForm.get("periodInSeconds").setValidators([])):(this.msgDelayConfigForm.get("periodInSecondsPattern").setValidators([]),this.msgDelayConfigForm.get("periodInSeconds").setValidators([O.required,O.min(0)])),this.msgDelayConfigForm.get("periodInSecondsPattern").updateValueAndValidity({emitEvent:e}),this.msgDelayConfigForm.get("periodInSeconds").updateValueAndValidity({emitEvent:e})}}e("MsgDelayConfigComponent",fn),fn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:fn,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),fn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:fn,selector:"tb-action-node-msg-delay-config",usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.use-metadata-period-in-seconds-patterns\' | translate }}\n \n
tb.rulenode.use-metadata-period-in-seconds-patterns-hint
\n \n tb.rulenode.period-seconds\n \n \n {{ \'tb.rulenode.period-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-period-0-seconds-message\' | translate }}\n \n \n \n \n tb.rulenode.period-in-seconds-pattern\n \n \n {{ \'tb.rulenode.period-in-seconds-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n \n tb.rulenode.max-pending-messages\n \n \n {{ \'tb.rulenode.max-pending-messages-required\' | translate }}\n \n \n {{ \'tb.rulenode.max-pending-messages-range\' | translate }}\n \n \n {{ \'tb.rulenode.max-pending-messages-range\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Q.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:fn,decorators:[{type:n,args:[{selector:"tb-action-node-msg-delay-config",template:'
\n \n {{ \'tb.rulenode.use-metadata-period-in-seconds-patterns\' | translate }}\n \n
tb.rulenode.use-metadata-period-in-seconds-patterns-hint
\n \n tb.rulenode.period-seconds\n \n \n {{ \'tb.rulenode.period-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-period-0-seconds-message\' | translate }}\n \n \n \n \n tb.rulenode.period-in-seconds-pattern\n \n \n {{ \'tb.rulenode.period-in-seconds-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n \n tb.rulenode.max-pending-messages\n \n \n {{ \'tb.rulenode.max-pending-messages-required\' | translate }}\n \n \n {{ \'tb.rulenode.max-pending-messages-range\' | translate }}\n \n \n {{ \'tb.rulenode.max-pending-messages-range\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class gn extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.attributeScopes=Object.keys(g),this.telemetryTypeTranslationsMap=y}configForm(){return this.pushToCloudConfigForm}onConfigurationSet(e){this.pushToCloudConfigForm=this.fb.group({scope:[e?e.scope:null,[O.required]]})}}e("PushToCloudConfigComponent",gn),gn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:gn,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),gn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:gn,selector:"tb-action-node-push-to-cloud-config",usesInheritance:!0,ngImport:t,template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:gn,decorators:[{type:n,args:[{selector:"tb-action-node-push-to-cloud-config",template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class yn extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.attributeScopes=Object.keys(g),this.telemetryTypeTranslationsMap=y}configForm(){return this.pushToEdgeConfigForm}onConfigurationSet(e){this.pushToEdgeConfigForm=this.fb.group({scope:[e?e.scope:null,[O.required]]})}}e("PushToEdgeConfigComponent",yn),yn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:yn,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),yn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:yn,selector:"tb-action-node-push-to-edge-config",usesInheritance:!0,ngImport:t,template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:yn,decorators:[{type:n,args:[{selector:"tb-action-node-push-to-edge-config",template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class xn extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.rpcReplyConfigForm}onConfigurationSet(e){this.rpcReplyConfigForm=this.fb.group({requestIdMetaDataAttribute:[e?e.requestIdMetaDataAttribute:null,[]]})}}e("RpcReplyConfigComponent",xn),xn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:xn,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),xn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:xn,selector:"tb-action-node-rpc-reply-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.request-id-metadata-attribute\n \n \n
\n',dependencies:[{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:xn,decorators:[{type:n,args:[{selector:"tb-action-node-rpc-reply-config",template:'
\n \n tb.rulenode.request-id-metadata-attribute\n \n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class bn extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.rpcRequestConfigForm}onConfigurationSet(e){this.rpcRequestConfigForm=this.fb.group({timeoutInSeconds:[e?e.timeoutInSeconds:null,[O.required,O.min(0)]]})}}e("RpcRequestConfigComponent",bn),bn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:bn,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),bn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:bn,selector:"tb-action-node-rpc-request-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.timeout-sec\n \n \n {{ \'tb.rulenode.timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-timeout-message\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:bn,decorators:[{type:n,args:[{selector:"tb-action-node-rpc-request-config",template:'
\n \n tb.rulenode.timeout-sec\n \n \n {{ \'tb.rulenode.timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-timeout-message\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class hn extends L{get required(){return this.requiredValue}set required(e){this.requiredValue=Fe(e)}constructor(e,t,n,r){super(e),this.store=e,this.translate=t,this.injector=n,this.fb=r,this.propagateChange=null,this.valueChangeSubscription=null}ngOnInit(){this.ngControl=this.injector.get(_),null!=this.ngControl&&(this.ngControl.valueAccessor=this),this.kvListFormGroup=this.fb.group({}),this.kvListFormGroup.addControl("keyVals",this.fb.array([]))}keyValsFormArray(){return this.kvListFormGroup.get("keyVals")}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.kvListFormGroup.disable({emitEvent:!1}):this.kvListFormGroup.enable({emitEvent:!1})}writeValue(e){this.valueChangeSubscription&&this.valueChangeSubscription.unsubscribe();const t=[];if(e)for(const n of Object.keys(e))Object.prototype.hasOwnProperty.call(e,n)&&t.push(this.fb.group({key:[n,[O.required]],value:[e[n],[O.required]]}));this.kvListFormGroup.setControl("keyVals",this.fb.array(t)),this.valueChangeSubscription=this.kvListFormGroup.valueChanges.subscribe((()=>{this.updateModel()}))}removeKeyVal(e){this.kvListFormGroup.get("keyVals").removeAt(e)}addKeyVal(){this.kvListFormGroup.get("keyVals").push(this.fb.group({key:["",[O.required]],value:["",[O.required]]}))}validate(e){const t=this.kvListFormGroup.get("keyVals").value;if(!t.length&&this.required)return{kvMapRequired:!0};if(!this.kvListFormGroup.valid)return{kvFieldsRequired:!0};if(this.uniqueKeyValuePairValidator)for(const e of t)if(e.key===e.value)return{uniqueKeyValuePair:!0};return null}updateModel(){const e=this.kvListFormGroup.get("keyVals").value;if(this.required&&!e.length||!this.kvListFormGroup.valid)this.propagateChange(null);else{const t={};e.forEach((e=>{t[e.key]=e.value})),this.propagateChange(t)}}}e("KvMapConfigOldComponent",hn),hn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:hn,deps:[{token:P.Store},{token:Z.TranslateService},{token:t.Injector},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),hn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:hn,selector:"tb-kv-map-config-old",inputs:{disabled:"disabled",uniqueKeyValuePairValidator:"uniqueKeyValuePairValidator",requiredText:"requiredText",keyText:"keyText",keyRequiredText:"keyRequiredText",valText:"valText",valRequiredText:"valRequiredText",hintText:"hintText",required:"required"},providers:[{provide:B,useExisting:a((()=>hn)),multi:!0},{provide:K,useExisting:a((()=>hn)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n
\n {{ keyText | translate }}\n {{ valText | translate }}\n \n
\n
\n
\n \n \n \n {{ keyRequiredText | translate }}\n \n \n \n \n \n {{ valRequiredText | translate }}\n \n \n \n
\n
\n
\n \n
\n \n
\n
\n',styles:[":host .tb-kv-map-config{margin-bottom:16px}:host .tb-kv-map-config .header{padding-left:5px;padding-right:5px;padding-bottom:5px}:host .tb-kv-map-config .header .cell{padding-left:5px;padding-right:5px;color:#757575;font-size:12px;font-weight:700;white-space:nowrap}:host .tb-kv-map-config .body{padding-left:5px;padding-right:5px;padding-bottom:0;max-height:300px;overflow:auto}:host .tb-kv-map-config .body .cell{padding-left:5px;padding-right:5px}:host .tb-kv-map-config tb-error{display:block;margin-top:-12px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Te.TbErrorComponent,selector:"tb-error",inputs:["noMargin","error"]},{kind:"component",type:de.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:de.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:W.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:Ie.DefaultShowHideDirective,selector:" [fxShow], [fxShow.print], [fxShow.xs], [fxShow.sm], [fxShow.md], [fxShow.lg], [fxShow.xl], [fxShow.lt-sm], [fxShow.lt-md], [fxShow.lt-lg], [fxShow.lt-xl], [fxShow.gt-xs], [fxShow.gt-sm], [fxShow.gt-md], [fxShow.gt-lg], [fxHide], [fxHide.print], [fxHide.xs], [fxHide.sm], [fxHide.md], [fxHide.lg], [fxHide.xl], [fxHide.lt-sm], [fxHide.lt-md], [fxHide.lt-lg], [fxHide.lt-xl], [fxHide.gt-xs], [fxHide.gt-sm], [fxHide.gt-md], [fxHide.gt-lg]",inputs:["fxShow","fxShow.print","fxShow.xs","fxShow.sm","fxShow.md","fxShow.lg","fxShow.xl","fxShow.lt-sm","fxShow.lt-md","fxShow.lt-lg","fxShow.lt-xl","fxShow.gt-xs","fxShow.gt-sm","fxShow.gt-md","fxShow.gt-lg","fxHide","fxHide.print","fxHide.xs","fxHide.sm","fxHide.md","fxHide.lg","fxHide.xl","fxHide.lt-sm","fxHide.lt-md","fxHide.lt-lg","fxHide.lt-xl","fxHide.gt-xs","fxHide.gt-sm","fxHide.gt-md","fxHide.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormControlDirective,selector:"[formControl]",inputs:["formControl","disabled","ngModel"],outputs:["ngModelChange"],exportAs:["ngForm"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormArrayName,selector:"[formArrayName]",inputs:["formArrayName"]},{kind:"pipe",type:H.AsyncPipe,name:"async"},{kind:"pipe",type:he.SafePipe,name:"safe"},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:hn,decorators:[{type:n,args:[{selector:"tb-kv-map-config-old",providers:[{provide:B,useExisting:a((()=>hn)),multi:!0},{provide:K,useExisting:a((()=>hn)),multi:!0}],template:'
\n
\n {{ keyText | translate }}\n {{ valText | translate }}\n \n
\n
\n
\n \n \n \n {{ keyRequiredText | translate }}\n \n \n \n \n \n {{ valRequiredText | translate }}\n \n \n \n
\n
\n
\n \n
\n \n
\n
\n',styles:[":host .tb-kv-map-config{margin-bottom:16px}:host .tb-kv-map-config .header{padding-left:5px;padding-right:5px;padding-bottom:5px}:host .tb-kv-map-config .header .cell{padding-left:5px;padding-right:5px;color:#757575;font-size:12px;font-weight:700;white-space:nowrap}:host .tb-kv-map-config .body{padding-left:5px;padding-right:5px;padding-bottom:0;max-height:300px;overflow:auto}:host .tb-kv-map-config .body .cell{padding-left:5px;padding-right:5px}:host .tb-kv-map-config tb-error{display:block;margin-top:-12px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:P.Store},{type:Z.TranslateService},{type:t.Injector},{type:R.FormBuilder}]},propDecorators:{disabled:[{type:i}],uniqueKeyValuePairValidator:[{type:i}],requiredText:[{type:i}],keyText:[{type:i}],keyRequiredText:[{type:i}],valText:[{type:i}],valRequiredText:[{type:i}],hintText:[{type:i}],required:[{type:i}]}});class vn extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.saveToCustomTableConfigForm}onConfigurationSet(e){this.saveToCustomTableConfigForm=this.fb.group({tableName:[e?e.tableName:null,[O.required,O.pattern(/.*\S.*/)]],fieldsMapping:[e?e.fieldsMapping:null,[O.required]]})}prepareOutputConfig(e){return e.tableName=e.tableName.trim(),e}}e("SaveToCustomTableConfigComponent",vn),vn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:vn,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),vn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:vn,selector:"tb-action-node-custom-table-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.custom-table-name\n \n \n {{ \'tb.rulenode.custom-table-name-required\' | translate }}\n \n tb.rulenode.custom-table-hint\n \n \n \n \n
\n',dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:hn,selector:"tb-kv-map-config-old",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:vn,decorators:[{type:n,args:[{selector:"tb-action-node-custom-table-config",template:'
\n \n tb.rulenode.custom-table-name\n \n \n {{ \'tb.rulenode.custom-table-name-required\' | translate }}\n \n tb.rulenode.custom-table-hint\n \n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class Cn extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.timeseriesConfigForm}onConfigurationSet(e){this.timeseriesConfigForm=this.fb.group({defaultTTL:[e?e.defaultTTL:null,[O.required,O.min(0)]],skipLatestPersistence:[!!e&&e.skipLatestPersistence,[]],useServerTs:[!!e&&e.useServerTs,[]]})}}e("TimeseriesConfigComponent",Cn),Cn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Cn,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Cn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Cn,selector:"tb-action-node-timeseries-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.default-ttl\n \n \n {{ \'tb.rulenode.default-ttl-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-default-ttl-message\' | translate }}\n \n \n \n {{ \'tb.rulenode.skip-latest-persistence\' | translate }}\n \n \n {{ \'tb.rulenode.use-server-ts\' | translate }}\n \n
tb.rulenode.use-server-ts-hint
\n
\n',dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Q.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Cn,decorators:[{type:n,args:[{selector:"tb-action-node-timeseries-config",template:'
\n \n tb.rulenode.default-ttl\n \n \n {{ \'tb.rulenode.default-ttl-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-default-ttl-message\' | translate }}\n \n \n \n {{ \'tb.rulenode.skip-latest-persistence\' | translate }}\n \n \n {{ \'tb.rulenode.use-server-ts\' | translate }}\n \n
tb.rulenode.use-server-ts-hint
\n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class Fn extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.unassignCustomerConfigForm}onConfigurationSet(e){this.unassignCustomerConfigForm=this.fb.group({customerNamePattern:[e?e.customerNamePattern:null,[O.required,O.pattern(/.*\S.*/)]],customerCacheExpiration:[e?e.customerCacheExpiration:null,[O.required,O.min(0)]]})}prepareOutputConfig(e){return e.customerNamePattern=e.customerNamePattern.trim(),e}}e("UnassignCustomerConfigComponent",Fn),Fn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Fn,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Fn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Fn,selector:"tb-action-node-un-assign-to-customer-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.customer-name-pattern\n \n \n {{ \'tb.rulenode.customer-name-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.customer-cache-expiration\n \n \n {{ \'tb.rulenode.customer-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.customer-cache-expiration-range\' | translate }}\n \n tb.rulenode.customer-cache-expiration-hint\n \n
\n',dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Fn,decorators:[{type:n,args:[{selector:"tb-action-node-un-assign-to-customer-config",template:'
\n \n tb.rulenode.customer-name-pattern\n \n \n {{ \'tb.rulenode.customer-name-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.customer-cache-expiration\n \n \n {{ \'tb.rulenode.customer-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.customer-cache-expiration-range\' | translate }}\n \n tb.rulenode.customer-cache-expiration-hint\n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class kn extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.attributeScopeMap=g,this.attributeScopes=Object.keys(g),this.telemetryTypeTranslationsMap=y,this.separatorKeysCodes=[ge,ye,xe]}configForm(){return this.deleteAttributesConfigForm}onConfigurationSet(e){this.deleteAttributesConfigForm=this.fb.group({scope:[e?e.scope:null,[O.required]],keys:[e?e.keys:null,[O.required]],sendAttributesDeletedNotification:[!!e&&e.sendAttributesDeletedNotification,[]],notifyDevice:[!!e&&e.notifyDevice,[]]}),this.deleteAttributesConfigForm.get("scope").valueChanges.subscribe((e=>{e!==g.SHARED_SCOPE&&this.deleteAttributesConfigForm.get("notifyDevice").patchValue(!1,{emitEvent:!1})}))}removeKey(e){const t=this.deleteAttributesConfigForm.get("keys").value,n=t.indexOf(e);n>=0&&(t.splice(n,1),this.deleteAttributesConfigForm.get("keys").patchValue(t,{emitEvent:!0}))}addKey(e){const t=e.input;let n=e.value;if((n||"").trim()){n=n.trim();let e=this.deleteAttributesConfigForm.get("keys").value;e&&-1!==e.indexOf(n)||(e||(e=[]),e.push(n),this.deleteAttributesConfigForm.get("keys").patchValue(e,{emitEvent:!0}))}t&&(t.value="")}}e("DeleteAttributesConfigComponent",kn),kn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:kn,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),kn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:kn,selector:"tb-action-node-delete-attributes-config",viewQueries:[{propertyName:"attributeChipList",first:!0,predicate:["attributeChipList"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'attribute.attributes-scope\' | translate }}\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n \n {{ \'tb.rulenode.attributes-keys\' | translate }}\n \n \n {{key}}\n close\n \n \n \n {{ \'tb.rulenode.attributes-keys-required\' | translate }}\n tb.rulenode.general-pattern-hint\n \n \n {{ \'tb.rulenode.send-attributes-deleted-notification\' | translate }}\n \n
tb.rulenode.send-attributes-deleted-notification-hint
\n
\n \n {{ \'tb.rulenode.notify-device\' | translate }}\n \n
tb.rulenode.notify-device-on-delete-hint
\n
\n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Q.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:be.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:be.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:be.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:be.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:kn,decorators:[{type:n,args:[{selector:"tb-action-node-delete-attributes-config",template:'
\n \n {{ \'attribute.attributes-scope\' | translate }}\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n \n {{ \'tb.rulenode.attributes-keys\' | translate }}\n \n \n {{key}}\n close\n \n \n \n {{ \'tb.rulenode.attributes-keys-required\' | translate }}\n tb.rulenode.general-pattern-hint\n \n \n {{ \'tb.rulenode.send-attributes-deleted-notification\' | translate }}\n \n
tb.rulenode.send-attributes-deleted-notification-hint
\n
\n \n {{ \'tb.rulenode.notify-device\' | translate }}\n \n
tb.rulenode.notify-device-on-delete-hint
\n
\n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]},propDecorators:{attributeChipList:[{type:o,args:["attributeChipList"]}]}});class Ln extends L{get function(){return this.functionValue}set function(e){e&&this.functionValue!==e&&(this.functionValue=e,this.setupArgumentsFormGroup(!0))}constructor(e,t){super(e),this.store=e,this.fb=t,this.maxArgs=16,this.minArgs=1,this.displayArgumentName=!1,this.mathFunctionMap=Wt,this.ArgumentType=Zt,this.attributeScopeMap=pn,this.argumentTypeMap=on,this.arguments=Object.values(Zt),this.attributeScope=Object.values(sn),this.propagateChange=null,this.valueChangeSubscription=[]}ngOnInit(){this.argumentsFormGroup=this.fb.group({arguments:this.fb.array([])}),this.valueChangeSubscription.push(this.argumentsFormGroup.valueChanges.subscribe((()=>{this.updateModel()}))),this.setupArgumentsFormGroup()}onDrop(e){const t=this.argumentsFormArray,n=t.at(e.previousIndex);t.removeAt(e.previousIndex),t.insert(e.currentIndex,n),this.updateArgumentNames()}get argumentsFormArray(){return this.argumentsFormGroup.get("arguments")}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.argumentsFormGroup.disable({emitEvent:!1}):(this.argumentsFormGroup.enable({emitEvent:!1}),this.argumentsFormArray.controls.forEach((e=>this.updateArgumentControlValidators(e))))}ngOnDestroy(){this.valueChangeSubscription.length&&this.valueChangeSubscription.forEach((e=>e.unsubscribe()))}writeValue(e){const t=[];e&&e.forEach(((e,n)=>{t.push(this.createArgumentControl(e,n))})),this.argumentsFormGroup.setControl("arguments",this.fb.array(t),{emitEvent:!1}),this.setupArgumentsFormGroup()}removeArgument(e){this.argumentsFormArray.removeAt(e),this.updateArgumentNames()}addArgument(e=!0){const t=this.argumentsFormArray,n=this.createArgumentControl(null,t.length);t.push(n,{emitEvent:e})}validate(e){return this.argumentsFormGroup.valid?null:{argumentsRequired:!0}}setupArgumentsFormGroup(e=!1){if(this.function&&(this.maxArgs=this.mathFunctionMap.get(this.function).maxArgs,this.minArgs=this.mathFunctionMap.get(this.function).minArgs,this.displayArgumentName=this.function===Yt.CUSTOM),this.argumentsFormGroup){for(this.argumentsFormGroup.get("arguments").setValidators([O.minLength(this.minArgs),O.maxLength(this.maxArgs)]);this.argumentsFormArray.length>this.maxArgs;)this.removeArgument(this.maxArgs-1);for(;this.argumentsFormArray.length{this.updateArgumentControlValidators(n),n.get("attributeScope").updateValueAndValidity({emitEvent:!1}),n.get("defaultValue").updateValueAndValidity({emitEvent:!1})}))),n}updateArgumentControlValidators(e){const t=e.get("type").value;t===Zt.ATTRIBUTE?e.get("attributeScope").enable({emitEvent:!1}):e.get("attributeScope").disable({emitEvent:!1}),t&&t!==Zt.CONSTANT?e.get("defaultValue").enable({emitEvent:!1}):e.get("defaultValue").disable({emitEvent:!1})}updateArgumentNames(){this.argumentsFormArray.controls.forEach(((e,t)=>{e.get("name").setValue(ln[t])}))}updateModel(){const e=this.argumentsFormArray.value;e.length&&this.argumentsFormGroup.valid?this.propagateChange(e):this.propagateChange(null)}}e("ArgumentsMapConfigComponent",Ln),Ln.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Ln,deps:[{token:P.Store},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Ln.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Ln,selector:"tb-arguments-map-config",inputs:{disabled:"disabled",function:"function"},providers:[{provide:B,useExisting:a((()=>Ln)),multi:!0},{provide:K,useExisting:a((()=>Ln)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n\n
\n \n \n
\n \n
\n {{argumentControl.get(\'name\').value}}.\n
\n \n tb.rulenode.argument-source-field-input\n \n \n {{ argumentTypeMap.get(argumentControl.get(\'type\').value)?.name | translate }}\n \n \n {{ argumentTypeMap.get(argument).name | translate }}\n \n {{ argumentTypeMap.get(argument).description }}\n \n \n \n \n tb.rulenode.argument-source-field-input-required\n \n \n
\n \n tb.rulenode.argument-key-field-input\n \n \n help\n \n \n tb.rulenode.argument-key-field-input-required\n \n \n \n tb.rulenode.constant-value-field-input\n \n \n tb.rulenode.constant-value-field-input-required\n \n \n \n tb.rulenode.default-value-field-input\n \n \n
\n \n tb.rulenode.attribute-scope-field-input\n \n \n {{ attributeScopeMap.get(scope) | translate }}\n \n \n \n tb.rulenode.attribute-scope-field-input-required\n \n \n
\n \n
\n
\n
\n
\n
\n
\n tb.rulenode.no-arguments-prompt\n
\n \n
\n',styles:[":host .mat-mdc-list-item.tb-argument{border:solid rgba(0,0,0,.25) 1px;border-radius:4px;padding:10px 0;margin-bottom:16px}:host .arguments-list{padding:0}\n"],dependencies:[{kind:"directive",type:H.NgClass,selector:"[ngClass]",inputs:["class","ngClass"]},{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:de.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:de.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Y.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"directive",type:X.MatSelectTrigger,selector:"mat-select-trigger"},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:Ne.MatList,selector:"mat-list",exportAs:["matList"]},{kind:"component",type:Ne.MatListItem,selector:"mat-list-item, a[mat-list-item], button[mat-list-item]",inputs:["activated"],exportAs:["matListItem"]},{kind:"directive",type:Se.CdkDropList,selector:"[cdkDropList], cdk-drop-list",inputs:["cdkDropListConnectedTo","cdkDropListData","cdkDropListOrientation","id","cdkDropListLockAxis","cdkDropListDisabled","cdkDropListSortingDisabled","cdkDropListEnterPredicate","cdkDropListSortPredicate","cdkDropListAutoScrollDisabled","cdkDropListAutoScrollStep"],outputs:["cdkDropListDropped","cdkDropListEntered","cdkDropListExited","cdkDropListSorted"],exportAs:["cdkDropList"]},{kind:"directive",type:Se.CdkDrag,selector:"[cdkDrag]",inputs:["cdkDragData","cdkDragLockAxis","cdkDragRootElement","cdkDragBoundary","cdkDragStartDelay","cdkDragFreeDragPosition","cdkDragDisabled","cdkDragConstrainPosition","cdkDragPreviewClass","cdkDragPreviewContainer"],outputs:["cdkDragStarted","cdkDragReleased","cdkDragEnded","cdkDragEntered","cdkDragExited","cdkDragDropped","cdkDragMoved"],exportAs:["cdkDrag"]},{kind:"directive",type:Se.CdkDragHandle,selector:"[cdkDragHandle]",inputs:["cdkDragHandleDisabled"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:W.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:Ie.DefaultClassDirective,selector:" [ngClass], [ngClass.xs], [ngClass.sm], [ngClass.md], [ngClass.lg], [ngClass.xl], [ngClass.lt-sm], [ngClass.lt-md], [ngClass.lt-lg], [ngClass.lt-xl], [ngClass.gt-xs], [ngClass.gt-sm], [ngClass.gt-md], [ngClass.gt-lg]",inputs:["ngClass","ngClass.xs","ngClass.sm","ngClass.md","ngClass.lg","ngClass.xl","ngClass.lt-sm","ngClass.lt-md","ngClass.lt-lg","ngClass.lt-xl","ngClass.gt-xs","ngClass.gt-sm","ngClass.gt-md","ngClass.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.FormControlDirective,selector:"[formControl]",inputs:["formControl","disabled","ngModel"],outputs:["ngModelChange"],exportAs:["ngForm"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormArrayName,selector:"[formArrayName]",inputs:["formArrayName"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Ln,decorators:[{type:n,args:[{selector:"tb-arguments-map-config",providers:[{provide:B,useExisting:a((()=>Ln)),multi:!0},{provide:K,useExisting:a((()=>Ln)),multi:!0}],template:'
\n\n
\n \n \n
\n \n
\n {{argumentControl.get(\'name\').value}}.\n
\n \n tb.rulenode.argument-source-field-input\n \n \n {{ argumentTypeMap.get(argumentControl.get(\'type\').value)?.name | translate }}\n \n \n {{ argumentTypeMap.get(argument).name | translate }}\n \n {{ argumentTypeMap.get(argument).description }}\n \n \n \n \n tb.rulenode.argument-source-field-input-required\n \n \n
\n \n tb.rulenode.argument-key-field-input\n \n \n help\n \n \n tb.rulenode.argument-key-field-input-required\n \n \n \n tb.rulenode.constant-value-field-input\n \n \n tb.rulenode.constant-value-field-input-required\n \n \n \n tb.rulenode.default-value-field-input\n \n \n
\n \n tb.rulenode.attribute-scope-field-input\n \n \n {{ attributeScopeMap.get(scope) | translate }}\n \n \n \n tb.rulenode.attribute-scope-field-input-required\n \n \n
\n \n
\n
\n
\n
\n
\n
\n tb.rulenode.no-arguments-prompt\n
\n \n
\n',styles:[":host .mat-mdc-list-item.tb-argument{border:solid rgba(0,0,0,.25) 1px;border-radius:4px;padding:10px 0;margin-bottom:16px}:host .arguments-list{padding:0}\n"]}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder}]},propDecorators:{disabled:[{type:i}],function:[{type:i}]}});class Tn extends L{get required(){return this.requiredValue}set required(e){this.requiredValue=Fe(e)}constructor(e,t,n,r){super(e),this.store=e,this.translate=t,this.injector=n,this.fb=r,this.searchText="",this.dirty=!1,this.mathOperation=[...Wt.values()],this.propagateChange=null}ngOnInit(){this.mathFunctionForm=this.fb.group({operation:[""]}),this.filteredOptions=this.mathFunctionForm.get("operation").valueChanges.pipe(qe((e=>{let t;t="string"==typeof e&&Yt[e]?Yt[e]:null,this.updateView(t)})),Ae((e=>(this.searchText=e||"",e?this._filter(e):this.mathOperation.slice()))))}_filter(e){const t=e.toLowerCase();return this.mathOperation.filter((e=>e.name.toLowerCase().includes(t)||e.value.toLowerCase().includes(t)))}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.mathFunctionForm.disable({emitEvent:!1}):this.mathFunctionForm.enable({emitEvent:!1})}mathFunctionDisplayFn(e){if(e){const t=Wt.get(e);return t.value+" | "+t.name}return""}writeValue(e){this.modelValue=e,this.mathFunctionForm.get("operation").setValue(e,{emitEvent:!1}),this.dirty=!0}updateView(e){this.modelValue!==e&&(this.modelValue=e,this.propagateChange(this.modelValue))}onFocus(){this.dirty&&(this.mathFunctionForm.get("operation").updateValueAndValidity({onlySelf:!0}),this.dirty=!1)}clear(){this.mathFunctionForm.get("operation").patchValue(""),setTimeout((()=>{this.operationInput.nativeElement.blur(),this.operationInput.nativeElement.focus()}),0)}}e("MathFunctionAutocompleteComponent",Tn),Tn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Tn,deps:[{token:P.Store},{token:Z.TranslateService},{token:t.Injector},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Tn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Tn,selector:"tb-math-function-autocomplete",inputs:{required:"required",disabled:"disabled"},providers:[{provide:B,useExisting:a((()=>Tn)),multi:!0}],viewQueries:[{propertyName:"operationInput",first:!0,predicate:["operationInput"],descendants:!0,static:!0}],usesInheritance:!0,ngImport:t,template:'\n tb.rulenode.functions-field-input\n \n \n \n \n \n \n {{ option.description }}\n \n \n \n tb.rulenode.no-option-found\n \n \n\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:de.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:Ve.MatAutocomplete,selector:"mat-autocomplete",inputs:["disableRipple","hideSingleSelectionIndicator"],exportAs:["matAutocomplete"]},{kind:"directive",type:Ve.MatAutocompleteTrigger,selector:"input[matAutocomplete], textarea[matAutocomplete]",exportAs:["matAutocompleteTrigger"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:H.AsyncPipe,name:"async"},{kind:"pipe",type:Pe.HighlightPipe,name:"highlight"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Tn,decorators:[{type:n,args:[{selector:"tb-math-function-autocomplete",providers:[{provide:B,useExisting:a((()=>Tn)),multi:!0}],template:'\n tb.rulenode.functions-field-input\n \n \n \n \n \n \n {{ option.description }}\n \n \n \n tb.rulenode.no-option-found\n \n \n\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:Z.TranslateService},{type:t.Injector},{type:R.UntypedFormBuilder}]},propDecorators:{required:[{type:i}],disabled:[{type:i}],operationInput:[{type:o,args:["operationInput",{static:!0}]}]}});class In extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.MathFunction=Yt,this.ArgumentTypeResult=Xt,this.argumentTypeResultMap=an,this.attributeScopeMap=pn,this.argumentsResult=Object.values(Xt),this.attributeScopeResult=Object.values(mn)}configForm(){return this.mathFunctionConfigForm}onConfigurationSet(e){this.mathFunctionConfigForm=this.fb.group({operation:[e?e.operation:null,[O.required]],arguments:[e?e.arguments:null,[O.required]],customFunction:[e?e.customFunction:"",[O.required]],result:this.fb.group({type:[e?e.result.type:null,[O.required]],attributeScope:[e?e.result.attributeScope:null,[O.required]],key:[e?e.result.key:"",[O.required]],resultValuePrecision:[e?e.result.resultValuePrecision:0],addToBody:[!!e&&e.result.addToBody],addToMetadata:[!!e&&e.result.addToMetadata]})})}updateValidators(e){const t=this.mathFunctionConfigForm.get("operation").value,n=this.mathFunctionConfigForm.get("result.type").value;t===Yt.CUSTOM?(this.mathFunctionConfigForm.get("customFunction").enable({emitEvent:!1}),null===this.mathFunctionConfigForm.get("customFunction").value&&this.mathFunctionConfigForm.get("customFunction").patchValue("(x - 32) / 1.8",{emitEvent:!1})):this.mathFunctionConfigForm.get("customFunction").disable({emitEvent:!1}),n===Xt.ATTRIBUTE?this.mathFunctionConfigForm.get("result.attributeScope").enable({emitEvent:!1}):this.mathFunctionConfigForm.get("result.attributeScope").disable({emitEvent:!1}),this.mathFunctionConfigForm.get("customFunction").updateValueAndValidity({emitEvent:e}),this.mathFunctionConfigForm.get("result.attributeScope").updateValueAndValidity({emitEvent:e})}validatorTriggers(){return["operation","result.type"]}}e("MathFunctionConfigComponent",In),In.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:In,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),In.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:In,selector:"tb-action-node-math-function-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n
\n tb.rulenode.argument-tile\n \n \n
\n
\n {{\'tb.rulenode.custom-expression-field-input\' | translate }} *\n \n \n \n tb.rulenode.custom-expression-field-input-required\n \n tb.rulenode.custom-expression-field-input-hint\n \n
\n
\n tb.rulenode.result-title\n
\n \n tb.rulenode.type-field-input\n \n \n {{ argumentTypeResultMap.get(mathFunctionConfigForm.get(\'result.type\').value)?.name | translate }}\n \n \n {{ argumentTypeResultMap.get(argument).name | translate }}\n \n {{ argumentTypeResultMap.get(argument).description }}\n \n \n \n \n tb.rulenode.type-field-input-required\n \n \n
\n \n tb.rulenode.attribute-scope-field-input\n \n \n {{ attributeScopeMap.get(scope) | translate }}\n \n \n \n \n tb.rulenode.key-field-input\n \n help\n \n tb.rulenode.key-field-input-required\n \n \n
\n
\n \n tb.rulenode.number-floating-point-field-input\n \n \n \n
\n
\n \n {{\'tb.rulenode.add-to-message-field-input\' | translate }}\n \n \n {{\'tb.rulenode.add-to-metadata-field-input\' | translate}}\n \n
\n
\n
\n
\n',styles:[":host ::ng-deep .fields-group{padding:0 16px 8px;margin:10px 0;border:1px groove rgba(0,0,0,.25);border-radius:4px}:host ::ng-deep .fields-group .mat-mdc-form-field .mat-mdc-form-field-infix{width:100%}:host ::ng-deep .fields-group legend{color:#000000b3;width:-moz-fit-content;width:fit-content}:host ::ng-deep .fields-group legend+*{display:block}:host ::ng-deep .fields-group legend+*.no-margin-top{margin-top:0}\n"],dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Q.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Y.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"directive",type:X.MatSelectTrigger,selector:"mat-select-trigger"},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:W.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:R.FormGroupName,selector:"[formGroupName]",inputs:["formGroupName"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Ln,selector:"tb-arguments-map-config",inputs:["disabled","function"]},{kind:"component",type:Tn,selector:"tb-math-function-autocomplete",inputs:["required","disabled"]},{kind:"pipe",type:he.SafePipe,name:"safe"},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:In,decorators:[{type:n,args:[{selector:"tb-action-node-math-function-config",template:'
\n \n \n
\n tb.rulenode.argument-tile\n \n \n
\n
\n {{\'tb.rulenode.custom-expression-field-input\' | translate }} *\n \n \n \n tb.rulenode.custom-expression-field-input-required\n \n tb.rulenode.custom-expression-field-input-hint\n \n
\n
\n tb.rulenode.result-title\n
\n \n tb.rulenode.type-field-input\n \n \n {{ argumentTypeResultMap.get(mathFunctionConfigForm.get(\'result.type\').value)?.name | translate }}\n \n \n {{ argumentTypeResultMap.get(argument).name | translate }}\n \n {{ argumentTypeResultMap.get(argument).description }}\n \n \n \n \n tb.rulenode.type-field-input-required\n \n \n
\n \n tb.rulenode.attribute-scope-field-input\n \n \n {{ attributeScopeMap.get(scope) | translate }}\n \n \n \n \n tb.rulenode.key-field-input\n \n help\n \n tb.rulenode.key-field-input-required\n \n \n
\n
\n \n tb.rulenode.number-floating-point-field-input\n \n \n \n
\n
\n \n {{\'tb.rulenode.add-to-message-field-input\' | translate }}\n \n \n {{\'tb.rulenode.add-to-metadata-field-input\' | translate}}\n \n
\n
\n
\n
\n',styles:[":host ::ng-deep .fields-group{padding:0 16px 8px;margin:10px 0;border:1px groove rgba(0,0,0,.25);border-radius:4px}:host ::ng-deep .fields-group .mat-mdc-form-field .mat-mdc-form-field-infix{width:100%}:host ::ng-deep .fields-group legend{color:#000000b3;width:-moz-fit-content;width:fit-content}:host ::ng-deep .fields-group legend+*{display:block}:host ::ng-deep .fields-group legend+*.no-margin-top{margin-top:0}\n"]}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class Nn{constructor(){this.textAlign="left"}}e("ExampleHintComponent",Nn),Nn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Nn,deps:[],target:t.ɵɵFactoryTarget.Component}),Nn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Nn,selector:"tb-example-hint",inputs:{hintText:"hintText",popupHelpLink:"popupHelpLink",textAlign:"textAlign"},ngImport:t,template:'
\n
\n
\n
\n
\n',styles:[":host .space-between{display:flex;justify-content:space-between;gap:20px}:host .space-between .see-example{display:flex;flex-shrink:0}:host .hint-text{width:100%}\n"],dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:He.HelpPopupComponent,selector:"[tb-help-popup], [tb-help-popup-content]",inputs:["tb-help-popup","tb-help-popup-content","trigger-text","trigger-style","tb-help-popup-placement","tb-help-popup-style","hintMode"]},{kind:"pipe",type:he.SafePipe,name:"safe"},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Nn,decorators:[{type:n,args:[{selector:"tb-example-hint",template:'
\n
\n
\n
\n
\n',styles:[":host .space-between{display:flex;justify-content:space-between;gap:20px}:host .space-between .see-example{display:flex;flex-shrink:0}:host .hint-text{width:100%}\n"]}]}],propDecorators:{hintText:[{type:i}],popupHelpLink:[{type:i}],textAlign:[{type:i}]}});class Sn{constructor(e,t){this.injector=e,this.fb=t,this.propagateChange=()=>{},this.destroy$=new _e,this.disabled=!1,this.uniqueKeyValuePairValidator=!1,this.required=!1,this.duplicateValuesValidator=e=>e.controls.key.value===e.controls.value.value&&e.controls.key.value&&e.controls.value.value?{uniqueKeyValuePair:!0}:null,this.oneMapRequiredValidator=e=>e.get("keyVals").value.length,this.propagateNestedErrors=e=>{if(this.kvListFormGroup&&this.kvListFormGroup.get("keyVals")&&"VALID"===this.kvListFormGroup.get("keyVals")?.status)return null;const t={};if(this.kvListFormGroup&&this.kvListFormGroup.setErrors(null),e instanceof z||e instanceof U){if(e.errors)for(const n of Object.keys(e.errors))t[n]=!0;for(const n of Object.keys(e.controls)){const r=this.propagateNestedErrors(e.controls[n]);if(r&&Object.keys(r).length)for(const e of Object.keys(r))t[e]=!0}return t}if(e.errors)for(const n of Object.keys(e.errors))t[n]=!0;return ae(t,{})?null:t}}ngOnInit(){this.ngControl=this.injector.get(_),null!=this.ngControl&&(this.ngControl.valueAccessor=this),this.kvListFormGroup=this.fb.group({keyVals:this.fb.array([])},{validators:[this.propagateNestedErrors,this.oneMapRequiredValidator]}),this.kvListFormGroup.valueChanges.pipe(Be(this.destroy$)).subscribe((()=>{this.updateModel()}))}ngOnDestroy(){this.destroy$.next(),this.destroy$.complete()}keyValsFormArray(){return this.kvListFormGroup.get("keyVals")}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.kvListFormGroup.disable({emitEvent:!1}):this.kvListFormGroup.enable({emitEvent:!1})}writeValue(e){const t=Object.keys(e).map((t=>({key:t,value:e[t]})));if(this.keyValsFormArray().length===t.length)this.keyValsFormArray().patchValue(t,{emitEvent:!1});else{const e=[];t.forEach((t=>{e.push(this.fb.group({key:[t.key,[O.required,O.pattern(/(?:.|\s)*\S(&:.|\s)*/)]],value:[t.value,[O.required,O.pattern(/(?:.|\s)*\S(&:.|\s)*/)]]},{validators:this.uniqueKeyValuePairValidator?[this.duplicateValuesValidator]:[]}))})),this.kvListFormGroup.setControl("keyVals",this.fb.array(e,this.propagateNestedErrors),{emitEvent:!1})}}removeKeyVal(e){this.keyValsFormArray().removeAt(e)}addKeyVal(){this.keyValsFormArray().push(this.fb.group({key:["",[O.required,O.pattern(/(?:.|\s)*\S(&:.|\s)*/)]],value:["",[O.required,O.pattern(/(?:.|\s)*\S(&:.|\s)*/)]]},{validators:this.uniqueKeyValuePairValidator?[this.duplicateValuesValidator]:[]}))}validate(){const e=this.kvListFormGroup.get("keyVals").value;if(!e.length&&this.required)return{kvMapRequired:!0};if(!this.kvListFormGroup.valid)return{kvFieldsRequired:!0};if(this.uniqueKeyValuePairValidator)for(const t of e)if(t.key===t.value)return{uniqueKeyValuePair:!0};return null}updateModel(){const e=this.kvListFormGroup.get("keyVals").value;if(this.required&&!e.length||!this.kvListFormGroup.valid)this.propagateChange(null);else{const t={};e.forEach((e=>{t[e.key]=e.value})),this.propagateChange(t)}}}e("KvMapConfigComponent",Sn),Sn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Sn,deps:[{token:t.Injector},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Sn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Sn,selector:"tb-kv-map-config",inputs:{disabled:"disabled",uniqueKeyValuePairValidator:"uniqueKeyValuePairValidator",labelText:"labelText",requiredText:"requiredText",keyText:"keyText",keyRequiredText:"keyRequiredText",valText:"valText",valRequiredText:"valRequiredText",hintText:"hintText",popupHelpLink:"popupHelpLink",required:"required"},providers:[{provide:B,useExisting:a((()=>Sn)),multi:!0},{provide:K,useExisting:a((()=>Sn)),multi:!0}],ngImport:t,template:'
\n
\n
{{ labelText }}
\n
\n {{ requiredText }}\n
\n
\n tb.rulenode.map-fields-required\n
\n
\n {{ \'tb.key-val.unique-key-value-pair-error\' | translate:\n {\n valText: valText,\n keyText: keyText\n } }}\n
\n
\n
\n
\n
\n
{{ keyText }}
\n
{{ valText }}
\n
\n
\n
\n
\n \n \n \n \n \n \n
\n \n
\n
\n
\n
\n
\n
\n \n
\n \n
\n',styles:[":host .field-space{flex:1 1 50%}:host .actions-header{width:40px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:de.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:de.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.FormControlDirective,selector:"[formControl]",inputs:["formControl","disabled","ngModel"],outputs:["ngModelChange"],exportAs:["ngForm"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Nn,selector:"tb-example-hint",inputs:["hintText","popupHelpLink","textAlign"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),Oe([T()],Sn.prototype,"disabled",void 0),Oe([T()],Sn.prototype,"uniqueKeyValuePairValidator",void 0),Oe([T()],Sn.prototype,"required",void 0),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Sn,decorators:[{type:n,args:[{selector:"tb-kv-map-config",providers:[{provide:B,useExisting:a((()=>Sn)),multi:!0},{provide:K,useExisting:a((()=>Sn)),multi:!0}],template:'
\n
\n
{{ labelText }}
\n
\n {{ requiredText }}\n
\n
\n tb.rulenode.map-fields-required\n
\n
\n {{ \'tb.key-val.unique-key-value-pair-error\' | translate:\n {\n valText: valText,\n keyText: keyText\n } }}\n
\n
\n
\n
\n
\n
{{ keyText }}
\n
{{ valText }}
\n
\n
\n
\n
\n \n \n \n \n \n \n
\n \n
\n
\n
\n
\n
\n
\n \n
\n \n
\n',styles:[":host .field-space{flex:1 1 50%}:host .actions-header{width:40px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:t.Injector},{type:R.FormBuilder}]},propDecorators:{disabled:[{type:i}],uniqueKeyValuePairValidator:[{type:i}],labelText:[{type:i}],requiredText:[{type:i}],keyText:[{type:i}],keyRequiredText:[{type:i}],valText:[{type:i}],valRequiredText:[{type:i}],hintText:[{type:i}],popupHelpLink:[{type:i}],required:[{type:i}]}});class qn extends L{get required(){return this.requiredValue}set required(e){this.requiredValue=Fe(e)}constructor(e,t){super(e),this.store=e,this.fb=t,this.directionTypes=Object.values(v),this.directionTypeTranslations=C,this.entityType=F,this.propagateChange=null}ngOnInit(){this.deviceRelationsQueryFormGroup=this.fb.group({fetchLastLevelOnly:[!1,[]],direction:[null,[O.required]],maxLevel:[null,[O.min(1)]],relationType:[null],deviceTypes:[null,[O.required]]}),this.deviceRelationsQueryFormGroup.valueChanges.subscribe((e=>{this.deviceRelationsQueryFormGroup.valid?this.propagateChange(e):this.propagateChange(null)}))}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.deviceRelationsQueryFormGroup.disable({emitEvent:!1}):this.deviceRelationsQueryFormGroup.enable({emitEvent:!1})}writeValue(e){this.deviceRelationsQueryFormGroup.reset(e,{emitEvent:!1})}}e("DeviceRelationsQueryConfigComponent",qn),qn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:qn,deps:[{token:P.Store},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),qn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:qn,selector:"tb-device-relations-query-config",inputs:{disabled:"disabled",required:"required"},providers:[{provide:B,useExisting:a((()=>qn)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }} tb.rulenode.relations-query-config-direction-suffix\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n {{ \'tb.rulenode.max-relation-level-error\' | translate }}\n \n \n
\n
\n \n {{ \'alias.last-level-relation\' | translate }}\n \n
\n \n \n \n help\n \n
\n',styles:[":host .last-level-slide-toggle{margin:8px 0 24px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:je.EntitySubTypeListComponent,selector:"tb-entity-subtype-list",inputs:["required","floatLabel","label","disabled","entityType","emptyInputPlaceholder","filledInputPlaceholder","appearance","subscriptSizing","additionalClasses"]},{kind:"component",type:$e.RelationTypeAutocompleteComponent,selector:"tb-relation-type-autocomplete",inputs:["showLabel","additionalClasses","appearance","required","disabled","subscriptSizing"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Y.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:te.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:ne.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:qn,decorators:[{type:n,args:[{selector:"tb-device-relations-query-config",providers:[{provide:B,useExisting:a((()=>qn)),multi:!0}],template:'
\n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }} tb.rulenode.relations-query-config-direction-suffix\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n {{ \'tb.rulenode.max-relation-level-error\' | translate }}\n \n \n
\n
\n \n {{ \'alias.last-level-relation\' | translate }}\n \n
\n \n \n \n help\n \n
\n',styles:[":host .last-level-slide-toggle{margin:8px 0 24px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder}]},propDecorators:{disabled:[{type:i}],required:[{type:i}]}});class An extends L{get required(){return this.requiredValue}set required(e){this.requiredValue=Fe(e)}constructor(e,t){super(e),this.store=e,this.fb=t,this.directionTypes=Object.values(v),this.directionTypeTranslations=C,this.propagateChange=null}ngOnInit(){this.relationsQueryFormGroup=this.fb.group({fetchLastLevelOnly:[!1,[]],direction:[null,[O.required]],maxLevel:[null,[O.min(1)]],filters:[null]}),this.relationsQueryFormGroup.valueChanges.subscribe((e=>{this.relationsQueryFormGroup.valid?this.propagateChange(e):this.propagateChange(null)}))}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.relationsQueryFormGroup.disable({emitEvent:!1}):this.relationsQueryFormGroup.enable({emitEvent:!1})}writeValue(e){this.relationsQueryFormGroup.reset(e||{},{emitEvent:!1})}}e("RelationsQueryConfigComponent",An),An.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:An,deps:[{token:P.Store},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),An.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:An,selector:"tb-relations-query-config",inputs:{disabled:"disabled",required:"required"},providers:[{provide:B,useExisting:a((()=>An)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n
tb.rulenode.relations-query
\n
\n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }} tb.rulenode.relations-query-config-direction-suffix\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n {{ \'tb.rulenode.max-relation-level-error\' | translate }}\n \n \n
\n
\n \n {{ \'alias.last-level-relation\' | translate }}\n \n
\n
\n
\n
relation.relation-filters
\n \n \n
\n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:te.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:ne.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"component",type:Qe.RelationFiltersComponent,selector:"tb-relation-filters",inputs:["disabled","allowedEntityTypes"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:An,decorators:[{type:n,args:[{selector:"tb-relations-query-config",providers:[{provide:B,useExisting:a((()=>An)),multi:!0}],template:'
\n
tb.rulenode.relations-query
\n
\n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }} tb.rulenode.relations-query-config-direction-suffix\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n {{ \'tb.rulenode.max-relation-level-error\' | translate }}\n \n \n
\n
\n \n {{ \'alias.last-level-relation\' | translate }}\n \n
\n
\n
\n
relation.relation-filters
\n \n \n
\n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder}]},propDecorators:{disabled:[{type:i}],required:[{type:i}]}});class Mn extends L{get required(){return this.requiredValue}set required(e){this.requiredValue=Fe(e)}constructor(e,t,n,r){super(e),this.store=e,this.translate=t,this.truncate=n,this.fb=r,this.placeholder="tb.rulenode.add-message-type",this.separatorKeysCodes=[ge,ye,xe],this.messageTypes=[],this.messageTypesList=[],this.searchText="",this.propagateChange=e=>{},this.messageTypeConfigForm=this.fb.group({messageType:[null]});for(const e of Object.keys(I))this.messageTypesList.push({name:N.get(I[e]),value:e})}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}ngOnInit(){this.filteredMessageTypes=this.messageTypeConfigForm.get("messageType").valueChanges.pipe(Me(""),Ae((e=>e||"")),Ee((e=>this.fetchMessageTypes(e))),Ge())}setDisabledState(e){this.disabled=e,this.disabled?this.messageTypeConfigForm.disable({emitEvent:!1}):this.messageTypeConfigForm.enable({emitEvent:!1})}writeValue(e){this.searchText="",this.messageTypes.length=0,e&&e.forEach((e=>{const t=this.messageTypesList.find((t=>t.value===e));t?this.messageTypes.push({name:t.name,value:t.value}):this.messageTypes.push({name:e,value:e})}))}displayMessageTypeFn(e){return e?e.name:void 0}textIsNotEmpty(e){return e&&e.length>0}createMessageType(e,t){e.preventDefault(),this.transformMessageType(t)}add(e){this.transformMessageType(e.value)}fetchMessageTypes(e){if(this.searchText=e,this.searchText&&this.searchText.length){const e=this.searchText.toUpperCase();return Ke(this.messageTypesList.filter((t=>t.name.toUpperCase().includes(e))))}return Ke(this.messageTypesList)}transformMessageType(e){if((e||"").trim()){let t;const n=e.trim(),r=this.messageTypesList.find((e=>e.name===n));t=r?{name:r.name,value:r.value}:{name:n,value:n},t&&this.addMessageType(t)}this.clear("")}remove(e){const t=this.messageTypes.indexOf(e);t>=0&&(this.messageTypes.splice(t,1),this.updateModel())}selected(e){this.addMessageType(e.option.value),this.clear("")}addMessageType(e){-1===this.messageTypes.findIndex((t=>t.value===e.value))&&(this.messageTypes.push(e),this.updateModel())}onFocus(){this.messageTypeConfigForm.get("messageType").updateValueAndValidity({onlySelf:!0,emitEvent:!0})}clear(e=""){this.messageTypeInput.nativeElement.value=e,this.messageTypeConfigForm.get("messageType").patchValue(null,{emitEvent:!0}),setTimeout((()=>{this.messageTypeInput.nativeElement.blur(),this.messageTypeInput.nativeElement.focus()}),0)}updateModel(){const e=this.messageTypes.map((e=>e.value));this.required?(this.chipList.errorState=!e.length,this.propagateChange(e.length>0?e:null)):(this.chipList.errorState=!1,this.propagateChange(e))}}e("MessageTypesConfigComponent",Mn),Mn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Mn,deps:[{token:P.Store},{token:Z.TranslateService},{token:S.TruncatePipe},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Mn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Mn,selector:"tb-message-types-config",inputs:{required:"required",label:"label",placeholder:"placeholder",disabled:"disabled"},providers:[{provide:B,useExisting:a((()=>Mn)),multi:!0}],viewQueries:[{propertyName:"chipList",first:!0,predicate:["chipList"],descendants:!0},{propertyName:"matAutocomplete",first:!0,predicate:["messageTypeAutocomplete"],descendants:!0},{propertyName:"messageTypeInput",first:!0,predicate:["messageTypeInput"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'\n {{ label }}\n \n \n {{messageType.name}}\n close\n \n \n \n \n \n \n \n \n
\n
\n tb.rulenode.no-message-types-found\n
\n \n \n {{ \'tb.rulenode.no-message-type-matching\' | translate :\n {messageType: truncate.transform(searchText, true, 6, '...')}\n }}\n \n \n \n tb.rulenode.create-new-message-type\n \n
\n
\n
\n help\n \n {{ \'tb.rulenode.select-message-types-required\' | translate }}\n \n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Y.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:Ve.MatAutocomplete,selector:"mat-autocomplete",inputs:["disableRipple","hideSingleSelectionIndicator"],exportAs:["matAutocomplete"]},{kind:"directive",type:Ve.MatAutocompleteTrigger,selector:"input[matAutocomplete], textarea[matAutocomplete]",exportAs:["matAutocompleteTrigger"]},{kind:"directive",type:Ve.MatAutocompleteOrigin,selector:"[matAutocompleteOrigin]",exportAs:["matAutocompleteOrigin"]},{kind:"component",type:be.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:be.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:be.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:be.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:H.AsyncPipe,name:"async"},{kind:"pipe",type:Pe.HighlightPipe,name:"highlight"},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Mn,decorators:[{type:n,args:[{selector:"tb-message-types-config",providers:[{provide:B,useExisting:a((()=>Mn)),multi:!0}],template:'\n {{ label }}\n \n \n {{messageType.name}}\n close\n \n \n \n \n \n \n \n \n
\n
\n tb.rulenode.no-message-types-found\n
\n \n \n {{ \'tb.rulenode.no-message-type-matching\' | translate :\n {messageType: truncate.transform(searchText, true, 6, '...')}\n }}\n \n \n \n tb.rulenode.create-new-message-type\n \n
\n
\n
\n help\n \n {{ \'tb.rulenode.select-message-types-required\' | translate }}\n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:Z.TranslateService},{type:S.TruncatePipe},{type:R.FormBuilder}]},propDecorators:{required:[{type:i}],label:[{type:i}],placeholder:[{type:i}],disabled:[{type:i}],chipList:[{type:o,args:["chipList",{static:!1}]}],matAutocomplete:[{type:o,args:["messageTypeAutocomplete",{static:!1}]}],messageTypeInput:[{type:o,args:["messageTypeInput",{static:!1}]}]}});class En extends L{get required(){return this.requiredValue}set required(e){this.requiredValue=Fe(e)}constructor(e,t){super(e),this.store=e,this.fb=t,this.subscriptions=[],this.disableCertPemCredentials=!1,this.passwordFieldRequired=!0,this.allCredentialsTypes=zt,this.credentialsTypeTranslationsMap=Ut,this.propagateChange=e=>{}}ngOnInit(){this.credentialsConfigFormGroup=this.fb.group({type:[null,[O.required]],username:[null,[]],password:[null,[]],caCert:[null,[]],caCertFileName:[null,[]],privateKey:[null,[]],privateKeyFileName:[null,[]],cert:[null,[]],certFileName:[null,[]]}),this.subscriptions.push(this.credentialsConfigFormGroup.valueChanges.subscribe((()=>{this.updateView()}))),this.subscriptions.push(this.credentialsConfigFormGroup.get("type").valueChanges.subscribe((()=>{this.credentialsTypeChanged()})))}ngOnChanges(e){for(const t of Object.keys(e)){const n=e[t];if(!n.firstChange&&n.currentValue!==n.previousValue&&n.currentValue&&"disableCertPemCredentials"===t){"cert.PEM"===this.credentialsConfigFormGroup.get("type").value&&setTimeout((()=>{this.credentialsConfigFormGroup.get("type").patchValue("anonymous",{emitEvent:!0})}))}}}ngOnDestroy(){this.subscriptions.forEach((e=>e.unsubscribe()))}writeValue(e){ie(e)&&(this.credentialsConfigFormGroup.reset(e,{emitEvent:!1}),this.updateValidators())}setDisabledState(e){e?this.credentialsConfigFormGroup.disable({emitEvent:!1}):(this.credentialsConfigFormGroup.enable({emitEvent:!1}),this.updateValidators())}updateView(){let e=this.credentialsConfigFormGroup.value;const t=e.type;switch(t){case"anonymous":e={type:t};break;case"basic":e={type:t,username:e.username,password:e.password};break;case"cert.PEM":delete e.username}this.propagateChange(e)}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}validate(e){return this.credentialsConfigFormGroup.valid?null:{credentialsConfig:{valid:!1}}}credentialsTypeChanged(){this.credentialsConfigFormGroup.patchValue({username:null,password:null,caCert:null,caCertFileName:null,privateKey:null,privateKeyFileName:null,cert:null,certFileName:null}),this.updateValidators()}updateValidators(e=!1){const t=this.credentialsConfigFormGroup.get("type").value;switch(e&&this.credentialsConfigFormGroup.reset({type:t},{emitEvent:!1}),this.credentialsConfigFormGroup.setValidators([]),this.credentialsConfigFormGroup.get("username").setValidators([]),this.credentialsConfigFormGroup.get("password").setValidators([]),t){case"anonymous":break;case"basic":this.credentialsConfigFormGroup.get("username").setValidators([O.required]),this.credentialsConfigFormGroup.get("password").setValidators(this.passwordFieldRequired?[O.required]:[]);break;case"cert.PEM":this.credentialsConfigFormGroup.setValidators([this.requiredFilesSelected(O.required,[["caCert","caCertFileName"],["privateKey","privateKeyFileName","cert","certFileName"]])])}this.credentialsConfigFormGroup.get("username").updateValueAndValidity({emitEvent:e}),this.credentialsConfigFormGroup.get("password").updateValueAndValidity({emitEvent:e}),this.credentialsConfigFormGroup.updateValueAndValidity({emitEvent:e})}requiredFilesSelected(e,t=null){return n=>{t||(t=[Object.keys(n.controls)]);return n?.controls&&t.some((t=>t.every((t=>!e(n.controls[t])))))?null:{notAllRequiredFilesSelected:!0}}}}e("CredentialsConfigComponent",En),En.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:En,deps:[{token:P.Store},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),En.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:En,selector:"tb-credentials-config",inputs:{required:"required",disableCertPemCredentials:"disableCertPemCredentials",passwordFieldRequired:"passwordFieldRequired"},providers:[{provide:B,useExisting:a((()=>En)),multi:!0},{provide:K,useExisting:a((()=>En)),multi:!0}],usesInheritance:!0,usesOnChanges:!0,ngImport:t,template:'
\n \n \n tb.rulenode.credentials\n \n {{ credentialsTypeTranslationsMap.get(credentialsConfigFormGroup.get(\'type\').value) | translate }}\n \n \n \n \n tb.rulenode.credentials-type\n \n \n {{ credentialsTypeTranslationsMap.get(credentialsType) | translate }}\n \n \n \n {{ \'tb.rulenode.credentials-type-required\' | translate }}\n \n \n
\n \n \n \n \n tb.rulenode.username\n \n \n {{ \'tb.rulenode.username-required\' | translate }}\n \n \n \n tb.rulenode.password\n \n \n \n {{ \'tb.rulenode.password-required\' | translate }}\n \n \n \n \n
{{ \'tb.rulenode.credentials-pem-hint\' | translate }}
\n \n \n \n \n \n \n \n tb.rulenode.private-key-password\n \n \n \n
\n
\n
\n
\n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:H.NgSwitch,selector:"[ngSwitch]",inputs:["ngSwitch"]},{kind:"directive",type:H.NgSwitchCase,selector:"[ngSwitchCase]",inputs:["ngSwitchCase"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Y.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:Je.MatExpansionPanel,selector:"mat-expansion-panel",inputs:["disabled","expanded","hideToggle","togglePosition"],outputs:["opened","closed","expandedChange","afterExpand","afterCollapse"],exportAs:["matExpansionPanel"]},{kind:"component",type:Je.MatExpansionPanelHeader,selector:"mat-expansion-panel-header",inputs:["tabIndex","expandedHeight","collapsedHeight"]},{kind:"directive",type:Je.MatExpansionPanelTitle,selector:"mat-panel-title"},{kind:"directive",type:Je.MatExpansionPanelDescription,selector:"mat-panel-description"},{kind:"directive",type:Je.MatExpansionPanelContent,selector:"ng-template[matExpansionPanelContent]"},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:Ye.FileInputComponent,selector:"tb-file-input",inputs:["label","hint","accept","noFileText","inputId","allowedExtensions","dropLabel","contentConvertFunction","required","requiredAsError","disabled","existingFileName","readAsBinary","workFromFileObj","multipleFile"],outputs:["fileNameChanged"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:We.TogglePasswordComponent,selector:"tb-toggle-password"},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:En,decorators:[{type:n,args:[{selector:"tb-credentials-config",providers:[{provide:B,useExisting:a((()=>En)),multi:!0},{provide:K,useExisting:a((()=>En)),multi:!0}],template:'
\n \n \n tb.rulenode.credentials\n \n {{ credentialsTypeTranslationsMap.get(credentialsConfigFormGroup.get(\'type\').value) | translate }}\n \n \n \n \n tb.rulenode.credentials-type\n \n \n {{ credentialsTypeTranslationsMap.get(credentialsType) | translate }}\n \n \n \n {{ \'tb.rulenode.credentials-type-required\' | translate }}\n \n \n
\n \n \n \n \n tb.rulenode.username\n \n \n {{ \'tb.rulenode.username-required\' | translate }}\n \n \n \n tb.rulenode.password\n \n \n \n {{ \'tb.rulenode.password-required\' | translate }}\n \n \n \n \n
{{ \'tb.rulenode.credentials-pem-hint\' | translate }}
\n \n \n \n \n \n \n \n tb.rulenode.private-key-password\n \n \n \n
\n
\n
\n
\n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder}]},propDecorators:{required:[{type:i}],disableCertPemCredentials:[{type:i}],passwordFieldRequired:[{type:i}]}});const Gn=new l("WindowToken","undefined"!=typeof window&&window.document?{providedIn:"root",factory:()=>window}:{providedIn:"root",factory:()=>{}});class Dn{constructor(e,t,n){this.ngZone=e,this.document=t,this.window=n,this.copySubject=new _e,this.copyResponse$=this.copySubject.asObservable(),this.config={}}configure(e){this.config=e}copy(e){if(!this.isSupported||!e)return this.pushCopyResponse({isSuccess:!1,content:e});const t=this.copyFromContent(e);return t?this.pushCopyResponse({content:e,isSuccess:t}):this.pushCopyResponse({isSuccess:!1,content:e})}get isSupported(){return!!this.document.queryCommandSupported&&!!this.document.queryCommandSupported("copy")&&!!this.window}isTargetValid(e){if(e instanceof HTMLInputElement||e instanceof HTMLTextAreaElement){if(e.hasAttribute("disabled"))throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');return!0}throw new Error("Target should be input or textarea")}copyFromInputElement(e,t=!0){try{this.selectTarget(e);const n=this.copyText();return this.clearSelection(t?e:void 0,this.window),n&&this.isCopySuccessInIE11()}catch(e){return!1}}isCopySuccessInIE11(){const e=this.window.clipboardData;return!(e&&e.getData&&!e.getData("Text"))}copyFromContent(e,t=this.document.body){if(this.tempTextArea&&!t.contains(this.tempTextArea)&&this.destroy(this.tempTextArea.parentElement||void 0),!this.tempTextArea){this.tempTextArea=this.createTempTextArea(this.document,this.window);try{t.appendChild(this.tempTextArea)}catch(e){throw new Error("Container should be a Dom element")}}this.tempTextArea.value=e;const n=this.copyFromInputElement(this.tempTextArea,!1);return this.config.cleanUpAfterCopy&&this.destroy(this.tempTextArea.parentElement||void 0),n}destroy(e=this.document.body){this.tempTextArea&&(e.removeChild(this.tempTextArea),this.tempTextArea=void 0)}selectTarget(e){return e.select(),e.setSelectionRange(0,e.value.length),e.value.length}copyText(){return this.document.execCommand("copy")}clearSelection(e,t){e&&e.focus(),t.getSelection()?.removeAllRanges()}createTempTextArea(e,t){const n="rtl"===e.documentElement.getAttribute("dir");let r;r=e.createElement("textarea"),r.style.fontSize="12pt",r.style.border="0",r.style.padding="0",r.style.margin="0",r.style.position="absolute",r.style[n?"right":"left"]="-9999px";const o=t.pageYOffset||e.documentElement.scrollTop;return r.style.top=o+"px",r.setAttribute("readonly",""),r}pushCopyResponse(e){this.copySubject.observers.length>0&&this.ngZone.run((()=>{this.copySubject.next(e)}))}pushCopyReponse(e){this.pushCopyResponse(e)}}Dn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"13.0.1",ngImport:t,type:Dn,deps:[{token:t.NgZone},{token:j},{token:Gn,optional:!0}],target:t.ɵɵFactoryTarget.Injectable}),Dn.ɵprov=t.ɵɵngDeclareInjectable({minVersion:"12.0.0",version:"13.0.1",ngImport:t,type:Dn,providedIn:"root"}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"13.0.1",ngImport:t,type:Dn,decorators:[{type:s,args:[{providedIn:"root"}]}],ctorParameters:function(){return[{type:t.NgZone},{type:void 0,decorators:[{type:m,args:[j]}]},{type:void 0,decorators:[{type:p},{type:m,args:[Gn]}]}]}});class wn{constructor(e,t,n,o){this.ngZone=e,this.host=t,this.renderer=n,this.clipboardSrv=o,this.cbOnSuccess=new r,this.cbOnError=new r,this.onClick=e=>{this.clipboardSrv.isSupported?this.targetElm&&this.clipboardSrv.isTargetValid(this.targetElm)?this.handleResult(this.clipboardSrv.copyFromInputElement(this.targetElm),this.targetElm.value,e):this.cbContent&&this.handleResult(this.clipboardSrv.copyFromContent(this.cbContent,this.container),this.cbContent,e):this.handleResult(!1,void 0,e)}}ngOnInit(){this.ngZone.runOutsideAngular((()=>{this.clickListener=this.renderer.listen(this.host.nativeElement,"click",this.onClick)}))}ngOnDestroy(){this.clickListener&&this.clickListener(),this.clipboardSrv.destroy(this.container)}handleResult(e,t,n){let r={isSuccess:e,content:t,successMessage:this.cbSuccessMsg,event:n};e?this.cbOnSuccess.observed&&this.ngZone.run((()=>{this.cbOnSuccess.emit(r)})):this.cbOnError.observed&&this.ngZone.run((()=>{this.cbOnError.emit(r)})),this.clipboardSrv.pushCopyResponse(r)}}wn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"13.0.1",ngImport:t,type:wn,deps:[{token:t.NgZone},{token:t.ElementRef},{token:t.Renderer2},{token:Dn}],target:t.ɵɵFactoryTarget.Directive}),wn.ɵdir=t.ɵɵngDeclareDirective({minVersion:"12.0.0",version:"13.0.1",type:wn,selector:"[ngxClipboard]",inputs:{targetElm:["ngxClipboard","targetElm"],container:"container",cbContent:"cbContent",cbSuccessMsg:"cbSuccessMsg"},outputs:{cbOnSuccess:"cbOnSuccess",cbOnError:"cbOnError"},ngImport:t}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"13.0.1",ngImport:t,type:wn,decorators:[{type:d,args:[{selector:"[ngxClipboard]"}]}],ctorParameters:function(){return[{type:t.NgZone},{type:t.ElementRef},{type:t.Renderer2},{type:Dn}]},propDecorators:{targetElm:[{type:i,args:["ngxClipboard"]}],container:[{type:i}],cbContent:[{type:i}],cbSuccessMsg:[{type:i}],cbOnSuccess:[{type:u}],cbOnError:[{type:u}]}});class Vn{constructor(e,t,n){this._clipboardService=e,this._viewContainerRef=t,this._templateRef=n}ngOnInit(){this._clipboardService.isSupported&&this._viewContainerRef.createEmbeddedView(this._templateRef)}}Vn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"13.0.1",ngImport:t,type:Vn,deps:[{token:Dn},{token:t.ViewContainerRef},{token:t.TemplateRef}],target:t.ɵɵFactoryTarget.Directive}),Vn.ɵdir=t.ɵɵngDeclareDirective({minVersion:"12.0.0",version:"13.0.1",type:Vn,selector:"[ngxClipboardIfSupported]",ngImport:t}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"13.0.1",ngImport:t,type:Vn,decorators:[{type:d,args:[{selector:"[ngxClipboardIfSupported]"}]}],ctorParameters:function(){return[{type:Dn},{type:t.ViewContainerRef},{type:t.TemplateRef}]}});class Pn{}Pn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"13.0.1",ngImport:t,type:Pn,deps:[],target:t.ɵɵFactoryTarget.NgModule}),Pn.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"12.0.0",version:"13.0.1",ngImport:t,type:Pn,declarations:[wn,Vn],imports:[$],exports:[wn,Vn]}),Pn.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"13.0.1",ngImport:t,type:Pn,imports:[[$]]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"13.0.1",ngImport:t,type:Pn,decorators:[{type:c,args:[{imports:[$],declarations:[wn,Vn],exports:[wn,Vn]}]}]});class Rn{set required(e){this.requiredValue!==e&&(this.requiredValue=e,this.updateValidators())}get required(){return this.requiredValue}constructor(e){this.fb=e,this.subscriptSizing="fixed",this.messageTypes=[{name:"Post attributes",value:"POST_ATTRIBUTES_REQUEST"},{name:"Post telemetry",value:"POST_TELEMETRY_REQUEST"},{name:"Custom",value:""}],this.propagateChange=()=>{},this.destroy$=new _e,this.messageTypeFormGroup=this.fb.group({messageTypeAlias:[null,[O.required]],messageType:[{value:null,disabled:!0},[O.maxLength(255)]]}),this.messageTypeFormGroup.get("messageTypeAlias").valueChanges.pipe(Be(this.destroy$)).subscribe((e=>this.updateMessageTypeValue(e))),this.messageTypeFormGroup.valueChanges.pipe(Be(this.destroy$)).subscribe((()=>this.updateView()))}ngOnDestroy(){this.destroy$.next(),this.destroy$.complete()}registerOnTouched(e){}registerOnChange(e){this.propagateChange=e}writeValue(e){this.modelValue=e;let t=this.messageTypes.find((t=>t.value===e));t||(t=this.messageTypes.find((e=>""===e.value))),this.messageTypeFormGroup.get("messageTypeAlias").patchValue(t,{emitEvent:!1}),this.messageTypeFormGroup.get("messageType").patchValue(e,{emitEvent:!1})}validate(){return this.messageTypeFormGroup.valid?null:{messageTypeInvalid:!0}}setDisabledState(e){this.disabled=e,e?this.messageTypeFormGroup.disable({emitEvent:!1}):(this.messageTypeFormGroup.enable({emitEvent:!1}),"Custom"!==this.messageTypeFormGroup.get("messageTypeAlias").value?.name&&this.messageTypeFormGroup.get("messageType").disable({emitEvent:!1}))}updateView(){const e=this.messageTypeFormGroup.getRawValue().messageType;this.modelValue!==e&&(this.modelValue=e,this.propagateChange(this.modelValue))}updateValidators(){this.messageTypeFormGroup.get("messageType").setValidators(this.required?[O.required,O.maxLength(255)]:[O.maxLength(255)]),this.messageTypeFormGroup.get("messageType").updateValueAndValidity({emitEvent:!1})}updateMessageTypeValue(e){"Custom"!==e?.name?this.messageTypeFormGroup.get("messageType").disable({emitEvent:!1}):this.messageTypeFormGroup.get("messageType").enable({emitEvent:!1}),this.messageTypeFormGroup.get("messageType").patchValue(e.value??null)}}e("OutputMessageTypeAutocompleteComponent",Rn),Rn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Rn,deps:[{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Rn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Rn,selector:"tb-output-message-type-autocomplete",inputs:{subscriptSizing:"subscriptSizing",disabled:"disabled",required:"required"},providers:[{provide:B,useExisting:a((()=>Rn)),multi:!0},{provide:K,useExisting:a((()=>Rn)),multi:!0}],ngImport:t,template:'
\n \n {{\'tb.rulenode.output-message-type\' | translate}}\n \n \n {{msgType.name}}\n \n \n \n \n {{\'tb.rulenode.message-type-value\' | translate}}\n \n \n \n {{ \'tb.rulenode.message-type-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.message-type-value-max-length\' | translate }}\n \n \n
\n\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:de.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Y.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:wn,selector:"[ngxClipboard]",inputs:["ngxClipboard","container","cbContent","cbSuccessMsg"],outputs:["cbOnSuccess","cbOnError"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),Oe([T()],Rn.prototype,"disabled",void 0),Oe([T()],Rn.prototype,"required",null),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Rn,decorators:[{type:n,args:[{selector:"tb-output-message-type-autocomplete",providers:[{provide:B,useExisting:a((()=>Rn)),multi:!0},{provide:K,useExisting:a((()=>Rn)),multi:!0}],template:'
\n \n {{\'tb.rulenode.output-message-type\' | translate}}\n \n \n {{msgType.name}}\n \n \n \n \n {{\'tb.rulenode.message-type-value\' | translate}}\n \n \n \n {{ \'tb.rulenode.message-type-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.message-type-value-max-length\' | translate }}\n \n \n
\n\n'}]}],ctorParameters:function(){return[{type:R.FormBuilder}]},propDecorators:{subscriptSizing:[{type:i}],disabled:[{type:i}],required:[{type:i}]}});class On{constructor(e,t){this.fb=e,this.translate=t,this.translation=nn,this.propagateChange=()=>{},this.destroy$=new _e,this.selectOptions=[]}ngOnInit(){this.initOptions(),this.chipControlGroup=this.fb.group({chipControl:[null,[]]}),this.chipControlGroup.get("chipControl").valueChanges.pipe(De(this.destroy$)).subscribe((e=>{e&&this.propagateChange(e)}))}ngOnDestroy(){this.destroy$.next(),this.destroy$.complete()}initOptions(){for(const e of this.translation.keys())this.selectOptions.push({value:e,name:this.translate.instant(this.translation.get(e))})}writeValue(e){this.chipControlGroup.get("chipControl").patchValue(e,{emitEvent:!1})}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){e?this.chipControlGroup.disable({emitEvent:!1}):this.chipControlGroup.enable({emitEvent:!1})}}e("MsgMetadataChipComponent",On),On.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:On,deps:[{token:R.FormBuilder},{token:Z.TranslateService}],target:t.ɵɵFactoryTarget.Component}),On.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:On,selector:"tb-msg-metadata-chip",inputs:{labelText:"labelText",translation:"translation"},providers:[{provide:B,useExisting:a((()=>On)),multi:!0}],ngImport:t,template:'
\n
{{ labelText }}
\n \n {{ option.name }}\n \n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"component",type:be.MatChipListbox,selector:"mat-chip-listbox",inputs:["tabIndex","multiple","aria-orientation","selectable","compareWith","required","hideSingleSelectionIndicator","value"],outputs:["change"]},{kind:"component",type:be.MatChipOption,selector:"mat-basic-chip-option, [mat-basic-chip-option], mat-chip-option, [mat-chip-option]",inputs:["color","disabled","disableRipple","tabIndex","selectable","selected"],outputs:["selectionChange"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:On,decorators:[{type:n,args:[{selector:"tb-msg-metadata-chip",providers:[{provide:B,useExisting:a((()=>On)),multi:!0}],template:'
\n
{{ labelText }}
\n \n {{ option.name }}\n \n
\n'}]}],ctorParameters:function(){return[{type:R.FormBuilder},{type:Z.TranslateService}]},propDecorators:{labelText:[{type:i}],translation:[{type:i}]}});class _n extends L{constructor(e,t,n,r){super(e),this.store=e,this.translate=t,this.injector=n,this.fb=r,this.destroy$=new _e,this.sourceFieldSubcritption=[],this.propagateChange=null,this.disabled=!1,this.required=!1,this.oneMapRequiredValidator=e=>e.get("keyVals").value.length,this.propagateNestedErrors=e=>{if(this.svListFormGroup&&this.svListFormGroup.get("keyVals")&&"VALID"===this.svListFormGroup.get("keyVals")?.status)return null;const t={};if(this.svListFormGroup&&this.svListFormGroup.setErrors(null),e instanceof z||e instanceof U){if(e.errors)for(const n of Object.keys(e.errors))t[n]=!0;for(const n of Object.keys(e.controls)){const r=this.propagateNestedErrors(e.controls[n]);if(r&&Object.keys(r).length)for(const e of Object.keys(r))t[e]=!0}return t}if(e.errors)for(const n of Object.keys(e.errors))t[n]=!0;return ae(t,{})?null:t}}ngOnInit(){this.ngControl=this.injector.get(_),null!=this.ngControl&&(this.ngControl.valueAccessor=this),this.svListFormGroup=this.fb.group({keyVals:this.fb.array([])},{validators:[this.propagateNestedErrors,this.oneMapRequiredValidator]}),this.svListFormGroup.valueChanges.pipe(De(this.destroy$)).subscribe((()=>{this.updateModel()}))}ngOnDestroy(){this.destroy$.next(),this.destroy$.complete()}keyValsFormArray(){return this.svListFormGroup.get("keyVals")}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.svListFormGroup.disable({emitEvent:!1}):this.svListFormGroup.enable({emitEvent:!1})}writeValue(e){const t=Object.keys(e).map((t=>({key:t,value:e[t]})));if(this.keyValsFormArray().length===t.length)this.keyValsFormArray().patchValue(t,{emitEvent:!1});else{const e=[];t.forEach((t=>{e.push(this.fb.group({key:[t.key,[O.required]],value:[t.value,[O.required,O.pattern(/(?:.|\s)*\S(&:.|\s)*/)]]}))})),this.svListFormGroup.setControl("keyVals",this.fb.array(e,this.propagateNestedErrors),{emitEvent:!1});for(const e of this.keyValsFormArray().controls)this.keyChangeSubscribe(e)}}filterSelectOptions(e){const t=[];for(const e of this.svListFormGroup.get("keyVals").value){const n=this.selectOptions.find((t=>t.value===e.key));n&&t.push(n)}const n=[];for(const r of this.selectOptions)ie(t.find((e=>e.value===r.value)))&&r.value!==e?.get("key").value||n.push(r);return n}removeKeyVal(e){this.keyValsFormArray().removeAt(e),this.sourceFieldSubcritption[e].unsubscribe(),this.sourceFieldSubcritption.splice(e,1)}addKeyVal(){this.keyValsFormArray().push(this.fb.group({key:["",[O.required]],value:["",[O.required,O.pattern(/(?:.|\s)*\S(&:.|\s)*/)]]})),this.keyChangeSubscribe(this.keyValsFormArray().at(this.keyValsFormArray().length-1))}keyChangeSubscribe(e){this.sourceFieldSubcritption.push(e.get("key").valueChanges.pipe(De(this.destroy$)).subscribe((t=>{const n=Lt.get(t);e.get("value").patchValue(this.targetKeyPrefix+n[0].toUpperCase()+n.slice(1))})))}validate(e){return!this.svListFormGroup.get("keyVals").value.length&&this.required?{svMapRequired:!0}:this.svListFormGroup.valid?null:{svFieldsRequired:!0}}updateModel(){const e=this.svListFormGroup.get("keyVals").value;if(this.required&&!e.length||!this.svListFormGroup.valid)this.propagateChange(null);else{const t={};e.forEach((e=>{t[e.key]=e.value})),this.propagateChange(t)}}}e("SvMapConfigComponent",_n),_n.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:_n,deps:[{token:P.Store},{token:Z.TranslateService},{token:t.Injector},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),_n.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:_n,selector:"tb-sv-map-config",inputs:{selectOptions:"selectOptions",disabled:"disabled",labelText:"labelText",requiredText:"requiredText",targetKeyPrefix:"targetKeyPrefix",selectText:"selectText",selectRequiredText:"selectRequiredText",valText:"valText",valRequiredText:"valRequiredText",hintText:"hintText",popupHelpLink:"popupHelpLink",required:"required"},providers:[{provide:B,useExisting:a((()=>_n)),multi:!0},{provide:K,useExisting:a((()=>_n)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n
\n
{{ labelText }}
\n
\n tb.rulenode.map-fields-required\n
\n
\n {{ requiredText }}\n
\n
\n
\n
\n
\n
{{ selectText }}
\n
{{ valText }}
\n
\n
\n
\n
\n \n \n \n {{option.name}}\n \n \n \n \n \n \n
\n \n
\n
\n
\n
\n
\n
\n \n
\n \n
\n',styles:[":host .field-space{flex:1 1 50%}:host .actions-header{width:40px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:H.NgClass,selector:"[ngClass]",inputs:["class","ngClass"]},{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:de.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:de.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:Ie.DefaultClassDirective,selector:" [ngClass], [ngClass.xs], [ngClass.sm], [ngClass.md], [ngClass.lg], [ngClass.xl], [ngClass.lt-sm], [ngClass.lt-md], [ngClass.lt-lg], [ngClass.lt-xl], [ngClass.gt-xs], [ngClass.gt-sm], [ngClass.gt-md], [ngClass.gt-lg]",inputs:["ngClass","ngClass.xs","ngClass.sm","ngClass.md","ngClass.lg","ngClass.xl","ngClass.lt-sm","ngClass.lt-md","ngClass.lt-lg","ngClass.lt-xl","ngClass.gt-xs","ngClass.gt-sm","ngClass.gt-md","ngClass.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormControlDirective,selector:"[formControl]",inputs:["formControl","disabled","ngModel"],outputs:["ngModelChange"],exportAs:["ngForm"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Nn,selector:"tb-example-hint",inputs:["hintText","popupHelpLink","textAlign"]},{kind:"pipe",type:H.AsyncPipe,name:"async"},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),Oe([T()],_n.prototype,"disabled",void 0),Oe([T()],_n.prototype,"required",void 0),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:_n,decorators:[{type:n,args:[{selector:"tb-sv-map-config",providers:[{provide:B,useExisting:a((()=>_n)),multi:!0},{provide:K,useExisting:a((()=>_n)),multi:!0}],template:'
\n
\n
{{ labelText }}
\n
\n tb.rulenode.map-fields-required\n
\n
\n {{ requiredText }}\n
\n
\n
\n
\n
\n
{{ selectText }}
\n
{{ valText }}
\n
\n
\n
\n
\n \n \n \n {{option.name}}\n \n \n \n \n \n \n
\n \n
\n
\n
\n
\n
\n
\n \n
\n \n
\n',styles:[":host .field-space{flex:1 1 50%}:host .actions-header{width:40px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:P.Store},{type:Z.TranslateService},{type:t.Injector},{type:R.FormBuilder}]},propDecorators:{selectOptions:[{type:i}],disabled:[{type:i}],labelText:[{type:i}],requiredText:[{type:i}],targetKeyPrefix:[{type:i}],selectText:[{type:i}],selectRequiredText:[{type:i}],valText:[{type:i}],valRequiredText:[{type:i}],hintText:[{type:i}],popupHelpLink:[{type:i}],required:[{type:i}]}});class Bn extends L{get required(){return this.requiredValue}set required(e){this.requiredValue=Fe(e)}constructor(e,t){super(e),this.store=e,this.fb=t,this.directionTypes=Object.keys(v),this.directionTypeTranslations=C,this.propagateChange=null}ngOnInit(){this.relationsQueryFormGroup=this.fb.group({fetchLastLevelOnly:[!1,[]],direction:[null,[O.required]],maxLevel:[null,[]],filters:[null]}),this.relationsQueryFormGroup.valueChanges.subscribe((e=>{this.relationsQueryFormGroup.valid?this.propagateChange(e):this.propagateChange(null)}))}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.relationsQueryFormGroup.disable({emitEvent:!1}):this.relationsQueryFormGroup.enable({emitEvent:!1})}writeValue(e){this.relationsQueryFormGroup.reset(e||{},{emitEvent:!1})}}e("RelationsQueryConfigOldComponent",Bn),Bn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Bn,deps:[{token:P.Store},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Bn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Bn,selector:"tb-relations-query-config-old",inputs:{disabled:"disabled",required:"required"},providers:[{provide:B,useExisting:a((()=>Bn)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'alias.last-level-relation\' | translate }}\n \n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n
\n
relation.relation-filters
\n \n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"component",type:Q.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Qe.RelationFiltersComponent,selector:"tb-relation-filters",inputs:["disabled","allowedEntityTypes"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Bn,decorators:[{type:n,args:[{selector:"tb-relations-query-config-old",providers:[{provide:B,useExisting:a((()=>Bn)),multi:!0}],template:'
\n \n {{ \'alias.last-level-relation\' | translate }}\n \n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n
\n
relation.relation-filters
\n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder}]},propDecorators:{disabled:[{type:i}],required:[{type:i}]}});class Kn{constructor(e,t){this.translate=e,this.fb=t,this.propagateChange=e=>{},this.destroy$=new _e,this.separatorKeysCodes=[ge,ye,xe],this.onTouched=()=>{}}ngOnInit(){this.attributeControlGroup=this.fb.group({clientAttributeNames:[[],[]],sharedAttributeNames:[[],[]],serverAttributeNames:[[],[]],latestTsKeyNames:[[],[]],getLatestValueWithTs:[!1,[]]},{validators:this.atLeastOne(O.required,["clientAttributeNames","sharedAttributeNames","serverAttributeNames","latestTsKeyNames"])}),this.attributeControlGroup.valueChanges.pipe(De(this.destroy$)).subscribe((e=>{this.propagateChange(this.preparePropagateValue(e))}))}preparePropagateValue(e){const t={};for(const n in e)t[n]="getLatestValueWithTs"===n||ie(e[n])?e[n]:[];return t}validate(){return this.attributeControlGroup.valid?null:{atLeastOneRequired:!0}}atLeastOne(e,t=null){return n=>{t||(t=Object.keys(n.controls));return n?.controls&&t.some((t=>!e(n.controls[t])))?null:{atLeastOne:!0}}}writeValue(e){this.attributeControlGroup.setValue(e,{emitEvent:!1})}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){this.onTouched=e}setDisabledState(e){e?this.attributeControlGroup.disable({emitEvent:!1}):this.attributeControlGroup.enable({emitEvent:!1})}ngOnDestroy(){this.destroy$.next(null),this.destroy$.complete()}}e("SelectAttributesComponent",Kn),Kn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Kn,deps:[{token:Z.TranslateService},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Kn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Kn,selector:"tb-select-attributes",inputs:{popupHelpLink:"popupHelpLink"},providers:[{provide:B,useExisting:a((()=>Kn)),multi:!0},{provide:K,useExisting:Kn,multi:!0}],ngImport:t,template:'
\n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n \n {{ \'tb.rulenode.fetch-latest-telemetry-with-timestamp\' | translate }}\n \n
\n
\n\n\n help\n\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:H.NgTemplateOutlet,selector:"[ngTemplateOutlet]",inputs:["ngTemplateOutletContext","ngTemplateOutlet","ngTemplateOutletInjector"]},{kind:"component",type:Ze.StringItemsListComponent,selector:"tb-string-items-list",inputs:["required","disabled","label","placeholder","hint","requiredText","floatLabel","appearance","editable","subscriptSizing","predefinedValues"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:Y.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:te.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:ne.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"component",type:Nn,selector:"tb-example-hint",inputs:["hintText","popupHelpLink","textAlign"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Kn,decorators:[{type:n,args:[{selector:"tb-select-attributes",providers:[{provide:B,useExisting:a((()=>Kn)),multi:!0},{provide:K,useExisting:Kn,multi:!0}],template:'
\n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n \n {{ \'tb.rulenode.fetch-latest-telemetry-with-timestamp\' | translate }}\n \n
\n
\n\n\n help\n\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:Z.TranslateService},{type:R.FormBuilder}]},propDecorators:{popupHelpLink:[{type:i}]}});class zn extends L{constructor(e,t){super(e),this.store=e,this.fb=t,this.propagateChange=null,this.destroy$=new _e,this.alarmStatus=q,this.alarmStatusTranslations=A}ngOnInit(){this.alarmStatusGroup=this.fb.group({alarmStatus:[null,[]]}),this.alarmStatusGroup.get("alarmStatus").valueChanges.pipe(De(this.destroy$)).subscribe((e=>{this.propagateChange(e)}))}setDisabledState(e){e?this.alarmStatusGroup.disable({emitEvent:!1}):this.alarmStatusGroup.enable({emitEvent:!1})}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}ngOnDestroy(){this.destroy$.next(),this.destroy$.complete()}writeValue(e){this.alarmStatusGroup.get("alarmStatus").patchValue(e,{emitEvent:!1})}}e("AlarmStatusSelectComponent",zn),zn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:zn,deps:[{token:P.Store},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),zn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:zn,selector:"tb-alarm-status-select",providers:[{provide:B,useExisting:a((()=>zn)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n
\n \n {{ alarmStatusTranslations.get(alarmStatus.ACTIVE_UNACK) | translate }}\n \n \n {{ alarmStatusTranslations.get(alarmStatus.ACTIVE_ACK) | translate }}\n \n
\n
\n \n {{ alarmStatusTranslations.get(alarmStatus.CLEARED_UNACK) | translate }}\n \n \n {{ alarmStatusTranslations.get(alarmStatus.CLEARED_ACK) | translate }}\n \n
\n
\n
\n',styles:[":host .chip-listbox{max-width:460px;width:100%}:host .chip-listbox .toggle-column{display:flex;flex:1 1 100%;gap:8px}:host .chip-listbox .option{margin:0}@media screen and (max-width: 959px){:host .chip-listbox{max-width:360px}:host .chip-listbox .toggle-column{flex-direction:column}}:host ::ng-deep .chip-listbox .mdc-evolution-chip-set__chips{gap:8px}:host ::ng-deep .chip-listbox .option button{flex-basis:100%;justify-content:start}:host ::ng-deep .chip-listbox .option .mdc-evolution-chip__graphic{flex-grow:0}\n"],dependencies:[{kind:"component",type:be.MatChipListbox,selector:"mat-chip-listbox",inputs:["tabIndex","multiple","aria-orientation","selectable","compareWith","required","hideSingleSelectionIndicator","value"],outputs:["change"]},{kind:"component",type:be.MatChipOption,selector:"mat-basic-chip-option, [mat-basic-chip-option], mat-chip-option, [mat-chip-option]",inputs:["color","disabled","disableRipple","tabIndex","selectable","selected"],outputs:["selectionChange"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:zn,decorators:[{type:n,args:[{selector:"tb-alarm-status-select",providers:[{provide:B,useExisting:a((()=>zn)),multi:!0}],template:'
\n \n
\n \n {{ alarmStatusTranslations.get(alarmStatus.ACTIVE_UNACK) | translate }}\n \n \n {{ alarmStatusTranslations.get(alarmStatus.ACTIVE_ACK) | translate }}\n \n
\n
\n \n {{ alarmStatusTranslations.get(alarmStatus.CLEARED_UNACK) | translate }}\n \n \n {{ alarmStatusTranslations.get(alarmStatus.CLEARED_ACK) | translate }}\n \n
\n
\n
\n',styles:[":host .chip-listbox{max-width:460px;width:100%}:host .chip-listbox .toggle-column{display:flex;flex:1 1 100%;gap:8px}:host .chip-listbox .option{margin:0}@media screen and (max-width: 959px){:host .chip-listbox{max-width:360px}:host .chip-listbox .toggle-column{flex-direction:column}}:host ::ng-deep .chip-listbox .mdc-evolution-chip-set__chips{gap:8px}:host ::ng-deep .chip-listbox .option button{flex-basis:100%;justify-content:start}:host ::ng-deep .chip-listbox .option .mdc-evolution-chip__graphic{flex-grow:0}\n"]}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder}]}});class Un{}e("RulenodeCoreConfigCommonModule",Un),Un.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Un,deps:[],target:t.ɵɵFactoryTarget.NgModule}),Un.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.10",ngImport:t,type:Un,declarations:[Sn,qn,An,Mn,En,Ln,Tn,Rn,hn,On,_n,Bn,Kn,zn,Nn],imports:[$,M,Re],exports:[Sn,qn,An,Mn,En,Ln,Tn,Rn,hn,On,_n,Bn,Kn,zn,Nn]}),Un.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Un,imports:[$,M,Re]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Un,decorators:[{type:c,args:[{declarations:[Sn,qn,An,Mn,En,Ln,Tn,Rn,hn,On,_n,Bn,Kn,zn,Nn],imports:[$,M,Re],exports:[Sn,qn,An,Mn,En,Ln,Tn,Rn,hn,On,_n,Bn,Kn,zn,Nn]}]}]});class Hn{}e("RuleNodeCoreConfigActionModule",Hn),Hn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Hn,deps:[],target:t.ɵɵFactoryTarget.NgModule}),Hn.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.10",ngImport:t,type:Hn,declarations:[kn,ct,Cn,bn,un,ut,ft,gt,yt,fn,xt,ht,dn,cn,xn,vn,Fn,bt,yn,gn,In],imports:[$,M,Re,Un],exports:[kn,ct,Cn,bn,un,ut,ft,gt,yt,fn,xt,ht,dn,cn,xn,vn,Fn,bt,yn,gn,In]}),Hn.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Hn,imports:[$,M,Re,Un]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Hn,decorators:[{type:c,args:[{declarations:[kn,ct,Cn,bn,un,ut,ft,gt,yt,fn,xt,ht,dn,cn,xn,vn,Fn,bt,yn,gn,In],imports:[$,M,Re,Un],exports:[kn,ct,Cn,bn,un,ut,ft,gt,yt,fn,xt,ht,dn,cn,xn,vn,Fn,bt,yn,gn,In]}]}]});class jn extends f{constructor(e,t,n){super(e),this.store=e,this.translate=t,this.fb=n,this.separatorKeysCodes=[ge,ye,xe]}configForm(){return this.calculateDeltaConfigForm}onConfigurationSet(e){this.calculateDeltaConfigForm=this.fb.group({inputValueKey:[e.inputValueKey,[O.required,O.pattern(/(?:.|\s)*\S(&:.|\s)*/)]],outputValueKey:[e.outputValueKey,[O.required,O.pattern(/(?:.|\s)*\S(&:.|\s)*/)]],useCache:[e.useCache,[]],addPeriodBetweenMsgs:[e.addPeriodBetweenMsgs,[]],periodValueKey:[e.periodValueKey,[]],round:[e.round,[O.min(0),O.max(15)]],tellFailureIfDeltaIsNegative:[e.tellFailureIfDeltaIsNegative,[]]})}prepareInputConfig(e){return{inputValueKey:ie(e?.inputValueKey)?e.inputValueKey:null,outputValueKey:ie(e?.outputValueKey)?e.outputValueKey:null,useCache:!ie(e?.useCache)||e.useCache,addPeriodBetweenMsgs:!!ie(e?.addPeriodBetweenMsgs)&&e.addPeriodBetweenMsgs,periodValueKey:ie(e?.periodValueKey)?e.periodValueKey:null,round:ie(e?.round)?e.round:null,tellFailureIfDeltaIsNegative:!ie(e?.tellFailureIfDeltaIsNegative)||e.tellFailureIfDeltaIsNegative}}prepareOutputConfig(e){return le(e)}updateValidators(e){this.calculateDeltaConfigForm.get("addPeriodBetweenMsgs").value?this.calculateDeltaConfigForm.get("periodValueKey").setValidators([O.required]):this.calculateDeltaConfigForm.get("periodValueKey").setValidators([]),this.calculateDeltaConfigForm.get("periodValueKey").updateValueAndValidity({emitEvent:e})}validatorTriggers(){return["addPeriodBetweenMsgs"]}}e("CalculateDeltaConfigComponent",jn),jn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:jn,deps:[{token:P.Store},{token:Z.TranslateService},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),jn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:jn,selector:"tb-enrichment-node-calculate-delta-config",usesInheritance:!0,ngImport:t,template:"
\n
\n \n {{ 'tb.rulenode.input-value-key' | translate }}\n \n \n {{ 'tb.rulenode.input-value-key-required' | translate }}\n \n \n \n {{ 'tb.rulenode.output-value-key' | translate }}\n \n \n {{ 'tb.rulenode.output-value-key-required' | translate }}\n \n \n
\n \n {{ 'tb.rulenode.number-of-digits-after-floating-point' | translate }}\n \n \n {{ 'tb.rulenode.number-of-digits-after-floating-point-range' | translate }}\n \n \n {{ 'tb.rulenode.number-of-digits-after-floating-point-range' | translate }}\n \n \n
\n
\n \n {{ 'tb.rulenode.failure-if-delta-negative' | translate }}\n \n
\n
\n \n {{ 'tb.rulenode.use-caching' | translate }}\n \n
\n
\n
\n \n {{ 'tb.rulenode.add-time-difference-between-readings' | translate:\n { inputValueKey: calculateDeltaConfigForm.get('inputValueKey').valid ?\n calculateDeltaConfigForm.get('inputValueKey').value : 'tb.rulenode.input-value-key' | translate } }}\n \n
\n \n {{ 'tb.rulenode.period-value-key' | translate }}\n \n \n {{ 'tb.rulenode.period-value-key-required' | translate }}\n \n \n
\n
\n
\n",dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:te.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:ne.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:jn,decorators:[{type:n,args:[{selector:"tb-enrichment-node-calculate-delta-config",template:"
\n
\n \n {{ 'tb.rulenode.input-value-key' | translate }}\n \n \n {{ 'tb.rulenode.input-value-key-required' | translate }}\n \n \n \n {{ 'tb.rulenode.output-value-key' | translate }}\n \n \n {{ 'tb.rulenode.output-value-key-required' | translate }}\n \n \n
\n \n {{ 'tb.rulenode.number-of-digits-after-floating-point' | translate }}\n \n \n {{ 'tb.rulenode.number-of-digits-after-floating-point-range' | translate }}\n \n \n {{ 'tb.rulenode.number-of-digits-after-floating-point-range' | translate }}\n \n \n
\n
\n \n {{ 'tb.rulenode.failure-if-delta-negative' | translate }}\n \n
\n
\n \n {{ 'tb.rulenode.use-caching' | translate }}\n \n
\n
\n
\n \n {{ 'tb.rulenode.add-time-difference-between-readings' | translate:\n { inputValueKey: calculateDeltaConfigForm.get('inputValueKey').valid ?\n calculateDeltaConfigForm.get('inputValueKey').value : 'tb.rulenode.input-value-key' | translate } }}\n \n
\n \n {{ 'tb.rulenode.period-value-key' | translate }}\n \n \n {{ 'tb.rulenode.period-value-key-required' | translate }}\n \n \n
\n
\n
\n"}]}],ctorParameters:function(){return[{type:P.Store},{type:Z.TranslateService},{type:R.FormBuilder}]}});class $n extends f{constructor(e,t,n){super(e),this.store=e,this.fb=t,this.translate=n,this.fetchToData=[],this.DataToFetch=Pt;for(const e of Rt.keys())e!==Pt.FIELDS&&this.fetchToData.push({value:e,name:this.translate.instant(Rt.get(e))})}configForm(){return this.customerAttributesConfigForm}prepareOutputConfig(e){const t={};for(const n of Object.keys(e.dataMapping))t[n.trim()]=e.dataMapping[n];return e.dataMapping=t,le(e)}prepareInputConfig(e){let t,n;return t=ie(e?.telemetry)?e.telemetry?Pt.LATEST_TELEMETRY:Pt.ATTRIBUTES:ie(e?.dataToFetch)?e.dataToFetch:Pt.ATTRIBUTES,n=ie(e?.attrMapping)?e.attrMapping:ie(e?.dataMapping)?e.dataMapping:null,{dataToFetch:t,dataMapping:n,fetchTo:ie(e?.fetchTo)?e.fetchTo:en.METADATA}}selectTranslation(e,t){return this.customerAttributesConfigForm.get("dataToFetch").value===Pt.LATEST_TELEMETRY?e:t}onConfigurationSet(e){this.customerAttributesConfigForm=this.fb.group({dataToFetch:[e.dataToFetch,[]],dataMapping:[e.dataMapping,[O.required]],fetchTo:[e.fetchTo]})}}e("CustomerAttributesConfigComponent",$n),$n.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:$n,deps:[{token:P.Store},{token:R.FormBuilder},{token:Z.TranslateService}],target:t.ɵɵFactoryTarget.Component}),$n.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:$n,selector:"tb-enrichment-node-customer-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n
tb.rulenode.mapping-of-customers
\n
\n
\n \n \n {{ data.name }}\n \n \n
\n
\n \n \n \n \n
\n',styles:[":host .fetch-to-data-toggle{max-width:420px;width:100%}\n"],dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:W.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"directive",type:Xe.ToggleOption,selector:"tb-toggle-option",inputs:["value"]},{kind:"component",type:et.ToggleSelectComponent,selector:"tb-toggle-select",inputs:["disabled","selectMediaBreakpoint","appearance","disablePagination"]},{kind:"component",type:Sn,selector:"tb-kv-map-config",inputs:["disabled","uniqueKeyValuePairValidator","labelText","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","popupHelpLink","required"]},{kind:"component",type:On,selector:"tb-msg-metadata-chip",inputs:["labelText","translation"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:$n,decorators:[{type:n,args:[{selector:"tb-enrichment-node-customer-attributes-config",template:'
\n
tb.rulenode.mapping-of-customers
\n
\n
\n \n \n {{ data.name }}\n \n \n
\n
\n \n \n \n \n
\n',styles:[":host .fetch-to-data-toggle{max-width:420px;width:100%}\n"]}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder},{type:Z.TranslateService}]}});class Qn extends f{constructor(e,t,n){super(e),this.store=e,this.translate=t,this.fb=n}configForm(){return this.deviceAttributesConfigForm}onConfigurationSet(e){this.deviceAttributesConfigForm=this.fb.group({deviceRelationsQuery:[e.deviceRelationsQuery,[O.required]],tellFailureIfAbsent:[e.tellFailureIfAbsent,[]],fetchTo:[e.fetchTo,[]],attributesControl:[e.attributesControl,[]]})}prepareInputConfig(e){return se(e)&&(e.attributesControl={clientAttributeNames:ie(e?.clientAttributeNames)?e.clientAttributeNames:[],latestTsKeyNames:ie(e?.latestTsKeyNames)?e.latestTsKeyNames:[],serverAttributeNames:ie(e?.serverAttributeNames)?e.serverAttributeNames:[],sharedAttributeNames:ie(e?.sharedAttributeNames)?e.sharedAttributeNames:[],getLatestValueWithTs:!!ie(e?.getLatestValueWithTs)&&e.getLatestValueWithTs}),{deviceRelationsQuery:ie(e?.deviceRelationsQuery)?e.deviceRelationsQuery:null,tellFailureIfAbsent:!ie(e?.tellFailureIfAbsent)||e.tellFailureIfAbsent,fetchTo:ie(e?.fetchTo)?e.fetchTo:en.METADATA,attributesControl:e?e.attributesControl:null}}prepareOutputConfig(e){for(const t of Object.keys(e.attributesControl))e[t]=e.attributesControl[t];return delete e.attributesControl,e}}e("DeviceAttributesConfigComponent",Qn),Qn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Qn,deps:[{token:P.Store},{token:Z.TranslateService},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Qn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Qn,selector:"tb-enrichment-node-device-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n
\n
tb.rulenode.device-relations-query
\n \n \n
\n
\n
\n
tb.rulenode.related-device-attributes
\n
\n tb.rulenode.at-least-one-field-required\n
\n
\n \n \n
\n
\n \n {{ \'tb.rulenode.tell-failure\' | translate }}\n \n
\n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"component",type:te.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:ne.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"component",type:qn,selector:"tb-device-relations-query-config",inputs:["disabled","required"]},{kind:"component",type:On,selector:"tb-msg-metadata-chip",inputs:["labelText","translation"]},{kind:"component",type:Kn,selector:"tb-select-attributes",inputs:["popupHelpLink"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Qn,decorators:[{type:n,args:[{selector:"tb-enrichment-node-device-attributes-config",template:'
\n
\n
tb.rulenode.device-relations-query
\n \n \n
\n
\n
\n
tb.rulenode.related-device-attributes
\n
\n tb.rulenode.at-least-one-field-required\n
\n
\n \n \n
\n
\n \n {{ \'tb.rulenode.tell-failure\' | translate }}\n \n
\n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:P.Store},{type:Z.TranslateService},{type:R.FormBuilder}]}});class Jn extends f{constructor(e,t,n){super(e),this.store=e,this.translate=t,this.fb=n,this.predefinedValues=[];for(const e of Object.keys(Mt))this.predefinedValues.push({value:Mt[e],name:this.translate.instant(Et.get(Mt[e]))})}ngOnInit(){super.ngOnInit()}configForm(){return this.entityDetailsConfigForm}prepareInputConfig(e){let t;return t=ie(e?.addToMetadata)?e.addToMetadata?en.METADATA:en.DATA:e?.fetchTo?e.fetchTo:en.DATA,{detailsList:ie(e?.detailsList)?e.detailsList:null,fetchTo:t}}onConfigurationSet(e){this.entityDetailsConfigForm=this.fb.group({detailsList:[e.detailsList,[O.required]],fetchTo:[e.fetchTo,[]]})}}e("EntityDetailsConfigComponent",Jn),Jn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Jn,deps:[{token:P.Store},{token:Z.TranslateService},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Jn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Jn,selector:"tb-enrichment-node-entity-details-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n help\n \n \n \n \n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"component",type:Ze.StringItemsListComponent,selector:"tb-string-items-list",inputs:["required","disabled","label","placeholder","hint","requiredText","floatLabel","appearance","editable","subscriptSizing","predefinedValues"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:Y.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:On,selector:"tb-msg-metadata-chip",inputs:["labelText","translation"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Jn,decorators:[{type:n,args:[{selector:"tb-enrichment-node-entity-details-config",template:'
\n \n \n help\n \n \n \n \n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:P.Store},{type:Z.TranslateService},{type:R.FormBuilder}]}});class Yn extends f{constructor(e,t,n){super(e),this.store=e,this.translate=t,this.fb=n,this.separatorKeysCodes=[ge,ye,xe],this.aggregationTypes=E,this.aggregations=Object.values(E),this.aggregationTypesTranslations=G,this.fetchMode=Gt,this.samplingOrders=Object.values(Vt),this.samplingOrdersTranslate=_t,this.timeUnits=Object.values(Nt),this.timeUnitsTranslationMap=St,this.deduplicationStrategiesHintTranslations=wt,this.headerOptions=[],this.timeUnitMap={[Nt.MILLISECONDS]:1,[Nt.SECONDS]:1e3,[Nt.MINUTES]:6e4,[Nt.HOURS]:36e5,[Nt.DAYS]:864e5},this.intervalValidator=()=>e=>e.get("startInterval").value*this.timeUnitMap[e.get("startIntervalTimeUnit").value]<=e.get("endInterval").value*this.timeUnitMap[e.get("endIntervalTimeUnit").value]?{intervalError:!0}:null;for(const e of Dt.keys())this.headerOptions.push({value:e,name:this.translate.instant(Dt.get(e))})}configForm(){return this.getTelemetryFromDatabaseConfigForm}onConfigurationSet(e){this.getTelemetryFromDatabaseConfigForm=this.fb.group({latestTsKeyNames:[e.latestTsKeyNames,[O.required]],aggregation:[e.aggregation,[O.required]],fetchMode:[e.fetchMode,[O.required]],orderBy:[e.orderBy,[]],limit:[e.limit,[]],useMetadataIntervalPatterns:[e.useMetadataIntervalPatterns,[]],interval:this.fb.group({startInterval:[e.interval.startInterval,[]],startIntervalTimeUnit:[e.interval.startIntervalTimeUnit,[]],endInterval:[e.interval.endInterval,[]],endIntervalTimeUnit:[e.interval.endIntervalTimeUnit,[]]}),startIntervalPattern:[e.startIntervalPattern,[]],endIntervalPattern:[e.endIntervalPattern,[]]})}validatorTriggers(){return["fetchMode","useMetadataIntervalPatterns"]}toggleChange(e){this.getTelemetryFromDatabaseConfigForm.get("fetchMode").patchValue(e,{emitEvent:!0})}prepareOutputConfig(e){return e.startInterval=e.interval.startInterval,e.startIntervalTimeUnit=e.interval.startIntervalTimeUnit,e.endInterval=e.interval.endInterval,e.endIntervalTimeUnit=e.interval.endIntervalTimeUnit,delete e.interval,le(e)}prepareInputConfig(e){return se(e)&&(e.interval={startInterval:e.startInterval,startIntervalTimeUnit:e.startIntervalTimeUnit,endInterval:e.endInterval,endIntervalTimeUnit:e.endIntervalTimeUnit}),{latestTsKeyNames:ie(e?.latestTsKeyNames)?e.latestTsKeyNames:null,aggregation:ie(e?.aggregation)?e.aggregation:E.NONE,fetchMode:ie(e?.fetchMode)?e.fetchMode:Gt.FIRST,orderBy:ie(e?.orderBy)?e.orderBy:Vt.ASC,limit:ie(e?.limit)?e.limit:1e3,useMetadataIntervalPatterns:!!ie(e?.useMetadataIntervalPatterns)&&e.useMetadataIntervalPatterns,interval:{startInterval:ie(e?.interval?.startInterval)?e.interval.startInterval:2,startIntervalTimeUnit:ie(e?.interval?.startIntervalTimeUnit)?e.interval.startIntervalTimeUnit:Nt.MINUTES,endInterval:ie(e?.interval?.endInterval)?e.interval.endInterval:1,endIntervalTimeUnit:ie(e?.interval?.endIntervalTimeUnit)?e.interval.endIntervalTimeUnit:Nt.MINUTES},startIntervalPattern:ie(e?.startIntervalPattern)?e.startIntervalPattern:null,endIntervalPattern:ie(e?.endIntervalPattern)?e.endIntervalPattern:null}}updateValidators(e){const t=this.getTelemetryFromDatabaseConfigForm.get("fetchMode").value,n=this.getTelemetryFromDatabaseConfigForm.get("useMetadataIntervalPatterns").value;t&&t===Gt.ALL?(this.getTelemetryFromDatabaseConfigForm.get("aggregation").setValidators([O.required]),this.getTelemetryFromDatabaseConfigForm.get("orderBy").setValidators([O.required]),this.getTelemetryFromDatabaseConfigForm.get("limit").setValidators([O.required,O.min(2),O.max(1e3)])):(this.getTelemetryFromDatabaseConfigForm.get("aggregation").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("orderBy").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("limit").setValidators([])),n?(this.getTelemetryFromDatabaseConfigForm.get("interval.startInterval").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("interval.startIntervalTimeUnit").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("interval.endInterval").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("interval.endIntervalTimeUnit").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("interval").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("startIntervalPattern").setValidators([O.required,O.pattern(/(?:.|\s)*\S(&:.|\s)*/)]),this.getTelemetryFromDatabaseConfigForm.get("endIntervalPattern").setValidators([O.required,O.pattern(/(?:.|\s)*\S(&:.|\s)*/)])):(this.getTelemetryFromDatabaseConfigForm.get("interval.startInterval").setValidators([O.required,O.min(1),O.max(2147483647)]),this.getTelemetryFromDatabaseConfigForm.get("interval.startIntervalTimeUnit").setValidators([O.required]),this.getTelemetryFromDatabaseConfigForm.get("interval.endInterval").setValidators([O.required,O.min(1),O.max(2147483647)]),this.getTelemetryFromDatabaseConfigForm.get("interval.endIntervalTimeUnit").setValidators([O.required]),this.getTelemetryFromDatabaseConfigForm.get("interval").setValidators([this.intervalValidator()]),this.getTelemetryFromDatabaseConfigForm.get("startIntervalPattern").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("endIntervalPattern").setValidators([])),this.getTelemetryFromDatabaseConfigForm.get("aggregation").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("orderBy").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("limit").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("interval.startInterval").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("interval.startIntervalTimeUnit").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("interval.endInterval").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("interval.endIntervalTimeUnit").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("interval").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("startIntervalPattern").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("endIntervalPattern").updateValueAndValidity({emitEvent:e})}removeKey(e,t){const n=this.getTelemetryFromDatabaseConfigForm.get(t).value,r=n.indexOf(e);r>=0&&(n.splice(r,1),this.getTelemetryFromDatabaseConfigForm.get(t).setValue(n,{emitEvent:!0}))}clearChipGrid(){this.getTelemetryFromDatabaseConfigForm.get("latestTsKeyNames").patchValue([],{emitEvent:!0})}addKey(e,t){const n=e.input;let r=e.value;if((r||"").trim()){r=r.trim();let e=this.getTelemetryFromDatabaseConfigForm.get(t).value;e&&-1!==e.indexOf(r)||(e||(e=[]),e.push(r),this.getTelemetryFromDatabaseConfigForm.get(t).setValue(e,{emitEvent:!0}))}n&&(n.value="")}defaultPaddingEnable(){return this.getTelemetryFromDatabaseConfigForm.get("fetchMode").value===Gt.ALL&&this.getTelemetryFromDatabaseConfigForm.get("aggregation").value===E.NONE}}e("GetTelemetryFromDatabaseConfigComponent",Yn),Yn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Yn,deps:[{token:P.Store},{token:Z.TranslateService},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Yn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Yn,selector:"tb-enrichment-node-get-telemetry-from-database",usesInheritance:!0,ngImport:t,template:'
\n \n
\n help\n \n
\n
\n
tb.rulenode.fetch-interval
\n
\n \n {{ \'tb.rulenode.use-metadata-dynamic-interval\' | translate }}\n \n
\n
\n
\n \n {{ \'tb.rulenode.interval-start\' | translate }}\n \n \n {{ \'tb.rulenode.start-interval-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n {{ \'tb.rulenode.time-unit\' | translate }}\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n \n {{ \'tb.rulenode.interval-end\' | translate }}\n \n \n {{ \'tb.rulenode.end-interval-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n {{ \'tb.rulenode.time-unit\' | translate }}\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n error_outline\n
\n \n {{ \'tb.rulenode.fetch-timeseries-from-to\' | translate:\n {\n startInterval: getTelemetryFromDatabaseConfigForm.get(\'interval.startInterval\').value,\n endInterval: getTelemetryFromDatabaseConfigForm.get(\'interval.endInterval\').value,\n startIntervalTimeUnit: getTelemetryFromDatabaseConfigForm.get(\'interval.startIntervalTimeUnit\').value.toLowerCase(),\n endIntervalTimeUnit: getTelemetryFromDatabaseConfigForm.get(\'interval.endIntervalTimeUnit\').value.toLowerCase()\n } }}\n \n \n {{ "tb.rulenode.fetch-timeseries-from-to-invalid" | translate }}\n \n
\n
\n
\n \n
\n \n {{ \'tb.rulenode.start-interval\' | translate }}\n \n \n {{ \'tb.rulenode.start-interval-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.end-interval\' | translate }}\n \n \n {{ \'tb.rulenode.end-interval-required\' | translate }}\n \n \n \n \n
\n
\n
\n
\n
tb.rulenode.fetch-strategy
\n
\n
\n \n \n {{ data.name }}\n \n \n
\n
\n {{ deduplicationStrategiesHintTranslations.get(getTelemetryFromDatabaseConfigForm.get(\'fetchMode\').value) | translate }}\n
\n
\n
\n \n {{ \'aggregation.function\' | translate }}\n \n \n {{ aggregationTypesTranslations.get(aggregationTypes[aggregation]) | translate }}\n \n \n \n
\n \n {{ "tb.rulenode.order-by-timestamp" | translate }} \n \n \n {{ samplingOrdersTranslate.get(order) | translate }}\n \n \n \n \n {{ "tb.rulenode.limit" | translate }}\n \n {{ "tb.rulenode.limit-hint" | translate }}\n \n {{ \'tb.rulenode.limit-required\' | translate }}\n \n \n {{ \'tb.rulenode.limit-range\' | translate }}\n \n \n {{ \'tb.rulenode.limit-range\' | translate }}\n \n \n
\n
\n
\n
\n',styles:[":host .see-example{display:inline-block}:host .description-block{display:flex;align-items:center;border-radius:6px;border:1px solid #EAEAEA}:host .description-block .description-icon{font-size:24px;height:24px;min-height:24px;width:24px;min-width:24px;line-height:24px;color:#d9d9d9;margin:4px}:host .description-block .description-text{font-size:12px;line-height:16px;letter-spacing:.25px;margin:6px}:host .description-block.error{color:var(--mdc-theme-error, #f44336)}:host .description-block.error .description-icon{color:var(--mdc-theme-error, #f44336)}:host .item-center{align-items:center}:host .item-center .fetch-mod-toggle{width:100%}:host .hint-container{width:100%}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:He.HelpPopupComponent,selector:"[tb-help-popup], [tb-help-popup-content]",inputs:["tb-help-popup","tb-help-popup-content","trigger-text","trigger-style","tb-help-popup-placement","tb-help-popup-style","hintMode"]},{kind:"component",type:Ze.StringItemsListComponent,selector:"tb-string-items-list",inputs:["required","disabled","label","placeholder","hint","requiredText","floatLabel","appearance","editable","subscriptSizing","predefinedValues"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Y.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:te.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:R.FormGroupName,selector:"[formGroupName]",inputs:["formGroupName"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"directive",type:Xe.ToggleOption,selector:"tb-toggle-option",inputs:["value"]},{kind:"component",type:et.ToggleSelectComponent,selector:"tb-toggle-select",inputs:["disabled","selectMediaBreakpoint","appearance","disablePagination"]},{kind:"component",type:ne.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"component",type:Nn,selector:"tb-example-hint",inputs:["hintText","popupHelpLink","textAlign"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Yn,decorators:[{type:n,args:[{selector:"tb-enrichment-node-get-telemetry-from-database",template:'
\n \n
\n help\n \n
\n
\n
tb.rulenode.fetch-interval
\n
\n \n {{ \'tb.rulenode.use-metadata-dynamic-interval\' | translate }}\n \n
\n
\n
\n \n {{ \'tb.rulenode.interval-start\' | translate }}\n \n \n {{ \'tb.rulenode.start-interval-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n {{ \'tb.rulenode.time-unit\' | translate }}\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n \n {{ \'tb.rulenode.interval-end\' | translate }}\n \n \n {{ \'tb.rulenode.end-interval-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n {{ \'tb.rulenode.time-unit\' | translate }}\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n error_outline\n
\n \n {{ \'tb.rulenode.fetch-timeseries-from-to\' | translate:\n {\n startInterval: getTelemetryFromDatabaseConfigForm.get(\'interval.startInterval\').value,\n endInterval: getTelemetryFromDatabaseConfigForm.get(\'interval.endInterval\').value,\n startIntervalTimeUnit: getTelemetryFromDatabaseConfigForm.get(\'interval.startIntervalTimeUnit\').value.toLowerCase(),\n endIntervalTimeUnit: getTelemetryFromDatabaseConfigForm.get(\'interval.endIntervalTimeUnit\').value.toLowerCase()\n } }}\n \n \n {{ "tb.rulenode.fetch-timeseries-from-to-invalid" | translate }}\n \n
\n
\n
\n \n
\n \n {{ \'tb.rulenode.start-interval\' | translate }}\n \n \n {{ \'tb.rulenode.start-interval-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.end-interval\' | translate }}\n \n \n {{ \'tb.rulenode.end-interval-required\' | translate }}\n \n \n \n \n
\n
\n
\n
\n
tb.rulenode.fetch-strategy
\n
\n
\n \n \n {{ data.name }}\n \n \n
\n
\n {{ deduplicationStrategiesHintTranslations.get(getTelemetryFromDatabaseConfigForm.get(\'fetchMode\').value) | translate }}\n
\n
\n
\n \n {{ \'aggregation.function\' | translate }}\n \n \n {{ aggregationTypesTranslations.get(aggregationTypes[aggregation]) | translate }}\n \n \n \n
\n \n {{ "tb.rulenode.order-by-timestamp" | translate }} \n \n \n {{ samplingOrdersTranslate.get(order) | translate }}\n \n \n \n \n {{ "tb.rulenode.limit" | translate }}\n \n {{ "tb.rulenode.limit-hint" | translate }}\n \n {{ \'tb.rulenode.limit-required\' | translate }}\n \n \n {{ \'tb.rulenode.limit-range\' | translate }}\n \n \n {{ \'tb.rulenode.limit-range\' | translate }}\n \n \n
\n
\n
\n
\n',styles:[":host .see-example{display:inline-block}:host .description-block{display:flex;align-items:center;border-radius:6px;border:1px solid #EAEAEA}:host .description-block .description-icon{font-size:24px;height:24px;min-height:24px;width:24px;min-width:24px;line-height:24px;color:#d9d9d9;margin:4px}:host .description-block .description-text{font-size:12px;line-height:16px;letter-spacing:.25px;margin:6px}:host .description-block.error{color:var(--mdc-theme-error, #f44336)}:host .description-block.error .description-icon{color:var(--mdc-theme-error, #f44336)}:host .item-center{align-items:center}:host .item-center .fetch-mod-toggle{width:100%}:host .hint-container{width:100%}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:P.Store},{type:Z.TranslateService},{type:R.FormBuilder}]}});class Wn extends f{constructor(e,t,n){super(e),this.store=e,this.translate=t,this.fb=n}configForm(){return this.originatorAttributesConfigForm}onConfigurationSet(e){this.originatorAttributesConfigForm=this.fb.group({tellFailureIfAbsent:[e.tellFailureIfAbsent,[]],fetchTo:[e.fetchTo,[]],attributesControl:[e.attributesControl,[]]})}prepareInputConfig(e){return se(e)&&(e.attributesControl={clientAttributeNames:ie(e?.clientAttributeNames)?e.clientAttributeNames:[],latestTsKeyNames:ie(e?.latestTsKeyNames)?e.latestTsKeyNames:[],serverAttributeNames:ie(e?.serverAttributeNames)?e.serverAttributeNames:[],sharedAttributeNames:ie(e?.sharedAttributeNames)?e.sharedAttributeNames:[],getLatestValueWithTs:!!ie(e?.getLatestValueWithTs)&&e.getLatestValueWithTs}),{fetchTo:ie(e?.fetchTo)?e.fetchTo:en.METADATA,tellFailureIfAbsent:!!ie(e?.tellFailureIfAbsent)&&e.tellFailureIfAbsent,attributesControl:ie(e?.attributesControl)?e.attributesControl:null}}prepareOutputConfig(e){for(const t of Object.keys(e.attributesControl))e[t]=e.attributesControl[t];return delete e.attributesControl,e}}e("OriginatorAttributesConfigComponent",Wn),Wn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Wn,deps:[{token:P.Store},{token:Z.TranslateService},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Wn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Wn,selector:"tb-enrichment-node-originator-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n
\n
\n
tb.rulenode.originator-attributes
\n
\n tb.rulenode.at-least-one-field-required\n
\n
\n \n \n \n \n
\n
\n \n {{ \'tb.rulenode.tell-failure\' | translate }}\n \n
\n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"component",type:te.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:ne.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"component",type:On,selector:"tb-msg-metadata-chip",inputs:["labelText","translation"]},{kind:"component",type:Kn,selector:"tb-select-attributes",inputs:["popupHelpLink"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Wn,decorators:[{type:n,args:[{selector:"tb-enrichment-node-originator-attributes-config",template:'
\n
\n
\n
tb.rulenode.originator-attributes
\n
\n tb.rulenode.at-least-one-field-required\n
\n
\n \n \n \n \n
\n
\n \n {{ \'tb.rulenode.tell-failure\' | translate }}\n \n
\n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:P.Store},{type:Z.TranslateService},{type:R.FormBuilder}]}});class Zn extends f{constructor(e,t,n){super(e),this.store=e,this.fb=t,this.translate=n,this.originatorFields=[];for(const e of kt)this.originatorFields.push({value:e.value,name:this.translate.instant(e.name)})}configForm(){return this.originatorFieldsConfigForm}prepareOutputConfig(e){return le(e)}prepareInputConfig(e){return{dataMapping:ie(e?.dataMapping)?e.dataMapping:null,ignoreNullStrings:ie(e?.ignoreNullStrings)?e.ignoreNullStrings:null,fetchTo:ie(e?.fetchTo)?e.fetchTo:en.METADATA}}onConfigurationSet(e){this.originatorFieldsConfigForm=this.fb.group({dataMapping:[e.dataMapping,[O.required]],ignoreNullStrings:[e.ignoreNullStrings,[]],fetchTo:[e.fetchTo,[]]})}}e("OriginatorFieldsConfigComponent",Zn),Zn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Zn,deps:[{token:P.Store},{token:R.FormBuilder},{token:Z.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Zn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Zn,selector:"tb-enrichment-node-originator-fields-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n
\n \n {{ \'tb.rulenode.skip-empty-fields\' | translate }}\n \n
\n
\n',dependencies:[{kind:"component",type:te.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:ne.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"component",type:On,selector:"tb-msg-metadata-chip",inputs:["labelText","translation"]},{kind:"component",type:_n,selector:"tb-sv-map-config",inputs:["selectOptions","disabled","labelText","requiredText","targetKeyPrefix","selectText","selectRequiredText","valText","valRequiredText","hintText","popupHelpLink","required"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Zn,decorators:[{type:n,args:[{selector:"tb-enrichment-node-originator-fields-config",template:'
\n \n \n \n \n
\n \n {{ \'tb.rulenode.skip-empty-fields\' | translate }}\n \n
\n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder},{type:Z.TranslateService}]}});class Xn extends f{constructor(e,t,n){super(e),this.store=e,this.fb=t,this.translate=n,this.DataToFetch=Pt,this.msgMetadataLabelTranslations=Ot,this.originatorFields=[],this.fetchToData=[];for(const e of Object.keys(kt))this.originatorFields.push({value:kt[e].value,name:this.translate.instant(kt[e].name)});for(const e of Rt.keys())this.fetchToData.push({value:e,name:this.translate.instant(Rt.get(e))})}configForm(){return this.relatedAttributesConfigForm}prepareOutputConfig(e){e.dataToFetch===Pt.FIELDS?(e.dataMapping=e.svMap,delete e.svMap):(e.dataMapping=e.kvMap,delete e.kvMap);const t={};if(e&&e.dataMapping)for(const n of Object.keys(e.dataMapping))t[n.trim()]=e.dataMapping[n];return e.dataMapping=t,delete e.svMap,delete e.kvMap,le(e)}prepareInputConfig(e){let t,n,r={[k.name.value]:`relatedEntity${this.translate.instant(k.name.name)}`},o={serialNumber:"sn"};return t=ie(e?.telemetry)?e.telemetry?Pt.LATEST_TELEMETRY:Pt.ATTRIBUTES:ie(e?.dataToFetch)?e.dataToFetch:Pt.ATTRIBUTES,n=ie(e?.attrMapping)?e.attrMapping:ie(e?.dataMapping)?e.dataMapping:null,t===Pt.FIELDS?r=n:o=n,{relationsQuery:ie(e?.relationsQuery)?e.relationsQuery:null,dataToFetch:t,svMap:r,kvMap:o,fetchTo:ie(e?.fetchTo)?e.fetchTo:en.METADATA}}selectTranslation(e,t){return this.relatedAttributesConfigForm.get("dataToFetch").value===Pt.LATEST_TELEMETRY?e:t}onConfigurationSet(e){this.relatedAttributesConfigForm=this.fb.group({relationsQuery:[e.relationsQuery,[O.required]],dataToFetch:[e.dataToFetch,[]],kvMap:[e.kvMap,[O.required]],svMap:[e.svMap,[O.required]],fetchTo:[e.fetchTo,[]]})}validatorTriggers(){return["dataToFetch"]}updateValidators(e){this.relatedAttributesConfigForm.get("dataToFetch").value===Pt.FIELDS?(this.relatedAttributesConfigForm.get("svMap").enable({emitEvent:!1}),this.relatedAttributesConfigForm.get("kvMap").disable({emitEvent:!1}),this.relatedAttributesConfigForm.get("svMap").updateValueAndValidity()):(this.relatedAttributesConfigForm.get("svMap").disable({emitEvent:!1}),this.relatedAttributesConfigForm.get("kvMap").enable({emitEvent:!1}),this.relatedAttributesConfigForm.get("kvMap").updateValueAndValidity())}}e("RelatedAttributesConfigComponent",Xn),Xn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Xn,deps:[{token:P.Store},{token:R.FormBuilder},{token:Z.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Xn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Xn,selector:"tb-enrichment-node-related-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n
\n
tb.rulenode.data-to-fetch
\n \n \n {{ data.name }}\n \n \n \n \n \n \n \n \n
\n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"directive",type:Xe.ToggleOption,selector:"tb-toggle-option",inputs:["value"]},{kind:"component",type:et.ToggleSelectComponent,selector:"tb-toggle-select",inputs:["disabled","selectMediaBreakpoint","appearance","disablePagination"]},{kind:"component",type:Sn,selector:"tb-kv-map-config",inputs:["disabled","uniqueKeyValuePairValidator","labelText","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","popupHelpLink","required"]},{kind:"component",type:An,selector:"tb-relations-query-config",inputs:["disabled","required"]},{kind:"component",type:On,selector:"tb-msg-metadata-chip",inputs:["labelText","translation"]},{kind:"component",type:_n,selector:"tb-sv-map-config",inputs:["selectOptions","disabled","labelText","requiredText","targetKeyPrefix","selectText","selectRequiredText","valText","valRequiredText","hintText","popupHelpLink","required"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Xn,decorators:[{type:n,args:[{selector:"tb-enrichment-node-related-attributes-config",template:'
\n \n \n
\n
tb.rulenode.data-to-fetch
\n \n \n {{ data.name }}\n \n \n \n \n \n \n \n \n
\n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder},{type:Z.TranslateService}]}});class er extends f{constructor(e,t,n){super(e),this.store=e,this.fb=t,this.translate=n,this.fetchToData=[],this.DataToFetch=Pt;for(const e of Rt.keys())e!==Pt.FIELDS&&this.fetchToData.push({value:e,name:this.translate.instant(Rt.get(e))})}configForm(){return this.tenantAttributesConfigForm}prepareInputConfig(e){let t,n;return t=ie(e?.telemetry)?e.telemetry?Pt.LATEST_TELEMETRY:Pt.ATTRIBUTES:ie(e?.dataToFetch)?e.dataToFetch:Pt.ATTRIBUTES,n=ie(e?.attrMapping)?e.attrMapping:ie(e?.dataMapping)?e.dataMapping:null,{dataToFetch:t,dataMapping:n,fetchTo:ie(e?.fetchTo)?e.fetchTo:en.METADATA}}selectTranslation(e,t){return this.tenantAttributesConfigForm.get("dataToFetch").value===Pt.LATEST_TELEMETRY?e:t}onConfigurationSet(e){this.tenantAttributesConfigForm=this.fb.group({dataToFetch:[e.dataToFetch,[]],dataMapping:[e.dataMapping,[O.required]],fetchTo:[e.fetchTo,[]]})}}e("TenantAttributesConfigComponent",er),er.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:er,deps:[{token:P.Store},{token:R.FormBuilder},{token:Z.TranslateService}],target:t.ɵɵFactoryTarget.Component}),er.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:er,selector:"tb-enrichment-node-tenant-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n
tb.rulenode.mapping-of-tenant
\n
\n
\n \n \n {{ data.name }}\n \n \n
\n
\n \n \n \n \n
\n',styles:[":host .fetch-to-data-toggle{max-width:420px;width:100%}\n"],dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:W.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"directive",type:Xe.ToggleOption,selector:"tb-toggle-option",inputs:["value"]},{kind:"component",type:et.ToggleSelectComponent,selector:"tb-toggle-select",inputs:["disabled","selectMediaBreakpoint","appearance","disablePagination"]},{kind:"component",type:Sn,selector:"tb-kv-map-config",inputs:["disabled","uniqueKeyValuePairValidator","labelText","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","popupHelpLink","required"]},{kind:"component",type:On,selector:"tb-msg-metadata-chip",inputs:["labelText","translation"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:er,decorators:[{type:n,args:[{selector:"tb-enrichment-node-tenant-attributes-config",template:'
\n
tb.rulenode.mapping-of-tenant
\n
\n
\n \n \n {{ data.name }}\n \n \n
\n
\n \n \n \n \n
\n',styles:[":host .fetch-to-data-toggle{max-width:420px;width:100%}\n"]}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder},{type:Z.TranslateService}]}});class tr extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.fetchDeviceCredentialsConfigForm}prepareInputConfig(e){return{fetchTo:ie(e?.fetchTo)?e.fetchTo:en.METADATA}}onConfigurationSet(e){this.fetchDeviceCredentialsConfigForm=this.fb.group({fetchTo:[e.fetchTo,[]]})}}e("FetchDeviceCredentialsConfigComponent",tr),tr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:tr,deps:[{token:P.Store},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),tr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:tr,selector:"./tb-enrichment-node-fetch-device-credentials-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n
\n',dependencies:[{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:On,selector:"tb-msg-metadata-chip",inputs:["labelText","translation"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:tr,decorators:[{type:n,args:[{selector:"./tb-enrichment-node-fetch-device-credentials-config",template:'
\n \n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder}]}});class nr{}e("RulenodeCoreConfigEnrichmentModule",nr),nr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:nr,deps:[],target:t.ɵɵFactoryTarget.NgModule}),nr.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.10",ngImport:t,type:nr,declarations:[$n,Jn,Qn,Wn,Zn,Yn,Xn,er,jn,tr],imports:[$,M,Un],exports:[$n,Jn,Qn,Wn,Zn,Yn,Xn,er,jn,tr]}),nr.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:nr,imports:[$,M,Un]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:nr,decorators:[{type:c,args:[{declarations:[$n,Jn,Qn,Wn,Zn,Yn,Xn,er,jn,tr],imports:[$,M,Un],exports:[$n,Jn,Qn,Wn,Zn,Yn,Xn,er,jn,tr]}]}]});class rr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.allAzureIotHubCredentialsTypes=Ht,this.azureIotHubCredentialsTypeTranslationsMap=jt}configForm(){return this.azureIotHubConfigForm}onConfigurationSet(e){this.azureIotHubConfigForm=this.fb.group({topicPattern:[e?e.topicPattern:null,[O.required]],host:[e?e.host:null,[O.required]],port:[e?e.port:null,[O.required,O.min(1),O.max(65535)]],connectTimeoutSec:[e?e.connectTimeoutSec:null,[O.required,O.min(1),O.max(200)]],clientId:[e?e.clientId:null,[O.required]],cleanSession:[!!e&&e.cleanSession,[]],ssl:[!!e&&e.ssl,[]],credentials:this.fb.group({type:[e&&e.credentials?e.credentials.type:null,[O.required]],sasKey:[e&&e.credentials?e.credentials.sasKey:null,[]],caCert:[e&&e.credentials?e.credentials.caCert:null,[]],caCertFileName:[e&&e.credentials?e.credentials.caCertFileName:null,[]],privateKey:[e&&e.credentials?e.credentials.privateKey:null,[]],privateKeyFileName:[e&&e.credentials?e.credentials.privateKeyFileName:null,[]],cert:[e&&e.credentials?e.credentials.cert:null,[]],certFileName:[e&&e.credentials?e.credentials.certFileName:null,[]],password:[e&&e.credentials?e.credentials.password:null,[]]})})}prepareOutputConfig(e){const t=e.credentials.type;return"sas"===t&&(e.credentials={type:t,sasKey:e.credentials.sasKey,caCert:e.credentials.caCert,caCertFileName:e.credentials.caCertFileName}),e}validatorTriggers(){return["credentials.type"]}updateValidators(e){const t=this.azureIotHubConfigForm.get("credentials"),n=t.get("type").value;switch(e&&t.reset({type:n},{emitEvent:!1}),t.get("sasKey").setValidators([]),t.get("privateKey").setValidators([]),t.get("privateKeyFileName").setValidators([]),t.get("cert").setValidators([]),t.get("certFileName").setValidators([]),n){case"sas":t.get("sasKey").setValidators([O.required]);break;case"cert.PEM":t.get("privateKey").setValidators([O.required]),t.get("privateKeyFileName").setValidators([O.required]),t.get("cert").setValidators([O.required]),t.get("certFileName").setValidators([O.required])}t.get("sasKey").updateValueAndValidity({emitEvent:e}),t.get("privateKey").updateValueAndValidity({emitEvent:e}),t.get("privateKeyFileName").updateValueAndValidity({emitEvent:e}),t.get("cert").updateValueAndValidity({emitEvent:e}),t.get("certFileName").updateValueAndValidity({emitEvent:e})}}e("AzureIotHubConfigComponent",rr),rr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:rr,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),rr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:rr,selector:"tb-external-node-azure-iot-hub-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.topic\n \n \n {{ \'tb.rulenode.topic-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.hostname\n \n \n {{ \'tb.rulenode.hostname-required\' | translate }}\n \n \n \n tb.rulenode.device-id\n \n \n {{ \'tb.rulenode.device-id-required\' | translate }}\n \n \n \n \n \n tb.rulenode.credentials\n \n {{ azureIotHubCredentialsTypeTranslationsMap.get(azureIotHubConfigForm.get(\'credentials.type\').value) | translate }}\n \n \n
\n \n tb.rulenode.credentials-type\n \n \n {{ azureIotHubCredentialsTypeTranslationsMap.get(credentialsType) | translate }}\n \n \n \n {{ \'tb.rulenode.credentials-type-required\' | translate }}\n \n \n
\n \n \n \n \n tb.rulenode.sas-key\n \n \n \n {{ \'tb.rulenode.sas-key-required\' | translate }}\n \n \n \n \n \n \n \n \n \n \n \n \n \n tb.rulenode.private-key-password\n \n \n \n \n
\n
\n
\n
\n
\n',styles:[":host .tb-mqtt-credentials-panel-group{margin:0 6px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:H.NgSwitch,selector:"[ngSwitch]",inputs:["ngSwitch"]},{kind:"directive",type:H.NgSwitchCase,selector:"[ngSwitchCase]",inputs:["ngSwitchCase"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Y.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:Je.MatAccordion,selector:"mat-accordion",inputs:["multi","hideToggle","displayMode","togglePosition"],exportAs:["matAccordion"]},{kind:"component",type:Je.MatExpansionPanel,selector:"mat-expansion-panel",inputs:["disabled","expanded","hideToggle","togglePosition"],outputs:["opened","closed","expandedChange","afterExpand","afterCollapse"],exportAs:["matExpansionPanel"]},{kind:"component",type:Je.MatExpansionPanelHeader,selector:"mat-expansion-panel-header",inputs:["tabIndex","expandedHeight","collapsedHeight"]},{kind:"directive",type:Je.MatExpansionPanelTitle,selector:"mat-panel-title"},{kind:"directive",type:Je.MatExpansionPanelDescription,selector:"mat-panel-description"},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:R.FormGroupName,selector:"[formGroupName]",inputs:["formGroupName"]},{kind:"component",type:Ye.FileInputComponent,selector:"tb-file-input",inputs:["label","hint","accept","noFileText","inputId","allowedExtensions","dropLabel","contentConvertFunction","required","requiredAsError","disabled","existingFileName","readAsBinary","workFromFileObj","multipleFile"],outputs:["fileNameChanged"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:We.TogglePasswordComponent,selector:"tb-toggle-password"},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:rr,decorators:[{type:n,args:[{selector:"tb-external-node-azure-iot-hub-config",template:'
\n \n tb.rulenode.topic\n \n \n {{ \'tb.rulenode.topic-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.hostname\n \n \n {{ \'tb.rulenode.hostname-required\' | translate }}\n \n \n \n tb.rulenode.device-id\n \n \n {{ \'tb.rulenode.device-id-required\' | translate }}\n \n \n \n \n \n tb.rulenode.credentials\n \n {{ azureIotHubCredentialsTypeTranslationsMap.get(azureIotHubConfigForm.get(\'credentials.type\').value) | translate }}\n \n \n
\n \n tb.rulenode.credentials-type\n \n \n {{ azureIotHubCredentialsTypeTranslationsMap.get(credentialsType) | translate }}\n \n \n \n {{ \'tb.rulenode.credentials-type-required\' | translate }}\n \n \n
\n \n \n \n \n tb.rulenode.sas-key\n \n \n \n {{ \'tb.rulenode.sas-key-required\' | translate }}\n \n \n \n \n \n \n \n \n \n \n \n \n \n tb.rulenode.private-key-password\n \n \n \n \n
\n
\n
\n
\n
\n',styles:[":host .tb-mqtt-credentials-panel-group{margin:0 6px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class or extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.ackValues=["all","-1","0","1"],this.ToByteStandartCharsetTypesValues=Qt,this.ToByteStandartCharsetTypeTranslationMap=Jt}configForm(){return this.kafkaConfigForm}onConfigurationSet(e){this.kafkaConfigForm=this.fb.group({topicPattern:[e?e.topicPattern:null,[O.required]],keyPattern:[e?e.keyPattern:null],bootstrapServers:[e?e.bootstrapServers:null,[O.required]],retries:[e?e.retries:null,[O.min(0)]],batchSize:[e?e.batchSize:null,[O.min(0)]],linger:[e?e.linger:null,[O.min(0)]],bufferMemory:[e?e.bufferMemory:null,[O.min(0)]],acks:[e?e.acks:null,[O.required]],keySerializer:[e?e.keySerializer:null,[O.required]],valueSerializer:[e?e.valueSerializer:null,[O.required]],otherProperties:[e?e.otherProperties:null,[]],addMetadataKeyValuesAsKafkaHeaders:[!!e&&e.addMetadataKeyValuesAsKafkaHeaders,[]],kafkaHeadersCharset:[e?e.kafkaHeadersCharset:null,[]]})}validatorTriggers(){return["addMetadataKeyValuesAsKafkaHeaders"]}updateValidators(e){this.kafkaConfigForm.get("addMetadataKeyValuesAsKafkaHeaders").value?this.kafkaConfigForm.get("kafkaHeadersCharset").setValidators([O.required]):this.kafkaConfigForm.get("kafkaHeadersCharset").setValidators([]),this.kafkaConfigForm.get("kafkaHeadersCharset").updateValueAndValidity({emitEvent:e})}}e("KafkaConfigComponent",or),or.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:or,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),or.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:or,selector:"tb-external-node-kafka-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.topic-pattern\n \n \n {{ \'tb.rulenode.topic-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.key-pattern\n \n tb.rulenode.general-pattern-hint\n \n
tb.rulenode.key-pattern-hint
\n \n tb.rulenode.bootstrap-servers\n \n \n {{ \'tb.rulenode.bootstrap-servers-required\' | translate }}\n \n \n \n tb.rulenode.retries\n \n \n {{ \'tb.rulenode.min-retries-message\' | translate }}\n \n \n \n tb.rulenode.batch-size-bytes\n \n \n {{ \'tb.rulenode.min-batch-size-bytes-message\' | translate }}\n \n \n \n tb.rulenode.linger-ms\n \n \n {{ \'tb.rulenode.min-linger-ms-message\' | translate }}\n \n \n \n tb.rulenode.buffer-memory-bytes\n \n \n {{ \'tb.rulenode.min-buffer-memory-bytes-message\' | translate }}\n \n \n \n tb.rulenode.acks\n \n \n {{ ackValue }}\n \n \n \n \n tb.rulenode.key-serializer\n \n \n {{ \'tb.rulenode.key-serializer-required\' | translate }}\n \n \n \n tb.rulenode.value-serializer\n \n \n {{ \'tb.rulenode.value-serializer-required\' | translate }}\n \n \n \n \n \n \n {{ \'tb.rulenode.add-metadata-key-values-as-kafka-headers\' | translate }}\n \n
tb.rulenode.add-metadata-key-values-as-kafka-headers-hint
\n \n tb.rulenode.charset-encoding\n \n \n {{ ToByteStandartCharsetTypeTranslationMap.get(charset) | translate }}\n \n \n \n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Q.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:hn,selector:"tb-kv-map-config-old",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:or,decorators:[{type:n,args:[{selector:"tb-external-node-kafka-config",template:'
\n \n tb.rulenode.topic-pattern\n \n \n {{ \'tb.rulenode.topic-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.key-pattern\n \n tb.rulenode.general-pattern-hint\n \n
tb.rulenode.key-pattern-hint
\n \n tb.rulenode.bootstrap-servers\n \n \n {{ \'tb.rulenode.bootstrap-servers-required\' | translate }}\n \n \n \n tb.rulenode.retries\n \n \n {{ \'tb.rulenode.min-retries-message\' | translate }}\n \n \n \n tb.rulenode.batch-size-bytes\n \n \n {{ \'tb.rulenode.min-batch-size-bytes-message\' | translate }}\n \n \n \n tb.rulenode.linger-ms\n \n \n {{ \'tb.rulenode.min-linger-ms-message\' | translate }}\n \n \n \n tb.rulenode.buffer-memory-bytes\n \n \n {{ \'tb.rulenode.min-buffer-memory-bytes-message\' | translate }}\n \n \n \n tb.rulenode.acks\n \n \n {{ ackValue }}\n \n \n \n \n tb.rulenode.key-serializer\n \n \n {{ \'tb.rulenode.key-serializer-required\' | translate }}\n \n \n \n tb.rulenode.value-serializer\n \n \n {{ \'tb.rulenode.value-serializer-required\' | translate }}\n \n \n \n \n \n \n {{ \'tb.rulenode.add-metadata-key-values-as-kafka-headers\' | translate }}\n \n
tb.rulenode.add-metadata-key-values-as-kafka-headers-hint
\n \n tb.rulenode.charset-encoding\n \n \n {{ ToByteStandartCharsetTypeTranslationMap.get(charset) | translate }}\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class ar extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.mqttConfigForm}onConfigurationSet(e){this.mqttConfigForm=this.fb.group({topicPattern:[e?e.topicPattern:null,[O.required]],host:[e?e.host:null,[O.required]],port:[e?e.port:null,[O.required,O.min(1),O.max(65535)]],connectTimeoutSec:[e?e.connectTimeoutSec:null,[O.required,O.min(1),O.max(200)]],clientId:[e?e.clientId:null,[]],appendClientIdSuffix:[{value:!!e&&e.appendClientIdSuffix,disabled:!(e&&me(e.clientId))},[]],cleanSession:[!!e&&e.cleanSession,[]],retainedMessage:[!!e&&e.retainedMessage,[]],ssl:[!!e&&e.ssl,[]],credentials:[e?e.credentials:null,[]]})}updateValidators(e){me(this.mqttConfigForm.get("clientId").value)?this.mqttConfigForm.get("appendClientIdSuffix").enable({emitEvent:!1}):this.mqttConfigForm.get("appendClientIdSuffix").disable({emitEvent:!1}),this.mqttConfigForm.get("appendClientIdSuffix").updateValueAndValidity({emitEvent:e})}validatorTriggers(){return["clientId"]}}e("MqttConfigComponent",ar),ar.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ar,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),ar.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:ar,selector:"tb-external-node-mqtt-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.topic-pattern\n \n \n {{ \'tb.rulenode.topic-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n
\n \n tb.rulenode.host\n \n \n {{ \'tb.rulenode.host-required\' | translate }}\n \n \n \n tb.rulenode.port\n \n \n {{ \'tb.rulenode.port-required\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n \n tb.rulenode.connect-timeout\n \n \n {{ \'tb.rulenode.connect-timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.connect-timeout-range\' | translate }}\n \n \n {{ \'tb.rulenode.connect-timeout-range\' | translate }}\n \n \n
\n \n tb.rulenode.client-id\n \n {{\'tb.rulenode.client-id-hint\' | translate}}\n \n \n {{ \'tb.rulenode.append-client-id-suffix\' | translate }}\n \n
{{ "tb.rulenode.client-id-suffix-hint" | translate }}
\n \n {{ \'tb.rulenode.clean-session\' | translate }}\n \n \n {{ "tb.rulenode.retained-message" | translate }}\n \n \n {{ \'tb.rulenode.enable-ssl\' | translate }}\n \n \n
\n',styles:[":host .tb-mqtt-credentials-panel-group{margin:0 6px}\n"],dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Q.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:En,selector:"tb-credentials-config",inputs:["required","disableCertPemCredentials","passwordFieldRequired"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ar,decorators:[{type:n,args:[{selector:"tb-external-node-mqtt-config",template:'
\n \n tb.rulenode.topic-pattern\n \n \n {{ \'tb.rulenode.topic-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n
\n \n tb.rulenode.host\n \n \n {{ \'tb.rulenode.host-required\' | translate }}\n \n \n \n tb.rulenode.port\n \n \n {{ \'tb.rulenode.port-required\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n \n tb.rulenode.connect-timeout\n \n \n {{ \'tb.rulenode.connect-timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.connect-timeout-range\' | translate }}\n \n \n {{ \'tb.rulenode.connect-timeout-range\' | translate }}\n \n \n
\n \n tb.rulenode.client-id\n \n {{\'tb.rulenode.client-id-hint\' | translate}}\n \n \n {{ \'tb.rulenode.append-client-id-suffix\' | translate }}\n \n
{{ "tb.rulenode.client-id-suffix-hint" | translate }}
\n \n {{ \'tb.rulenode.clean-session\' | translate }}\n \n \n {{ "tb.rulenode.retained-message" | translate }}\n \n \n {{ \'tb.rulenode.enable-ssl\' | translate }}\n \n \n
\n',styles:[":host .tb-mqtt-credentials-panel-group{margin:0 6px}\n"]}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class ir extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.notificationType=D,this.entityType=F}configForm(){return this.notificationConfigForm}onConfigurationSet(e){this.notificationConfigForm=this.fb.group({templateId:[e?e.templateId:null,[O.required]],targets:[e?e.targets:[],[O.required]]})}}e("NotificationConfigComponent",ir),ir.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ir,deps:[{token:P.Store},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),ir.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:ir,selector:"tb-external-node-notification-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n
\n',dependencies:[{kind:"component",type:tt.EntityListComponent,selector:"tb-entity-list",inputs:["entityType","subType","labelText","placeholderText","requiredText","required","disabled","subscriptSizing","hint"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:nt.TemplateAutocompleteComponent,selector:"tb-template-autocomplete",inputs:["required","allowCreate","allowEdit","disabled","notificationTypes"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ir,decorators:[{type:n,args:[{selector:"tb-external-node-notification-config",template:'
\n \n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder}]}});class lr extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.pubSubConfigForm}onConfigurationSet(e){this.pubSubConfigForm=this.fb.group({projectId:[e?e.projectId:null,[O.required]],topicName:[e?e.topicName:null,[O.required]],serviceAccountKey:[e?e.serviceAccountKey:null,[O.required]],serviceAccountKeyFileName:[e?e.serviceAccountKeyFileName:null,[O.required]],messageAttributes:[e?e.messageAttributes:null,[]]})}}e("PubSubConfigComponent",lr),lr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:lr,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),lr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:lr,selector:"tb-external-node-pub-sub-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.gcp-project-id\n \n \n {{ \'tb.rulenode.gcp-project-id-required\' | translate }}\n \n \n \n tb.rulenode.pubsub-topic-name\n \n \n {{ \'tb.rulenode.pubsub-topic-name-required\' | translate }}\n \n \n \n \n \n
\n \n \n
\n',dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:Ye.FileInputComponent,selector:"tb-file-input",inputs:["label","hint","accept","noFileText","inputId","allowedExtensions","dropLabel","contentConvertFunction","required","requiredAsError","disabled","existingFileName","readAsBinary","workFromFileObj","multipleFile"],outputs:["fileNameChanged"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:hn,selector:"tb-kv-map-config-old",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:he.SafePipe,name:"safe"},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:lr,decorators:[{type:n,args:[{selector:"tb-external-node-pub-sub-config",template:'
\n \n tb.rulenode.gcp-project-id\n \n \n {{ \'tb.rulenode.gcp-project-id-required\' | translate }}\n \n \n \n tb.rulenode.pubsub-topic-name\n \n \n {{ \'tb.rulenode.pubsub-topic-name-required\' | translate }}\n \n \n \n \n \n
\n \n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class sr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.messageProperties=[null,"BASIC","TEXT_PLAIN","MINIMAL_BASIC","MINIMAL_PERSISTENT_BASIC","PERSISTENT_BASIC","PERSISTENT_TEXT_PLAIN"]}configForm(){return this.rabbitMqConfigForm}onConfigurationSet(e){this.rabbitMqConfigForm=this.fb.group({exchangeNamePattern:[e?e.exchangeNamePattern:null,[]],routingKeyPattern:[e?e.routingKeyPattern:null,[]],messageProperties:[e?e.messageProperties:null,[]],host:[e?e.host:null,[O.required]],port:[e?e.port:null,[O.required,O.min(1),O.max(65535)]],virtualHost:[e?e.virtualHost:null,[]],username:[e?e.username:null,[]],password:[e?e.password:null,[]],automaticRecoveryEnabled:[!!e&&e.automaticRecoveryEnabled,[]],connectionTimeout:[e?e.connectionTimeout:null,[O.min(0)]],handshakeTimeout:[e?e.handshakeTimeout:null,[O.min(0)]],clientProperties:[e?e.clientProperties:null,[]]})}}e("RabbitMqConfigComponent",sr),sr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:sr,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),sr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:sr,selector:"tb-external-node-rabbit-mq-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.exchange-name-pattern\n \n \n \n tb.rulenode.routing-key-pattern\n \n \n \n tb.rulenode.message-properties\n \n \n {{ property }}\n \n \n \n
\n \n tb.rulenode.host\n \n \n {{ \'tb.rulenode.host-required\' | translate }}\n \n \n \n tb.rulenode.port\n \n \n {{ \'tb.rulenode.port-required\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n
\n \n tb.rulenode.virtual-host\n \n \n \n tb.rulenode.username\n \n \n \n tb.rulenode.password\n \n \n \n \n {{ \'tb.rulenode.automatic-recovery\' | translate }}\n \n \n tb.rulenode.connection-timeout-ms\n \n \n {{ \'tb.rulenode.min-connection-timeout-ms-message\' | translate }}\n \n \n \n tb.rulenode.handshake-timeout-ms\n \n \n {{ \'tb.rulenode.min-handshake-timeout-ms-message\' | translate }}\n \n \n \n \n \n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Q.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Y.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:We.TogglePasswordComponent,selector:"tb-toggle-password"},{kind:"component",type:hn,selector:"tb-kv-map-config-old",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:sr,decorators:[{type:n,args:[{selector:"tb-external-node-rabbit-mq-config",template:'
\n \n tb.rulenode.exchange-name-pattern\n \n \n \n tb.rulenode.routing-key-pattern\n \n \n \n tb.rulenode.message-properties\n \n \n {{ property }}\n \n \n \n
\n \n tb.rulenode.host\n \n \n {{ \'tb.rulenode.host-required\' | translate }}\n \n \n \n tb.rulenode.port\n \n \n {{ \'tb.rulenode.port-required\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n
\n \n tb.rulenode.virtual-host\n \n \n \n tb.rulenode.username\n \n \n \n tb.rulenode.password\n \n \n \n \n {{ \'tb.rulenode.automatic-recovery\' | translate }}\n \n \n tb.rulenode.connection-timeout-ms\n \n \n {{ \'tb.rulenode.min-connection-timeout-ms-message\' | translate }}\n \n \n \n tb.rulenode.handshake-timeout-ms\n \n \n {{ \'tb.rulenode.min-handshake-timeout-ms-message\' | translate }}\n \n \n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class mr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.proxySchemes=["http","https"],this.httpRequestTypes=Object.keys($t)}configForm(){return this.restApiCallConfigForm}onConfigurationSet(e){this.restApiCallConfigForm=this.fb.group({restEndpointUrlPattern:[e?e.restEndpointUrlPattern:null,[O.required]],requestMethod:[e?e.requestMethod:null,[O.required]],useSimpleClientHttpFactory:[!!e&&e.useSimpleClientHttpFactory,[]],parseToPlainText:[!!e&&e.parseToPlainText,[]],ignoreRequestBody:[!!e&&e.ignoreRequestBody,[]],enableProxy:[!!e&&e.enableProxy,[]],useSystemProxyProperties:[!!e&&e.enableProxy,[]],proxyScheme:[e?e.proxyHost:null,[]],proxyHost:[e?e.proxyHost:null,[]],proxyPort:[e?e.proxyPort:null,[]],proxyUser:[e?e.proxyUser:null,[]],proxyPassword:[e?e.proxyPassword:null,[]],readTimeoutMs:[e?e.readTimeoutMs:null,[]],maxParallelRequestsCount:[e?e.maxParallelRequestsCount:null,[O.min(0)]],headers:[e?e.headers:null,[]],useRedisQueueForMsgPersistence:[!!e&&e.useRedisQueueForMsgPersistence,[]],trimQueue:[!!e&&e.trimQueue,[]],maxQueueSize:[e?e.maxQueueSize:null,[]],credentials:[e?e.credentials:null,[]]})}validatorTriggers(){return["useSimpleClientHttpFactory","useRedisQueueForMsgPersistence","enableProxy","useSystemProxyProperties"]}updateValidators(e){const t=this.restApiCallConfigForm.get("useSimpleClientHttpFactory").value,n=this.restApiCallConfigForm.get("useRedisQueueForMsgPersistence").value,r=this.restApiCallConfigForm.get("enableProxy").value,o=this.restApiCallConfigForm.get("useSystemProxyProperties").value;r&&!o?(this.restApiCallConfigForm.get("proxyHost").setValidators(r?[O.required]:[]),this.restApiCallConfigForm.get("proxyPort").setValidators(r?[O.required,O.min(1),O.max(65535)]:[])):(this.restApiCallConfigForm.get("proxyHost").setValidators([]),this.restApiCallConfigForm.get("proxyPort").setValidators([]),t?this.restApiCallConfigForm.get("readTimeoutMs").setValidators([]):this.restApiCallConfigForm.get("readTimeoutMs").setValidators([O.min(0)])),n?this.restApiCallConfigForm.get("maxQueueSize").setValidators([O.min(0)]):this.restApiCallConfigForm.get("maxQueueSize").setValidators([]),this.restApiCallConfigForm.get("readTimeoutMs").updateValueAndValidity({emitEvent:e}),this.restApiCallConfigForm.get("maxQueueSize").updateValueAndValidity({emitEvent:e}),this.restApiCallConfigForm.get("proxyHost").updateValueAndValidity({emitEvent:e}),this.restApiCallConfigForm.get("proxyPort").updateValueAndValidity({emitEvent:e}),this.restApiCallConfigForm.get("credentials").updateValueAndValidity({emitEvent:e})}}e("RestApiCallConfigComponent",mr),mr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:mr,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),mr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:mr,selector:"tb-external-node-rest-api-call-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.endpoint-url-pattern\n \n \n {{ \'tb.rulenode.endpoint-url-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.request-method\n \n \n {{ requestType }}\n \n \n \n \n {{ \'tb.rulenode.enable-proxy\' | translate }}\n \n \n {{ \'tb.rulenode.use-simple-client-http-factory\' | translate }}\n \n \n {{ \'tb.rulenode.parse-to-plain-text\' | translate }}\n \n
tb.rulenode.parse-to-plain-text-hint
\n \n {{ \'tb.rulenode.ignore-request-body\' | translate }}\n \n
\n \n {{ \'tb.rulenode.use-system-proxy-properties\' | translate }}\n \n
\n
\n \n tb.rulenode.proxy-scheme\n \n \n {{ proxyScheme }}\n \n \n \n \n tb.rulenode.proxy-host\n \n \n {{ \'tb.rulenode.proxy-host-required\' | translate }}\n \n \n \n tb.rulenode.proxy-port\n \n \n {{ \'tb.rulenode.proxy-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.proxy-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.proxy-user\n \n \n \n tb.rulenode.proxy-password\n \n \n
\n
\n \n tb.rulenode.read-timeout\n \n tb.rulenode.read-timeout-hint\n \n \n tb.rulenode.max-parallel-requests-count\n \n tb.rulenode.max-parallel-requests-count-hint\n \n \n
\n \n \n \n {{ \'tb.rulenode.use-redis-queue\' | translate }}\n \n
\n \n {{ \'tb.rulenode.trim-redis-queue\' | translate }}\n \n \n tb.rulenode.redis-queue-max-size\n \n \n
\n \n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Q.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:En,selector:"tb-credentials-config",inputs:["required","disableCertPemCredentials","passwordFieldRequired"]},{kind:"component",type:hn,selector:"tb-kv-map-config-old",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:he.SafePipe,name:"safe"},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:mr,decorators:[{type:n,args:[{selector:"tb-external-node-rest-api-call-config",template:'
\n \n tb.rulenode.endpoint-url-pattern\n \n \n {{ \'tb.rulenode.endpoint-url-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.request-method\n \n \n {{ requestType }}\n \n \n \n \n {{ \'tb.rulenode.enable-proxy\' | translate }}\n \n \n {{ \'tb.rulenode.use-simple-client-http-factory\' | translate }}\n \n \n {{ \'tb.rulenode.parse-to-plain-text\' | translate }}\n \n
tb.rulenode.parse-to-plain-text-hint
\n \n {{ \'tb.rulenode.ignore-request-body\' | translate }}\n \n
\n \n {{ \'tb.rulenode.use-system-proxy-properties\' | translate }}\n \n
\n
\n \n tb.rulenode.proxy-scheme\n \n \n {{ proxyScheme }}\n \n \n \n \n tb.rulenode.proxy-host\n \n \n {{ \'tb.rulenode.proxy-host-required\' | translate }}\n \n \n \n tb.rulenode.proxy-port\n \n \n {{ \'tb.rulenode.proxy-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.proxy-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.proxy-user\n \n \n \n tb.rulenode.proxy-password\n \n \n
\n
\n \n tb.rulenode.read-timeout\n \n tb.rulenode.read-timeout-hint\n \n \n tb.rulenode.max-parallel-requests-count\n \n tb.rulenode.max-parallel-requests-count-hint\n \n \n
\n \n \n \n {{ \'tb.rulenode.use-redis-queue\' | translate }}\n \n
\n \n {{ \'tb.rulenode.trim-redis-queue\' | translate }}\n \n \n tb.rulenode.redis-queue-max-size\n \n \n
\n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class pr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.smtpProtocols=["smtp","smtps"],this.tlsVersions=["TLSv1","TLSv1.1","TLSv1.2","TLSv1.3"]}configForm(){return this.sendEmailConfigForm}onConfigurationSet(e){this.sendEmailConfigForm=this.fb.group({useSystemSmtpSettings:[!!e&&e.useSystemSmtpSettings,[]],smtpProtocol:[e?e.smtpProtocol:null,[]],smtpHost:[e?e.smtpHost:null,[]],smtpPort:[e?e.smtpPort:null,[]],timeout:[e?e.timeout:null,[]],enableTls:[!!e&&e.enableTls,[]],tlsVersion:[e?e.tlsVersion:null,[]],enableProxy:[!!e&&e.enableProxy,[]],proxyHost:[e?e.proxyHost:null,[]],proxyPort:[e?e.proxyPort:null,[]],proxyUser:[e?e.proxyUser:null,[]],proxyPassword:[e?e.proxyPassword:null,[]],username:[e?e.username:null,[]],password:[e?e.password:null,[]]})}validatorTriggers(){return["useSystemSmtpSettings","enableProxy"]}updateValidators(e){const t=this.sendEmailConfigForm.get("useSystemSmtpSettings").value,n=this.sendEmailConfigForm.get("enableProxy").value;t?(this.sendEmailConfigForm.get("smtpProtocol").setValidators([]),this.sendEmailConfigForm.get("smtpHost").setValidators([]),this.sendEmailConfigForm.get("smtpPort").setValidators([]),this.sendEmailConfigForm.get("timeout").setValidators([]),this.sendEmailConfigForm.get("proxyHost").setValidators([]),this.sendEmailConfigForm.get("proxyPort").setValidators([])):(this.sendEmailConfigForm.get("smtpProtocol").setValidators([O.required]),this.sendEmailConfigForm.get("smtpHost").setValidators([O.required]),this.sendEmailConfigForm.get("smtpPort").setValidators([O.required,O.min(1),O.max(65535)]),this.sendEmailConfigForm.get("timeout").setValidators([O.required,O.min(0)]),this.sendEmailConfigForm.get("proxyHost").setValidators(n?[O.required]:[]),this.sendEmailConfigForm.get("proxyPort").setValidators(n?[O.required,O.min(1),O.max(65535)]:[])),this.sendEmailConfigForm.get("smtpProtocol").updateValueAndValidity({emitEvent:e}),this.sendEmailConfigForm.get("smtpHost").updateValueAndValidity({emitEvent:e}),this.sendEmailConfigForm.get("smtpPort").updateValueAndValidity({emitEvent:e}),this.sendEmailConfigForm.get("timeout").updateValueAndValidity({emitEvent:e}),this.sendEmailConfigForm.get("proxyHost").updateValueAndValidity({emitEvent:e}),this.sendEmailConfigForm.get("proxyPort").updateValueAndValidity({emitEvent:e})}}e("SendEmailConfigComponent",pr),pr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:pr,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),pr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:pr,selector:"tb-external-node-send-email-config",usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.use-system-smtp-settings\' | translate }}\n \n
\n \n tb.rulenode.smtp-protocol\n \n \n {{ smtpProtocol.toUpperCase() }}\n \n \n \n
\n \n tb.rulenode.smtp-host\n \n \n {{ \'tb.rulenode.smtp-host-required\' | translate }}\n \n \n \n tb.rulenode.smtp-port\n \n \n {{ \'tb.rulenode.smtp-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.smtp-port-range\' | translate }}\n \n \n {{ \'tb.rulenode.smtp-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.timeout-msec\n \n \n {{ \'tb.rulenode.timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-timeout-msec-message\' | translate }}\n \n \n \n {{ \'tb.rulenode.enable-tls\' | translate }}\n \n \n tb.rulenode.tls-version\n \n \n {{ tlsVersion }}\n \n \n \n \n {{ \'tb.rulenode.enable-proxy\' | translate }}\n \n
\n
\n \n tb.rulenode.proxy-host\n \n \n {{ \'tb.rulenode.proxy-host-required\' | translate }}\n \n \n \n tb.rulenode.proxy-port\n \n \n {{ \'tb.rulenode.proxy-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.proxy-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.proxy-user\n \n \n \n tb.rulenode.proxy-password\n \n \n
\n \n tb.rulenode.username\n \n \n \n tb.rulenode.password\n \n \n \n
\n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:rt.TbCheckboxComponent,selector:"tb-checkbox",inputs:["disabled","trueValue","falseValue"],outputs:["valueChange"]},{kind:"component",type:Q.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Y.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:We.TogglePasswordComponent,selector:"tb-toggle-password"},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:pr,decorators:[{type:n,args:[{selector:"tb-external-node-send-email-config",template:'
\n \n {{ \'tb.rulenode.use-system-smtp-settings\' | translate }}\n \n
\n \n tb.rulenode.smtp-protocol\n \n \n {{ smtpProtocol.toUpperCase() }}\n \n \n \n
\n \n tb.rulenode.smtp-host\n \n \n {{ \'tb.rulenode.smtp-host-required\' | translate }}\n \n \n \n tb.rulenode.smtp-port\n \n \n {{ \'tb.rulenode.smtp-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.smtp-port-range\' | translate }}\n \n \n {{ \'tb.rulenode.smtp-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.timeout-msec\n \n \n {{ \'tb.rulenode.timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-timeout-msec-message\' | translate }}\n \n \n \n {{ \'tb.rulenode.enable-tls\' | translate }}\n \n \n tb.rulenode.tls-version\n \n \n {{ tlsVersion }}\n \n \n \n \n {{ \'tb.rulenode.enable-proxy\' | translate }}\n \n
\n
\n \n tb.rulenode.proxy-host\n \n \n {{ \'tb.rulenode.proxy-host-required\' | translate }}\n \n \n \n tb.rulenode.proxy-port\n \n \n {{ \'tb.rulenode.proxy-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.proxy-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.proxy-user\n \n \n \n tb.rulenode.proxy-password\n \n \n
\n \n tb.rulenode.username\n \n \n \n tb.rulenode.password\n \n \n \n
\n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class dr extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.sendSmsConfigForm}onConfigurationSet(e){this.sendSmsConfigForm=this.fb.group({numbersToTemplate:[e?e.numbersToTemplate:null,[O.required]],smsMessageTemplate:[e?e.smsMessageTemplate:null,[O.required]],useSystemSmsSettings:[!!e&&e.useSystemSmsSettings,[]],smsProviderConfiguration:[e?e.smsProviderConfiguration:null,[]]})}validatorTriggers(){return["useSystemSmsSettings"]}updateValidators(e){this.sendSmsConfigForm.get("useSystemSmsSettings").value?this.sendSmsConfigForm.get("smsProviderConfiguration").setValidators([]):this.sendSmsConfigForm.get("smsProviderConfiguration").setValidators([O.required]),this.sendSmsConfigForm.get("smsProviderConfiguration").updateValueAndValidity({emitEvent:e})}}e("SendSmsConfigComponent",dr),dr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:dr,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),dr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:dr,selector:"tb-external-node-send-sms-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.numbers-to-template\n \n \n {{ \'tb.rulenode.numbers-to-template-required\' | translate }}\n \n \n \n \n tb.rulenode.sms-message-template\n \n \n {{ \'tb.rulenode.sms-message-template-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n {{ \'tb.rulenode.use-system-sms-settings\' | translate }}\n \n \n \n
\n',dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Q.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:ot.SmsProviderConfigurationComponent,selector:"tb-sms-provider-configuration",inputs:["required","disabled"]},{kind:"pipe",type:he.SafePipe,name:"safe"},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:dr,decorators:[{type:n,args:[{selector:"tb-external-node-send-sms-config",template:'
\n \n tb.rulenode.numbers-to-template\n \n \n {{ \'tb.rulenode.numbers-to-template-required\' | translate }}\n \n \n \n \n tb.rulenode.sms-message-template\n \n \n {{ \'tb.rulenode.sms-message-template-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n {{ \'tb.rulenode.use-system-sms-settings\' | translate }}\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class ur extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.slackChanelTypes=Object.keys(w),this.slackChanelTypesTranslateMap=V}configForm(){return this.slackConfigForm}onConfigurationSet(e){this.slackConfigForm=this.fb.group({botToken:[e?e.botToken:null],useSystemSettings:[!!e&&e.useSystemSettings],messageTemplate:[e?e.messageTemplate:null,[O.required]],conversationType:[e?e.conversationType:null,[O.required]],conversation:[e?e.conversation:null,[O.required]]})}validatorTriggers(){return["useSystemSettings"]}updateValidators(e){this.slackConfigForm.get("useSystemSettings").value?this.slackConfigForm.get("botToken").clearValidators():this.slackConfigForm.get("botToken").setValidators([O.required]),this.slackConfigForm.get("botToken").updateValueAndValidity({emitEvent:e})}}e("SlackConfigComponent",ur),ur.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ur,deps:[{token:P.Store},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),ur.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:ur,selector:"tb-external-node-slack-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.message-template\n \n \n {{ \'tb.rulenode.message-template-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n {{ \'tb.rulenode.use-system-slack-settings\' | translate }}\n \n \n tb.rulenode.slack-api-token\n \n \n {{ \'tb.rulenode.slack-api-token-required\' | translate }}\n \n \n \n \n \n {{ slackChanelTypesTranslateMap.get(slackChanelType) | translate }}\n \n \n \n \n
\n',styles:[":host .tb-title{display:block;padding-bottom:6px}:host ::ng-deep .mat-mdc-radio-group{display:flex;flex-direction:row;margin-bottom:22px;gap:12px}:host ::ng-deep .mat-mdc-radio-group .mat-mdc-radio-button{flex:1 1 100%;padding:4px;border:1px solid rgba(0,0,0,.12);border-radius:6px}@media screen and (max-width: 599px){:host ::ng-deep .mat-mdc-radio-group{flex-direction:column}}\n"],dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Q.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:at.MatRadioGroup,selector:"mat-radio-group",exportAs:["matRadioGroup"]},{kind:"component",type:at.MatRadioButton,selector:"mat-radio-button",inputs:["disableRipple","tabIndex"],exportAs:["matRadioButton"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:it.SlackConversationAutocompleteComponent,selector:"tb-slack-conversation-autocomplete",inputs:["labelText","requiredText","required","disabled","slackChanelType","token"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ur,decorators:[{type:n,args:[{selector:"tb-external-node-slack-config",template:'
\n \n tb.rulenode.message-template\n \n \n {{ \'tb.rulenode.message-template-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n {{ \'tb.rulenode.use-system-slack-settings\' | translate }}\n \n \n tb.rulenode.slack-api-token\n \n \n {{ \'tb.rulenode.slack-api-token-required\' | translate }}\n \n \n \n \n \n {{ slackChanelTypesTranslateMap.get(slackChanelType) | translate }}\n \n \n \n \n
\n',styles:[":host .tb-title{display:block;padding-bottom:6px}:host ::ng-deep .mat-mdc-radio-group{display:flex;flex-direction:row;margin-bottom:22px;gap:12px}:host ::ng-deep .mat-mdc-radio-group .mat-mdc-radio-button{flex:1 1 100%;padding:4px;border:1px solid rgba(0,0,0,.12);border-radius:6px}@media screen and (max-width: 599px){:host ::ng-deep .mat-mdc-radio-group{flex-direction:column}}\n"]}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder}]}});class cr extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.snsConfigForm}onConfigurationSet(e){this.snsConfigForm=this.fb.group({topicArnPattern:[e?e.topicArnPattern:null,[O.required]],accessKeyId:[e?e.accessKeyId:null,[O.required]],secretAccessKey:[e?e.secretAccessKey:null,[O.required]],region:[e?e.region:null,[O.required]]})}}e("SnsConfigComponent",cr),cr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:cr,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),cr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:cr,selector:"tb-external-node-sns-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.topic-arn-pattern\n \n \n {{ \'tb.rulenode.topic-arn-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.aws-access-key-id\n \n \n {{ \'tb.rulenode.aws-access-key-id-required\' | translate }}\n \n \n \n tb.rulenode.aws-secret-access-key\n \n \n {{ \'tb.rulenode.aws-secret-access-key-required\' | translate }}\n \n \n \n tb.rulenode.aws-region\n \n \n {{ \'tb.rulenode.aws-region-required\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:cr,decorators:[{type:n,args:[{selector:"tb-external-node-sns-config",template:'
\n \n tb.rulenode.topic-arn-pattern\n \n \n {{ \'tb.rulenode.topic-arn-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.aws-access-key-id\n \n \n {{ \'tb.rulenode.aws-access-key-id-required\' | translate }}\n \n \n \n tb.rulenode.aws-secret-access-key\n \n \n {{ \'tb.rulenode.aws-secret-access-key-required\' | translate }}\n \n \n \n tb.rulenode.aws-region\n \n \n {{ \'tb.rulenode.aws-region-required\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class fr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.sqsQueueType=Bt,this.sqsQueueTypes=Object.keys(Bt),this.sqsQueueTypeTranslationsMap=Kt}configForm(){return this.sqsConfigForm}onConfigurationSet(e){this.sqsConfigForm=this.fb.group({queueType:[e?e.queueType:null,[O.required]],queueUrlPattern:[e?e.queueUrlPattern:null,[O.required]],delaySeconds:[e?e.delaySeconds:null,[O.min(0),O.max(900)]],messageAttributes:[e?e.messageAttributes:null,[]],accessKeyId:[e?e.accessKeyId:null,[O.required]],secretAccessKey:[e?e.secretAccessKey:null,[O.required]],region:[e?e.region:null,[O.required]]})}}e("SqsConfigComponent",fr),fr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:fr,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),fr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:fr,selector:"tb-external-node-sqs-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.queue-type\n \n \n {{ sqsQueueTypeTranslationsMap.get(type) | translate }}\n \n \n \n \n tb.rulenode.queue-url-pattern\n \n \n {{ \'tb.rulenode.queue-url-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.delay-seconds\n \n \n {{ \'tb.rulenode.min-delay-seconds-message\' | translate }}\n \n \n {{ \'tb.rulenode.max-delay-seconds-message\' | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.aws-access-key-id\n \n \n {{ \'tb.rulenode.aws-access-key-id-required\' | translate }}\n \n \n \n tb.rulenode.aws-secret-access-key\n \n \n {{ \'tb.rulenode.aws-secret-access-key-required\' | translate }}\n \n \n \n tb.rulenode.aws-region\n \n \n {{ \'tb.rulenode.aws-region-required\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:hn,selector:"tb-kv-map-config-old",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:he.SafePipe,name:"safe"},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:fr,decorators:[{type:n,args:[{selector:"tb-external-node-sqs-config",template:'
\n \n tb.rulenode.queue-type\n \n \n {{ sqsQueueTypeTranslationsMap.get(type) | translate }}\n \n \n \n \n tb.rulenode.queue-url-pattern\n \n \n {{ \'tb.rulenode.queue-url-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.delay-seconds\n \n \n {{ \'tb.rulenode.min-delay-seconds-message\' | translate }}\n \n \n {{ \'tb.rulenode.max-delay-seconds-message\' | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.aws-access-key-id\n \n \n {{ \'tb.rulenode.aws-access-key-id-required\' | translate }}\n \n \n \n tb.rulenode.aws-secret-access-key\n \n \n {{ \'tb.rulenode.aws-secret-access-key-required\' | translate }}\n \n \n \n tb.rulenode.aws-region\n \n \n {{ \'tb.rulenode.aws-region-required\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class gr{}e("RulenodeCoreConfigExternalModule",gr),gr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:gr,deps:[],target:t.ɵɵFactoryTarget.NgModule}),gr.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.10",ngImport:t,type:gr,declarations:[cr,fr,lr,or,ar,ir,sr,mr,pr,rr,dr,ur],imports:[$,M,Re,Un],exports:[cr,fr,lr,or,ar,ir,sr,mr,pr,rr,dr,ur]}),gr.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:gr,imports:[$,M,Re,Un]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:gr,decorators:[{type:c,args:[{declarations:[cr,fr,lr,or,ar,ir,sr,mr,pr,rr,dr,ur],imports:[$,M,Re,Un],exports:[cr,fr,lr,or,ar,ir,sr,mr,pr,rr,dr,ur]}]}]});class yr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.searchText=""}configForm(){return this.alarmStatusConfigForm}prepareInputConfig(e){return{alarmStatusList:ie(e?.alarmStatusList)?e.alarmStatusList:null}}onConfigurationSet(e){this.alarmStatusConfigForm=this.fb.group({alarmStatusList:[e.alarmStatusList,[O.required]]})}}e("CheckAlarmStatusComponent",yr),yr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:yr,deps:[{token:P.Store},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),yr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:yr,selector:"tb-filter-node-check-alarm-status-config",usesInheritance:!0,ngImport:t,template:'
\n
\n
tb.rulenode.alarm-status
\n
\n tb.rulenode.alarm-required\n
\n
\n \n
\n\n\n\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:zn,selector:"tb-alarm-status-select"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:yr,decorators:[{type:n,args:[{selector:"tb-filter-node-check-alarm-status-config",template:'
\n
\n
tb.rulenode.alarm-status
\n
\n tb.rulenode.alarm-required\n
\n
\n \n
\n\n\n\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder}]}});class xr extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.checkMessageConfigForm}prepareInputConfig(e){return{messageNames:ie(e?.messageNames)?e.messageNames:[],metadataNames:ie(e?.metadataNames)?e.metadataNames:[],checkAllKeys:!!ie(e?.checkAllKeys)&&e.checkAllKeys}}prepareOutputConfig(e){return{messageNames:ie(e?.messageNames)?e.messageNames:[],metadataNames:ie(e?.metadataNames)?e.metadataNames:[],checkAllKeys:e.checkAllKeys}}atLeastOne(e,t=null){return n=>{t||(t=Object.keys(n.controls));return n?.controls&&t.some((t=>!e(n.controls[t])))?null:{atLeastOne:!0}}}onConfigurationSet(e){this.checkMessageConfigForm=this.fb.group({messageNames:[e.messageNames,[]],metadataNames:[e.metadataNames,[]],checkAllKeys:[e.checkAllKeys,[]]},{validators:this.atLeastOne(O.required,["messageNames","metadataNames"])})}get touchedValidationControl(){return["messageNames","metadataNames"].some((e=>this.checkMessageConfigForm.get(e).touched))}}e("CheckMessageConfigComponent",xr),xr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:xr,deps:[{token:P.Store},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),xr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:xr,selector:"tb-filter-node-check-message-config",usesInheritance:!0,ngImport:t,template:'
\n
\n
tb.rulenode.fields-to-check
\n
\n tb.rulenode.at-least-one-field-required\n
\n
\n \n help\n \n \n help\n \n
\n \n {{ \'tb.rulenode.check-all-keys\' | translate }}\n \n
\n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"component",type:Ze.StringItemsListComponent,selector:"tb-string-items-list",inputs:["required","disabled","label","placeholder","hint","requiredText","floatLabel","appearance","editable","subscriptSizing","predefinedValues"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:Y.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:te.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:ne.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:xr,decorators:[{type:n,args:[{selector:"tb-filter-node-check-message-config",template:'
\n
\n
tb.rulenode.fields-to-check
\n
\n tb.rulenode.at-least-one-field-required\n
\n
\n \n help\n \n \n help\n \n
\n \n {{ \'tb.rulenode.check-all-keys\' | translate }}\n \n
\n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder}]}});class br extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.entitySearchDirection=Object.values(v),this.entitySearchDirectionTranslationsMap=C}configForm(){return this.checkRelationConfigForm}prepareInputConfig(e){return{checkForSingleEntity:!!ie(e?.checkForSingleEntity)&&e.checkForSingleEntity,direction:ie(e?.direction)?e.direction:null,entityType:ie(e?.entityType)?e.entityType:null,entityId:ie(e?.entityId)?e.entityId:null,relationType:ie(e?.relationType)?e.relationType:null}}onConfigurationSet(e){this.checkRelationConfigForm=this.fb.group({checkForSingleEntity:[e.checkForSingleEntity,[]],direction:[e.direction,[]],entityType:[e.entityType,e&&e.checkForSingleEntity?[O.required]:[]],entityId:[e.entityId,e&&e.checkForSingleEntity?[O.required]:[]],relationType:[e.relationType,[O.required]]})}validatorTriggers(){return["checkForSingleEntity"]}updateValidators(e){const t=this.checkRelationConfigForm.get("checkForSingleEntity").value;this.checkRelationConfigForm.get("entityType").setValidators(t?[O.required]:[]),this.checkRelationConfigForm.get("entityType").updateValueAndValidity({emitEvent:e}),this.checkRelationConfigForm.get("entityId").setValidators(t?[O.required]:[]),this.checkRelationConfigForm.get("entityId").updateValueAndValidity({emitEvent:e})}}e("CheckRelationConfigComponent",br),br.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:br,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),br.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:br,selector:"tb-filter-node-check-relation-config",usesInheritance:!0,ngImport:t,template:'
\n
tb.rulenode.relation-search-parameters
\n
\n \n {{ \'relation.direction\' | translate }}\n \n \n {{ entitySearchDirectionTranslationsMap.get(direction) | translate }} tb.rulenode.relations-query-config-direction-suffix\n \n \n \n \n \n
\n \n {{ \'tb.rulenode.check-relation-to-specific-entity\' | translate }}\n \n
\n
\n \n \n \n \n
\n
\n
\n',styles:[":host .slide-toggle{margin-bottom:18px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:lt.EntityAutocompleteComponent,selector:"tb-entity-autocomplete",inputs:["entityType","entitySubtype","excludeEntityIds","labelText","requiredText","useFullEntityId","appearance","required","disabled"],outputs:["entityChanged"]},{kind:"component",type:ve.EntityTypeSelectComponent,selector:"tb-entity-type-select",inputs:["allowedEntityTypes","useAliasEntityTypes","filterAllowedEntityTypes","showLabel","required","disabled"]},{kind:"component",type:$e.RelationTypeAutocompleteComponent,selector:"tb-relation-type-autocomplete",inputs:["showLabel","additionalClasses","appearance","required","disabled","subscriptSizing"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:te.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:ne.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:br,decorators:[{type:n,args:[{selector:"tb-filter-node-check-relation-config",template:'
\n
tb.rulenode.relation-search-parameters
\n
\n \n {{ \'relation.direction\' | translate }}\n \n \n {{ entitySearchDirectionTranslationsMap.get(direction) | translate }} tb.rulenode.relations-query-config-direction-suffix\n \n \n \n \n \n
\n \n {{ \'tb.rulenode.check-relation-to-specific-entity\' | translate }}\n \n
\n
\n \n \n \n \n
\n
\n
\n',styles:[":host .slide-toggle{margin-bottom:18px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class hr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.perimeterType=Tt,this.perimeterTypes=Object.values(Tt),this.perimeterTypeTranslationMap=It,this.rangeUnits=Object.values(qt),this.rangeUnitTranslationMap=At,this.defaultPaddingEnable=!0}configForm(){return this.geoFilterConfigForm}prepareInputConfig(e){return{latitudeKeyName:ie(e?.latitudeKeyName)?e.latitudeKeyName:null,longitudeKeyName:ie(e?.longitudeKeyName)?e.longitudeKeyName:null,perimeterType:ie(e?.perimeterType)?e.perimeterType:null,fetchPerimeterInfoFromMessageMetadata:!!ie(e?.fetchPerimeterInfoFromMessageMetadata)&&e.fetchPerimeterInfoFromMessageMetadata,perimeterKeyName:ie(e?.perimeterKeyName)?e.perimeterKeyName:null,centerLatitude:ie(e?.centerLatitude)?e.centerLatitude:null,centerLongitude:ie(e?.centerLongitude)?e.centerLongitude:null,range:ie(e?.range)?e.range:null,rangeUnit:ie(e?.rangeUnit)?e.rangeUnit:null,polygonsDefinition:ie(e?.polygonsDefinition)?e.polygonsDefinition:null}}onConfigurationSet(e){this.geoFilterConfigForm=this.fb.group({latitudeKeyName:[e.latitudeKeyName,[O.required]],longitudeKeyName:[e.longitudeKeyName,[O.required]],perimeterType:[e.perimeterType,[O.required]],fetchPerimeterInfoFromMessageMetadata:[e.fetchPerimeterInfoFromMessageMetadata,[]],perimeterKeyName:[e.perimeterKeyName,[]],centerLatitude:[e.centerLatitude,[]],centerLongitude:[e.centerLongitude,[]],range:[e.range,[]],rangeUnit:[e.rangeUnit,[]],polygonsDefinition:[e.polygonsDefinition,[]]})}validatorTriggers(){return["fetchPerimeterInfoFromMessageMetadata","perimeterType"]}updateValidators(e){const t=this.geoFilterConfigForm.get("fetchPerimeterInfoFromMessageMetadata").value,n=this.geoFilterConfigForm.get("perimeterType").value;t?this.geoFilterConfigForm.get("perimeterKeyName").setValidators([O.required]):this.geoFilterConfigForm.get("perimeterKeyName").setValidators([]),t||n!==Tt.CIRCLE?(this.geoFilterConfigForm.get("centerLatitude").setValidators([]),this.geoFilterConfigForm.get("centerLongitude").setValidators([]),this.geoFilterConfigForm.get("range").setValidators([]),this.geoFilterConfigForm.get("rangeUnit").setValidators([]),this.defaultPaddingEnable=!0):(this.geoFilterConfigForm.get("centerLatitude").setValidators([O.required,O.min(-90),O.max(90)]),this.geoFilterConfigForm.get("centerLongitude").setValidators([O.required,O.min(-180),O.max(180)]),this.geoFilterConfigForm.get("range").setValidators([O.required,O.min(0)]),this.geoFilterConfigForm.get("rangeUnit").setValidators([O.required]),this.defaultPaddingEnable=!1),t||n!==Tt.POLYGON?this.geoFilterConfigForm.get("polygonsDefinition").setValidators([]):this.geoFilterConfigForm.get("polygonsDefinition").setValidators([O.required]),this.geoFilterConfigForm.get("perimeterKeyName").updateValueAndValidity({emitEvent:e}),this.geoFilterConfigForm.get("centerLatitude").updateValueAndValidity({emitEvent:e}),this.geoFilterConfigForm.get("centerLongitude").updateValueAndValidity({emitEvent:e}),this.geoFilterConfigForm.get("range").updateValueAndValidity({emitEvent:e}),this.geoFilterConfigForm.get("rangeUnit").updateValueAndValidity({emitEvent:e}),this.geoFilterConfigForm.get("polygonsDefinition").updateValueAndValidity({emitEvent:e})}}e("GpsGeoFilterConfigComponent",hr),hr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:hr,deps:[{token:P.Store},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),hr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:hr,selector:"tb-filter-node-gps-geofencing-config",usesInheritance:!0,ngImport:t,template:'
\n
\n
tb.rulenode.coordinate-field-names
\n
\n
\n \n {{ \'tb.rulenode.latitude-field-name\' | translate }}\n \n \n {{ \'tb.rulenode.latitude-field-name-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.longitude-field-name\' | translate }}\n \n \n {{ \'tb.rulenode.longitude-field-name-required\' | translate }}\n \n \n
\n
tb.rulenode.coordinate-field-hint
\n
\n
\n
\n
tb.rulenode.geofence-configuration
\n
\n \n {{ \'tb.rulenode.perimeter-type\' | translate }}\n \n \n {{ perimeterTypeTranslationMap.get(type) | translate }}\n \n \n \n
\n \n {{ \'tb.rulenode.fetch-perimeter-info-from-metadata\' | translate }}\n \n
\n \n {{ \'tb.rulenode.perimeter-key-name\' | translate }}\n \n \n {{ \'tb.rulenode.perimeter-key-name-required\' | translate }}\n \n {{ \'tb.rulenode.perimeter-key-name-hint\' | translate }}\n \n
\n
\n \n {{ \'tb.rulenode.circle-center-latitude\' | translate }}\n \n \n {{ \'tb.rulenode.circle-center-latitude-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.circle-center-longitude\' | translate }}\n \n \n {{ \'tb.rulenode.circle-center-longitude-required\' | translate }}\n \n \n
\n
\n \n {{ \'tb.rulenode.range\' | translate }}\n \n \n {{ \'tb.rulenode.range-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.range-units\' | translate }}\n \n \n {{ rangeUnitTranslationMap.get(type) | translate }}\n \n \n \n {{ \'tb.rulenode.range-units-required\' | translate }}\n \n \n
\n
\n \n {{ \'tb.rulenode.polygon-definition\' | translate }}\n \n {{ \'tb.rulenode.polygon-definition-hint\' | translate }}\n \n {{ \'tb.rulenode.polygon-definition-required\' | translate }}\n \n \n
\n
\n
\n',styles:[":host .slide-toggle{margin-bottom:18px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:te.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:ne.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:hr,decorators:[{type:n,args:[{selector:"tb-filter-node-gps-geofencing-config",template:'
\n
\n
tb.rulenode.coordinate-field-names
\n
\n
\n \n {{ \'tb.rulenode.latitude-field-name\' | translate }}\n \n \n {{ \'tb.rulenode.latitude-field-name-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.longitude-field-name\' | translate }}\n \n \n {{ \'tb.rulenode.longitude-field-name-required\' | translate }}\n \n \n
\n
tb.rulenode.coordinate-field-hint
\n
\n
\n
\n
tb.rulenode.geofence-configuration
\n
\n \n {{ \'tb.rulenode.perimeter-type\' | translate }}\n \n \n {{ perimeterTypeTranslationMap.get(type) | translate }}\n \n \n \n
\n \n {{ \'tb.rulenode.fetch-perimeter-info-from-metadata\' | translate }}\n \n
\n \n {{ \'tb.rulenode.perimeter-key-name\' | translate }}\n \n \n {{ \'tb.rulenode.perimeter-key-name-required\' | translate }}\n \n {{ \'tb.rulenode.perimeter-key-name-hint\' | translate }}\n \n
\n
\n \n {{ \'tb.rulenode.circle-center-latitude\' | translate }}\n \n \n {{ \'tb.rulenode.circle-center-latitude-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.circle-center-longitude\' | translate }}\n \n \n {{ \'tb.rulenode.circle-center-longitude-required\' | translate }}\n \n \n
\n
\n \n {{ \'tb.rulenode.range\' | translate }}\n \n \n {{ \'tb.rulenode.range-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.range-units\' | translate }}\n \n \n {{ rangeUnitTranslationMap.get(type) | translate }}\n \n \n \n {{ \'tb.rulenode.range-units-required\' | translate }}\n \n \n
\n
\n \n {{ \'tb.rulenode.polygon-definition\' | translate }}\n \n {{ \'tb.rulenode.polygon-definition-hint\' | translate }}\n \n {{ \'tb.rulenode.polygon-definition-required\' | translate }}\n \n \n
\n
\n
\n',styles:[":host .slide-toggle{margin-bottom:18px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder}]}});class vr extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.messageTypeConfigForm}prepareInputConfig(e){return{messageTypes:ie(e?.messageTypes)?e.messageTypes:null}}onConfigurationSet(e){this.messageTypeConfigForm=this.fb.group({messageTypes:[e.messageTypes,[O.required]]})}}e("MessageTypeConfigComponent",vr),vr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:vr,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),vr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:vr,selector:"tb-filter-node-message-type-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n
\n',dependencies:[{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:Mn,selector:"tb-message-types-config",inputs:["required","label","placeholder","disabled"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:vr,decorators:[{type:n,args:[{selector:"tb-filter-node-message-type-config",template:'
\n \n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class Cr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.allowedEntityTypes=[F.DEVICE,F.ASSET,F.ENTITY_VIEW,F.TENANT,F.CUSTOMER,F.USER,F.DASHBOARD,F.RULE_CHAIN,F.RULE_NODE]}configForm(){return this.originatorTypeConfigForm}prepareInputConfig(e){return{originatorTypes:ie(e?.originatorTypes)?e.originatorTypes:null}}onConfigurationSet(e){this.originatorTypeConfigForm=this.fb.group({originatorTypes:[e.originatorTypes,[O.required]]})}}e("OriginatorTypeConfigComponent",Cr),Cr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Cr,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Cr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Cr,selector:"tb-filter-node-originator-type-config",usesInheritance:!0,ngImport:t,template:'
\n \n help\n \n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"component",type:st.EntityTypeListComponent,selector:"tb-entity-type-list",inputs:["required","additionalClasses","appearance","label","floatLabel","disabled","subscriptSizing","allowedEntityTypes","emptyInputPlaceholder","filledInputPlaceholder","ignoreAuthorityFilter"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:Y.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Cr,decorators:[{type:n,args:[{selector:"tb-filter-node-originator-type-config",template:'
\n \n help\n \n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class Fr extends f{constructor(e,t,n,o){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=n,this.translate=o,this.tbelEnabled=re(this.store).tbelEnabled,this.scriptLanguage=x,this.changeScript=new r,this.hasScript=!0,this.testScriptLabel="tb.rulenode.test-filter-function"}configForm(){return this.scriptConfigForm}onConfigurationSet(e){this.scriptConfigForm=this.fb.group({scriptLang:[e.scriptLang,[O.required]],jsScript:[e.jsScript,[]],tbelScript:[e.tbelScript,[]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.scriptConfigForm.get("scriptLang").value;t!==x.TBEL||this.tbelEnabled||(t=x.JS,this.scriptConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.scriptConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.scriptConfigForm.get("jsScript").setValidators(t===x.JS?[O.required]:[]),this.scriptConfigForm.get("jsScript").updateValueAndValidity({emitEvent:e}),this.scriptConfigForm.get("tbelScript").setValidators(t===x.TBEL?[O.required]:[]),this.scriptConfigForm.get("tbelScript").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=x.JS)),{scriptLang:ie(e?.scriptLang)?e.scriptLang:x.JS,jsScript:ie(e?.jsScript)?e.jsScript:null,tbelScript:ie(e?.tbelScript)?e.tbelScript:null}}testScript(e){const t=this.scriptConfigForm.get("scriptLang").value,n=t===x.JS?"jsScript":"tbelScript",r=t===x.JS?"rulenode/filter_node_script_fn":"rulenode/tbel/filter_node_script_fn",o=this.scriptConfigForm.get(n).value;this.nodeScriptTestService.testNodeScript(o,"filter",this.translate.instant("tb.rulenode.filter"),"Filter",["msg","metadata","msgType"],this.ruleNodeId,r,t,e).subscribe((e=>{e&&(this.scriptConfigForm.get(n).setValue(e),this.changeScript.emit())}))}onValidate(){this.scriptConfigForm.get("scriptLang").value===x.JS&&this.jsFuncComponent.validateOnSubmit()}}e("ScriptConfigComponent",Fr),Fr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Fr,deps:[{token:P.Store},{token:R.UntypedFormBuilder},{token:oe.NodeScriptTestService},{token:Z.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Fr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Fr,selector:"tb-filter-node-script-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n \n \n \n
\n',dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:pe.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:de.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:de.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:fe.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Fr,decorators:[{type:n,args:[{selector:"tb-filter-node-script-config",template:'
\n \n \n \n \n \n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder},{type:oe.NodeScriptTestService},{type:Z.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}});class kr extends f{constructor(e,t,n,o){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=n,this.translate=o,this.tbelEnabled=re(this.store).tbelEnabled,this.scriptLanguage=x,this.changeScript=new r,this.hasScript=!0,this.testScriptLabel="tb.rulenode.test-switch-function"}configForm(){return this.switchConfigForm}onConfigurationSet(e){this.switchConfigForm=this.fb.group({scriptLang:[e.scriptLang,[O.required]],jsScript:[e.jsScript,[]],tbelScript:[e.tbelScript,[]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.switchConfigForm.get("scriptLang").value;t!==x.TBEL||this.tbelEnabled||(t=x.JS,this.switchConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.switchConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.switchConfigForm.get("jsScript").setValidators(t===x.JS?[O.required]:[]),this.switchConfigForm.get("jsScript").updateValueAndValidity({emitEvent:e}),this.switchConfigForm.get("tbelScript").setValidators(t===x.TBEL?[O.required]:[]),this.switchConfigForm.get("tbelScript").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=x.JS)),{scriptLang:ie(e?.scriptLang)?e.scriptLang:x.JS,jsScript:ie(e?.jsScript)?e.jsScript:null,tbelScript:ie(e?.tbelScript)?e.tbelScript:null}}testScript(e){const t=this.switchConfigForm.get("scriptLang").value,n=t===x.JS?"jsScript":"tbelScript",r=t===x.JS?"rulenode/switch_node_script_fn":"rulenode/tbel/switch_node_script_fn",o=this.switchConfigForm.get(n).value;this.nodeScriptTestService.testNodeScript(o,"switch",this.translate.instant("tb.rulenode.switch"),"Switch",["msg","metadata","msgType"],this.ruleNodeId,r,t,e).subscribe((e=>{e&&(this.switchConfigForm.get(n).setValue(e),this.changeScript.emit())}))}onValidate(){this.switchConfigForm.get("scriptLang").value===x.JS&&this.jsFuncComponent.validateOnSubmit()}}e("SwitchConfigComponent",kr),kr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:kr,deps:[{token:P.Store},{token:R.UntypedFormBuilder},{token:oe.NodeScriptTestService},{token:Z.TranslateService}],target:t.ɵɵFactoryTarget.Component}),kr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:kr,selector:"tb-filter-node-switch-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n \n \n \n
\n',dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:pe.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:de.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:de.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:fe.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:kr,decorators:[{type:n,args:[{selector:"tb-filter-node-switch-config",template:'
\n \n \n \n \n \n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder},{type:oe.NodeScriptTestService},{type:Z.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}});class Lr{}e("RuleNodeCoreConfigFilterModule",Lr),Lr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Lr,deps:[],target:t.ɵɵFactoryTarget.NgModule}),Lr.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.10",ngImport:t,type:Lr,declarations:[xr,br,hr,vr,Cr,Fr,kr,yr],imports:[$,M,Un],exports:[xr,br,hr,vr,Cr,Fr,kr,yr]}),Lr.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Lr,imports:[$,M,Un]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Lr,decorators:[{type:c,args:[{declarations:[xr,br,hr,vr,Cr,Fr,kr,yr],imports:[$,M,Un],exports:[xr,br,hr,vr,Cr,Fr,kr,yr]}]}]});class Tr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.originatorSource=vt,this.originatorSources=Object.keys(vt),this.originatorSourceTranslationMap=Ct,this.originatorSourceDescTranslationMap=Ft,this.allowedEntityTypes=[F.DEVICE,F.ASSET,F.ENTITY_VIEW,F.USER,F.EDGE]}configForm(){return this.changeOriginatorConfigForm}onConfigurationSet(e){this.changeOriginatorConfigForm=this.fb.group({originatorSource:[e?e.originatorSource:null,[O.required]],entityType:[e?e.entityType:null,[]],entityNamePattern:[e?e.entityNamePattern:null,[]],relationsQuery:[e?e.relationsQuery:null,[]]})}validatorTriggers(){return["originatorSource"]}updateValidators(e){const t=this.changeOriginatorConfigForm.get("originatorSource").value;t===vt.RELATED?this.changeOriginatorConfigForm.get("relationsQuery").setValidators([O.required]):this.changeOriginatorConfigForm.get("relationsQuery").setValidators([]),t===vt.ENTITY?(this.changeOriginatorConfigForm.get("entityType").setValidators([O.required]),this.changeOriginatorConfigForm.get("entityNamePattern").setValidators([O.required,O.pattern(/.*\S.*/)])):(this.changeOriginatorConfigForm.get("entityType").patchValue(null,{emitEvent:e}),this.changeOriginatorConfigForm.get("entityNamePattern").patchValue(null,{emitEvent:e}),this.changeOriginatorConfigForm.get("entityType").setValidators([]),this.changeOriginatorConfigForm.get("entityNamePattern").setValidators([])),this.changeOriginatorConfigForm.get("relationsQuery").updateValueAndValidity({emitEvent:e}),this.changeOriginatorConfigForm.get("entityType").updateValueAndValidity({emitEvent:e}),this.changeOriginatorConfigForm.get("entityNamePattern").updateValueAndValidity({emitEvent:e})}}e("ChangeOriginatorConfigComponent",Tr),Tr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Tr,deps:[{token:P.Store},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Tr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Tr,selector:"tb-transformation-node-change-originator-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.new-originator\n \n \n \n {{ originatorSourceTranslationMap.get(changeOriginatorConfigForm.get(\'originatorSource\').value) | translate }}\n \n \n \n \n {{ originatorSourceTranslationMap.get(source) | translate }}\n \n
\n \n {{ originatorSourceDescTranslationMap.get(source) | translate }}\n \n
\n
\n
\n
\n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n \n
\n
\n \n \n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ve.EntityTypeSelectComponent,selector:"tb-entity-type-select",inputs:["allowedEntityTypes","useAliasEntityTypes","filterAllowedEntityTypes","showLabel","required","disabled"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"directive",type:X.MatSelectTrigger,selector:"mat-select-trigger"},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:Ne.MatListItemTitle,selector:"[matListItemTitle]"},{kind:"directive",type:Ne.MatListItemMeta,selector:"[matListItemMeta]"},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:An,selector:"tb-relations-query-config",inputs:["disabled","required"]},{kind:"component",type:Nn,selector:"tb-example-hint",inputs:["hintText","popupHelpLink","textAlign"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Tr,decorators:[{type:n,args:[{selector:"tb-transformation-node-change-originator-config",template:'
\n \n tb.rulenode.new-originator\n \n \n \n {{ originatorSourceTranslationMap.get(changeOriginatorConfigForm.get(\'originatorSource\').value) | translate }}\n \n \n \n \n {{ originatorSourceTranslationMap.get(source) | translate }}\n \n
\n \n {{ originatorSourceDescTranslationMap.get(source) | translate }}\n \n
\n
\n
\n
\n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n \n
\n
\n \n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder}]}});class Ir extends f{constructor(e,t,n,o){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=n,this.translate=o,this.tbelEnabled=re(this.store).tbelEnabled,this.scriptLanguage=x,this.changeScript=new r,this.hasScript=!0,this.testScriptLabel="tb.rulenode.test-transformer-function"}configForm(){return this.scriptConfigForm}onConfigurationSet(e){this.scriptConfigForm=this.fb.group({scriptLang:[e?e.scriptLang:x.JS,[O.required]],jsScript:[e?e.jsScript:null,[O.required]],tbelScript:[e?e.tbelScript:null,[]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.scriptConfigForm.get("scriptLang").value;t!==x.TBEL||this.tbelEnabled||(t=x.JS,this.scriptConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.scriptConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.scriptConfigForm.get("jsScript").setValidators(t===x.JS?[O.required]:[]),this.scriptConfigForm.get("jsScript").updateValueAndValidity({emitEvent:e}),this.scriptConfigForm.get("tbelScript").setValidators(t===x.TBEL?[O.required]:[]),this.scriptConfigForm.get("tbelScript").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=x.JS)),e}testScript(e){const t=this.scriptConfigForm.get("scriptLang").value,n=t===x.JS?"jsScript":"tbelScript",r=t===x.JS?"rulenode/transformation_node_script_fn":"rulenode/tbel/transformation_node_script_fn",o=this.scriptConfigForm.get(n).value;this.nodeScriptTestService.testNodeScript(o,"update",this.translate.instant("tb.rulenode.transformer"),"Transform",["msg","metadata","msgType"],this.ruleNodeId,r,t,e).subscribe((e=>{e&&(this.scriptConfigForm.get(n).setValue(e),this.changeScript.emit())}))}onValidate(){this.scriptConfigForm.get("scriptLang").value===x.JS&&this.jsFuncComponent.validateOnSubmit()}}e("TransformScriptConfigComponent",Ir),Ir.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Ir,deps:[{token:P.Store},{token:R.FormBuilder},{token:oe.NodeScriptTestService},{token:Z.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Ir.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Ir,selector:"tb-transformation-node-script-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n \n \n
\n \n
\n
\n',dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:pe.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:de.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:de.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:fe.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Ir,decorators:[{type:n,args:[{selector:"tb-transformation-node-script-config",template:'
\n \n \n \n \n \n \n \n
\n \n
\n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder},{type:oe.NodeScriptTestService},{type:Z.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}}); - /** - * @license - * Copyright Google LLC All Rights Reserved. - * - * Use of this source code is governed by an MIT-style license that can be - * found in the LICENSE file at https://angular.io/license - */ - const Nr=mt({passive:!0});class Sr{constructor(e,t){this._platform=e,this._ngZone=t,this._monitoredElements=new Map}monitor(e){if(!this._platform.isBrowser)return ze;const t=ke(e),n=this._monitoredElements.get(t);if(n)return n.subject;const r=new _e,o="cdk-text-field-autofilled",a=e=>{"cdk-text-field-autofill-start"!==e.animationName||t.classList.contains(o)?"cdk-text-field-autofill-end"===e.animationName&&t.classList.contains(o)&&(t.classList.remove(o),this._ngZone.run((()=>r.next({target:e.target,isAutofilled:!1})))):(t.classList.add(o),this._ngZone.run((()=>r.next({target:e.target,isAutofilled:!0}))))};return this._ngZone.runOutsideAngular((()=>{t.addEventListener("animationstart",a,Nr),t.classList.add("cdk-text-field-autofill-monitored")})),this._monitoredElements.set(t,{subject:r,unlisten:()=>{t.removeEventListener("animationstart",a,Nr)}}),r}stopMonitoring(e){const t=ke(e),n=this._monitoredElements.get(t);n&&(n.unlisten(),n.subject.complete(),t.classList.remove("cdk-text-field-autofill-monitored"),t.classList.remove("cdk-text-field-autofilled"),this._monitoredElements.delete(t))}ngOnDestroy(){this._monitoredElements.forEach(((e,t)=>this.stopMonitoring(t)))}}Sr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.0-rc.0",ngImport:t,type:Sr,deps:[{token:pt.Platform},{token:t.NgZone}],target:t.ɵɵFactoryTarget.Injectable}),Sr.ɵprov=t.ɵɵngDeclareInjectable({minVersion:"12.0.0",version:"15.2.0-rc.0",ngImport:t,type:Sr,providedIn:"root"}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.0-rc.0",ngImport:t,type:Sr,decorators:[{type:s,args:[{providedIn:"root"}]}],ctorParameters:function(){return[{type:pt.Platform},{type:t.NgZone}]}});class qr{constructor(e,t){this._elementRef=e,this._autofillMonitor=t,this.cdkAutofill=new r}ngOnInit(){this._autofillMonitor.monitor(this._elementRef).subscribe((e=>this.cdkAutofill.emit(e)))}ngOnDestroy(){this._autofillMonitor.stopMonitoring(this._elementRef)}}qr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.0-rc.0",ngImport:t,type:qr,deps:[{token:t.ElementRef},{token:Sr}],target:t.ɵɵFactoryTarget.Directive}),qr.ɵdir=t.ɵɵngDeclareDirective({minVersion:"14.0.0",version:"15.2.0-rc.0",type:qr,selector:"[cdkAutofill]",outputs:{cdkAutofill:"cdkAutofill"},ngImport:t}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.0-rc.0",ngImport:t,type:qr,decorators:[{type:d,args:[{selector:"[cdkAutofill]"}]}],ctorParameters:function(){return[{type:t.ElementRef},{type:Sr}]},propDecorators:{cdkAutofill:[{type:u}]}}); - /** - * @license - * Copyright Google LLC All Rights Reserved. - * - * Use of this source code is governed by an MIT-style license that can be - * found in the LICENSE file at https://angular.io/license - */ - class Ar{get minRows(){return this._minRows}set minRows(e){this._minRows=Le(e),this._setMinHeight()}get maxRows(){return this._maxRows}set maxRows(e){this._maxRows=Le(e),this._setMaxHeight()}get enabled(){return this._enabled}set enabled(e){e=Fe(e),this._enabled!==e&&((this._enabled=e)?this.resizeToFitContent(!0):this.reset())}get placeholder(){return this._textareaElement.placeholder}set placeholder(e){this._cachedPlaceholderHeight=void 0,e?this._textareaElement.setAttribute("placeholder",e):this._textareaElement.removeAttribute("placeholder"),this._cacheTextareaPlaceholderHeight()}constructor(e,t,n,r){this._elementRef=e,this._platform=t,this._ngZone=n,this._destroyed=new _e,this._enabled=!0,this._previousMinRows=-1,this._isViewInited=!1,this._handleFocusEvent=e=>{this._hasFocus="focus"===e.type},this._document=r,this._textareaElement=this._elementRef.nativeElement}_setMinHeight(){const e=this.minRows&&this._cachedLineHeight?this.minRows*this._cachedLineHeight+"px":null;e&&(this._textareaElement.style.minHeight=e)}_setMaxHeight(){const e=this.maxRows&&this._cachedLineHeight?this.maxRows*this._cachedLineHeight+"px":null;e&&(this._textareaElement.style.maxHeight=e)}ngAfterViewInit(){this._platform.isBrowser&&(this._initialHeight=this._textareaElement.style.height,this.resizeToFitContent(),this._ngZone.runOutsideAngular((()=>{const e=this._getWindow();Ue(e,"resize").pipe(we(16),De(this._destroyed)).subscribe((()=>this.resizeToFitContent(!0))),this._textareaElement.addEventListener("focus",this._handleFocusEvent),this._textareaElement.addEventListener("blur",this._handleFocusEvent)})),this._isViewInited=!0,this.resizeToFitContent(!0))}ngOnDestroy(){this._textareaElement.removeEventListener("focus",this._handleFocusEvent),this._textareaElement.removeEventListener("blur",this._handleFocusEvent),this._destroyed.next(),this._destroyed.complete()}_cacheTextareaLineHeight(){if(this._cachedLineHeight)return;let e=this._textareaElement.cloneNode(!1);e.rows=1,e.style.position="absolute",e.style.visibility="hidden",e.style.border="none",e.style.padding="0",e.style.height="",e.style.minHeight="",e.style.maxHeight="",e.style.overflow="hidden",this._textareaElement.parentNode.appendChild(e),this._cachedLineHeight=e.clientHeight,e.remove(),this._setMinHeight(),this._setMaxHeight()}_measureScrollHeight(){const e=this._textareaElement,t=e.style.marginBottom||"",n=this._platform.FIREFOX,r=n&&this._hasFocus,o=n?"cdk-textarea-autosize-measuring-firefox":"cdk-textarea-autosize-measuring";r&&(e.style.marginBottom=`${e.clientHeight}px`),e.classList.add(o);const a=e.scrollHeight-4;return e.classList.remove(o),r&&(e.style.marginBottom=t),a}_cacheTextareaPlaceholderHeight(){if(!this._isViewInited||null!=this._cachedPlaceholderHeight)return;if(!this.placeholder)return void(this._cachedPlaceholderHeight=0);const e=this._textareaElement.value;this._textareaElement.value=this._textareaElement.placeholder,this._cachedPlaceholderHeight=this._measureScrollHeight(),this._textareaElement.value=e}ngDoCheck(){this._platform.isBrowser&&this.resizeToFitContent()}resizeToFitContent(e=!1){if(!this._enabled)return;if(this._cacheTextareaLineHeight(),this._cacheTextareaPlaceholderHeight(),!this._cachedLineHeight)return;const t=this._elementRef.nativeElement,n=t.value;if(!e&&this._minRows===this._previousMinRows&&n===this._previousValue)return;const r=this._measureScrollHeight(),o=Math.max(r,this._cachedPlaceholderHeight||0);t.style.height=`${o}px`,this._ngZone.runOutsideAngular((()=>{"undefined"!=typeof requestAnimationFrame?requestAnimationFrame((()=>this._scrollToCaretPosition(t))):setTimeout((()=>this._scrollToCaretPosition(t)))})),this._previousValue=n,this._previousMinRows=this._minRows}reset(){void 0!==this._initialHeight&&(this._textareaElement.style.height=this._initialHeight)}_noopInputHandler(){}_getDocument(){return this._document||document}_getWindow(){return this._getDocument().defaultView||window}_scrollToCaretPosition(e){const{selectionStart:t,selectionEnd:n}=e;!this._destroyed.isStopped&&this._hasFocus&&e.setSelectionRange(t,n)}}Ar.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.0-rc.0",ngImport:t,type:Ar,deps:[{token:t.ElementRef},{token:pt.Platform},{token:t.NgZone},{token:j,optional:!0}],target:t.ɵɵFactoryTarget.Directive}),Ar.ɵdir=t.ɵɵngDeclareDirective({minVersion:"14.0.0",version:"15.2.0-rc.0",type:Ar,selector:"textarea[cdkTextareaAutosize]",inputs:{minRows:["cdkAutosizeMinRows","minRows"],maxRows:["cdkAutosizeMaxRows","maxRows"],enabled:["cdkTextareaAutosize","enabled"],placeholder:"placeholder"},host:{attributes:{rows:"1"},listeners:{input:"_noopInputHandler()"},classAttribute:"cdk-textarea-autosize"},exportAs:["cdkTextareaAutosize"],ngImport:t}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.0-rc.0",ngImport:t,type:Ar,decorators:[{type:d,args:[{selector:"textarea[cdkTextareaAutosize]",exportAs:"cdkTextareaAutosize",host:{class:"cdk-textarea-autosize",rows:"1","(input)":"_noopInputHandler()"}}]}],ctorParameters:function(){return[{type:t.ElementRef},{type:pt.Platform},{type:t.NgZone},{type:void 0,decorators:[{type:p},{type:m,args:[j]}]}]},propDecorators:{minRows:[{type:i,args:["cdkAutosizeMinRows"]}],maxRows:[{type:i,args:["cdkAutosizeMaxRows"]}],enabled:[{type:i,args:["cdkTextareaAutosize"]}],placeholder:[{type:i}]}}); - /** - * @license - * Copyright Google LLC All Rights Reserved. - * - * Use of this source code is governed by an MIT-style license that can be - * found in the LICENSE file at https://angular.io/license - */ - class Mr{}Mr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.0-rc.0",ngImport:t,type:Mr,deps:[],target:t.ɵɵFactoryTarget.NgModule}),Mr.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.0-rc.0",ngImport:t,type:Mr,declarations:[qr,Ar],exports:[qr,Ar]}),Mr.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.0-rc.0",ngImport:t,type:Mr}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.0-rc.0",ngImport:t,type:Mr,decorators:[{type:c,args:[{declarations:[qr,Ar],exports:[qr,Ar]}]}]});class Er extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.mailBodyTypes=[{name:"tb.mail-body-type.plain-text",description:"tb.mail-body-type.plain-text-description",value:"false"},{name:"tb.mail-body-type.html",description:"tb.mail-body-type.html-text-description",value:"true"},{name:"tb.mail-body-type.use-body-type-template",description:"tb.mail-body-type.dynamic-text-description",value:"dynamic"}]}configForm(){return this.toEmailConfigForm}onConfigurationSet(e){this.toEmailConfigForm=this.fb.group({fromTemplate:[e?e.fromTemplate:null,[O.required]],toTemplate:[e?e.toTemplate:null,[O.required]],ccTemplate:[e?e.ccTemplate:null,[]],bccTemplate:[e?e.bccTemplate:null,[]],subjectTemplate:[e?e.subjectTemplate:null,[O.required]],mailBodyType:[e?e.mailBodyType:null],isHtmlTemplate:[e?e.isHtmlTemplate:null,[O.required]],bodyTemplate:[e?e.bodyTemplate:null,[O.required]]})}prepareInputConfig(e){return{fromTemplate:ie(e?.fromTemplate)?e.fromTemplate:null,toTemplate:ie(e?.toTemplate)?e.toTemplate:null,ccTemplate:ie(e?.ccTemplate)?e.ccTemplate:null,bccTemplate:ie(e?.bccTemplate)?e.bccTemplate:null,subjectTemplate:ie(e?.subjectTemplate)?e.subjectTemplate:null,mailBodyType:ie(e?.mailBodyType)?e.mailBodyType:null,isHtmlTemplate:ie(e?.isHtmlTemplate)?e.isHtmlTemplate:null,bodyTemplate:ie(e?.bodyTemplate)?e.bodyTemplate:null}}updateValidators(e){"dynamic"===this.toEmailConfigForm.get("mailBodyType").value?this.toEmailConfigForm.get("isHtmlTemplate").enable({emitEvent:!1}):this.toEmailConfigForm.get("isHtmlTemplate").disable({emitEvent:!1}),this.toEmailConfigForm.get("isHtmlTemplate").updateValueAndValidity({emitEvent:e})}validatorTriggers(){return["mailBodyType"]}getBodyTypeName(){return this.mailBodyTypes.find((e=>e.value===this.toEmailConfigForm.get("mailBodyType").value)).name}}e("ToEmailConfigComponent",Er),Er.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Er,deps:[{token:P.Store},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Er.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Er,selector:"tb-transformation-node-to-email-config",usesInheritance:!0,ngImport:t,template:'
\n
\n
tb.rulenode.email-sender
\n
\n \n tb.rulenode.from-template\n \n \n {{ \'tb.rulenode.email-from-template-hint\' | translate }}\n \n \n
\n
\n
\n
\n \n {{ \'tb.rulenode.from-template-required\' | translate }}\n \n
\n
\n
\n
\n
\n
tb.rulenode.recipients
\n \n \n
\n
\n \n tb.rulenode.to-template\n \n \n {{ \'tb.rulenode.to-template-required\' | translate }}\n \n \n \n tb.rulenode.cc-template\n \n \n \n tb.rulenode.bcc-template\n \n \n
\n
\n
\n
tb.rulenode.message-subject-and-content
\n \n \n
\n \n tb.rulenode.subject-template\n \n \n {{ \'tb.rulenode.subject-template-required\' | translate }}\n \n \n \n tb.rulenode.mail-body-type\n \n \n \n {{ getBodyTypeName() | translate }}\n \n \n \n \n {{ type.name | translate }}\n \n
\n \n {{ type.description | translate }}\n \n
\n
\n
\n \n tb.rulenode.body-type-template\n \n tb.mail-body-type.after-template-evaluation-hint\n \n \n tb.rulenode.body-template\n \n \n {{ \'tb.rulenode.body-template-required\' | translate }}\n \n \n
\n
\n
\n',styles:[":host .input-bottom-double-hint{display:inline-flex}:host .input-bottom-double-hint .see-example{flex-shrink:0;padding-right:16px}:host textarea.tb-enable-vertical-resize{resize:vertical}\n"],dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:He.HelpPopupComponent,selector:"[tb-help-popup], [tb-help-popup-content]",inputs:["tb-help-popup","tb-help-popup-content","trigger-text","trigger-style","tb-help-popup-placement","tb-help-popup-style","hintMode"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Ar,selector:"textarea[cdkTextareaAutosize]",inputs:["cdkAutosizeMinRows","cdkAutosizeMaxRows","cdkTextareaAutosize","placeholder"],exportAs:["cdkTextareaAutosize"]},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"directive",type:X.MatSelectTrigger,selector:"mat-select-trigger"},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:Ne.MatListItemTitle,selector:"[matListItemTitle]"},{kind:"directive",type:Ne.MatListItemMeta,selector:"[matListItemMeta]"},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Nn,selector:"tb-example-hint",inputs:["hintText","popupHelpLink","textAlign"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Er,decorators:[{type:n,args:[{selector:"tb-transformation-node-to-email-config",template:'
\n
\n
tb.rulenode.email-sender
\n
\n \n tb.rulenode.from-template\n \n \n {{ \'tb.rulenode.email-from-template-hint\' | translate }}\n \n \n
\n
\n
\n
\n \n {{ \'tb.rulenode.from-template-required\' | translate }}\n \n
\n
\n
\n
\n
\n
tb.rulenode.recipients
\n \n \n
\n
\n \n tb.rulenode.to-template\n \n \n {{ \'tb.rulenode.to-template-required\' | translate }}\n \n \n \n tb.rulenode.cc-template\n \n \n \n tb.rulenode.bcc-template\n \n \n
\n
\n
\n
tb.rulenode.message-subject-and-content
\n \n \n
\n \n tb.rulenode.subject-template\n \n \n {{ \'tb.rulenode.subject-template-required\' | translate }}\n \n \n \n tb.rulenode.mail-body-type\n \n \n \n {{ getBodyTypeName() | translate }}\n \n \n \n \n {{ type.name | translate }}\n \n
\n \n {{ type.description | translate }}\n \n
\n
\n
\n \n tb.rulenode.body-type-template\n \n tb.mail-body-type.after-template-evaluation-hint\n \n \n tb.rulenode.body-template\n \n \n {{ \'tb.rulenode.body-template-required\' | translate }}\n \n \n
\n
\n
\n',styles:[":host .input-bottom-double-hint{display:inline-flex}:host .input-bottom-double-hint .see-example{flex-shrink:0;padding-right:16px}:host textarea.tb-enable-vertical-resize{resize:vertical}\n"]}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder}]}});class Gr extends f{constructor(e,t,n){super(e),this.store=e,this.fb=t,this.translate=n,this.copyFrom=[],this.translation=tn;for(const e of this.translation.keys())this.copyFrom.push({value:e,name:this.translate.instant(this.translation.get(e))})}onConfigurationSet(e){this.copyKeysConfigForm=this.fb.group({copyFrom:[e.copyFrom,[O.required]],keys:[e?e.keys:null,[O.required]]})}configForm(){return this.copyKeysConfigForm}prepareInputConfig(e){let t;return t=ie(e?.fromMetadata)?e.copyFrom?en.METADATA:en.DATA:ie(e?.copyFrom)?e.copyFrom:en.DATA,{keys:ie(e?.keys)?e.keys:null,copyFrom:t}}}e("CopyKeysConfigComponent",Gr),Gr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Gr,deps:[{token:P.Store},{token:R.FormBuilder},{token:Z.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Gr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Gr,selector:"tb-transformation-node-copy-keys-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n help\n \n \n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"component",type:Ze.StringItemsListComponent,selector:"tb-string-items-list",inputs:["required","disabled","label","placeholder","hint","requiredText","floatLabel","appearance","editable","subscriptSizing","predefinedValues"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:Y.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:On,selector:"tb-msg-metadata-chip",inputs:["labelText","translation"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Gr,decorators:[{type:n,args:[{selector:"tb-transformation-node-copy-keys-config",template:'
\n \n \n \n \n help\n \n \n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder},{type:Z.TranslateService}]}});class Dr extends f{constructor(e,t,n){super(e),this.store=e,this.fb=t,this.translate=n,this.renameIn=[],this.translation=rn;for(const e of this.translation.keys())this.renameIn.push({value:e,name:this.translate.instant(this.translation.get(e))})}configForm(){return this.renameKeysConfigForm}onConfigurationSet(e){this.renameKeysConfigForm=this.fb.group({renameIn:[e?e.renameIn:null,[O.required]],renameKeysMapping:[e?e.renameKeysMapping:null,[O.required]]})}prepareInputConfig(e){let t;return t=ie(e?.fromMetadata)?e.fromMetadata?en.METADATA:en.DATA:ie(e?.renameIn)?e?.renameIn:en.DATA,{renameKeysMapping:ie(e?.renameKeysMapping)?e.renameKeysMapping:null,renameIn:t}}}e("RenameKeysConfigComponent",Dr),Dr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Dr,deps:[{token:P.Store},{token:R.FormBuilder},{token:Z.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Dr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Dr,selector:"tb-transformation-node-rename-keys-config",usesInheritance:!0,ngImport:t,template:'
\n
tb.rulenode.rename-keys-in
\n
\n
\n \n \n {{ data.name }}\n \n \n
\n
\n \n \n
\n',styles:[":host .fetch-to-data-toggle{max-width:420px;width:100%}:host .fx-centered{display:flex;width:100%;justify-content:space-around}\n"],dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"directive",type:Xe.ToggleOption,selector:"tb-toggle-option",inputs:["value"]},{kind:"component",type:et.ToggleSelectComponent,selector:"tb-toggle-select",inputs:["disabled","selectMediaBreakpoint","appearance","disablePagination"]},{kind:"component",type:Sn,selector:"tb-kv-map-config",inputs:["disabled","uniqueKeyValuePairValidator","labelText","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","popupHelpLink","required"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Dr,decorators:[{type:n,args:[{selector:"tb-transformation-node-rename-keys-config",template:'
\n
tb.rulenode.rename-keys-in
\n
\n
\n \n \n {{ data.name }}\n \n \n
\n
\n \n \n
\n',styles:[":host .fetch-to-data-toggle{max-width:420px;width:100%}:host .fx-centered{display:flex;width:100%;justify-content:space-around}\n"]}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder},{type:Z.TranslateService}]}});class wr extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.jsonPathConfigForm}onConfigurationSet(e){this.jsonPathConfigForm=this.fb.group({jsonPath:[e?e.jsonPath:null,[O.required]]})}}e("NodeJsonPathConfigComponent",wr),wr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:wr,deps:[{token:P.Store},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),wr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:wr,selector:"tb-transformation-node-json-path-config",usesInheritance:!0,ngImport:t,template:"
\n \n {{ 'tb.rulenode.json-path-expression' | translate }}\n \n {{ 'tb.rulenode.json-path-expression-hint' | translate }}\n {{ 'tb.rulenode.json-path-expression-required' | translate }}\n \n
\n",dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:wr,decorators:[{type:n,args:[{selector:"tb-transformation-node-json-path-config",template:"
\n \n {{ 'tb.rulenode.json-path-expression' | translate }}\n \n {{ 'tb.rulenode.json-path-expression-hint' | translate }}\n {{ 'tb.rulenode.json-path-expression-required' | translate }}\n \n
\n"}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder}]}});class Vr extends f{constructor(e,t,n){super(e),this.store=e,this.fb=t,this.translate=n,this.deleteFrom=[],this.translation=nn;for(const e of this.translation.keys())this.deleteFrom.push({value:e,name:this.translate.instant(this.translation.get(e))})}onConfigurationSet(e){this.deleteKeysConfigForm=this.fb.group({deleteFrom:[e.deleteFrom,[O.required]],keys:[e?e.keys:null,[O.required]]})}prepareInputConfig(e){let t;return t=ie(e?.fromMetadata)?e.fromMetadata?en.METADATA:en.DATA:ie(e?.deleteFrom)?e?.deleteFrom:en.DATA,{keys:ie(e?.keys)?e.keys:null,deleteFrom:t}}configForm(){return this.deleteKeysConfigForm}}e("DeleteKeysConfigComponent",Vr),Vr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Vr,deps:[{token:P.Store},{token:R.FormBuilder},{token:Z.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Vr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Vr,selector:"tb-transformation-node-delete-keys-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n help\n \n \n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"component",type:Ze.StringItemsListComponent,selector:"tb-string-items-list",inputs:["required","disabled","label","placeholder","hint","requiredText","floatLabel","appearance","editable","subscriptSizing","predefinedValues"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:Y.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:On,selector:"tb-msg-metadata-chip",inputs:["labelText","translation"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Vr,decorators:[{type:n,args:[{selector:"tb-transformation-node-delete-keys-config",template:'
\n \n \n \n \n help\n \n \n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder},{type:Z.TranslateService}]}});class Pr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.deduplicationStrategie=Gt,this.deduplicationStrategies=Object.keys(this.deduplicationStrategie),this.deduplicationStrategiesTranslations=Dt}configForm(){return this.deduplicationConfigForm}onConfigurationSet(e){this.deduplicationConfigForm=this.fb.group({interval:[ie(e?.interval)?e.interval:null,[O.required,O.min(1)]],strategy:[ie(e?.strategy)?e.strategy:null,[O.required]],outMsgType:[ie(e?.outMsgType)?e.outMsgType:null,[O.required]],maxPendingMsgs:[ie(e?.maxPendingMsgs)?e.maxPendingMsgs:null,[O.required,O.min(1),O.max(1e3)]],maxRetries:[ie(e?.maxRetries)?e.maxRetries:null,[O.required,O.min(0),O.max(100)]]})}prepareInputConfig(e){return e||(e={}),e.outMsgType||(e.outMsgType="POST_TELEMETRY_REQUEST"),super.prepareInputConfig(e)}updateValidators(e){this.deduplicationConfigForm.get("strategy").value===this.deduplicationStrategie.ALL?this.deduplicationConfigForm.get("outMsgType").enable({emitEvent:!1}):this.deduplicationConfigForm.get("outMsgType").disable({emitEvent:!1}),this.deduplicationConfigForm.get("outMsgType").updateValueAndValidity({emitEvent:e})}validatorTriggers(){return["strategy"]}}e("DeduplicationConfigComponent",Pr),Pr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Pr,deps:[{token:P.Store},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Pr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Pr,selector:"tb-action-node-msg-deduplication-config",usesInheritance:!0,ngImport:t,template:'
\n \n {{\'tb.rulenode.interval\' | translate}}\n \n \n {{\'tb.rulenode.interval-required\' | translate}}\n \n \n {{\'tb.rulenode.interval-min-error\' | translate}}\n \n help\n \n
\n
\n
tb.rulenode.strategy
\n \n \n {{ deduplicationStrategiesTranslations.get(strategy) | translate }}\n \n \n \n \n \n \n \n \n
\n \n \n
\n
\n
\n \n \n tb.rulenode.advanced-settings\n \n
\n \n {{\'tb.rulenode.max-pending-msgs\' | translate}}\n \n \n {{\'tb.rulenode.max-pending-msgs-required\' | translate}}\n \n \n {{\'tb.rulenode.max-pending-msgs-max-error\' | translate}}\n \n \n {{\'tb.rulenode.max-pending-msgs-min-error\' | translate}}\n \n help\n \n \n {{\'tb.rulenode.max-retries\' | translate}}\n \n \n {{\'tb.rulenode.max-retries-required\' | translate}}\n \n \n {{\'tb.rulenode.max-retries-max-error\' | translate}}\n \n \n {{\'tb.rulenode.max-retries-min-error\' | translate}}\n \n help\n \n
\n
\n
\n
\n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Y.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:Je.MatExpansionPanel,selector:"mat-expansion-panel",inputs:["disabled","expanded","hideToggle","togglePosition"],outputs:["opened","closed","expandedChange","afterExpand","afterCollapse"],exportAs:["matExpansionPanel"]},{kind:"component",type:Je.MatExpansionPanelHeader,selector:"mat-expansion-panel-header",inputs:["tabIndex","expandedHeight","collapsedHeight"]},{kind:"directive",type:Je.MatExpansionPanelTitle,selector:"mat-panel-title"},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"directive",type:Xe.ToggleOption,selector:"tb-toggle-option",inputs:["value"]},{kind:"component",type:et.ToggleSelectComponent,selector:"tb-toggle-select",inputs:["disabled","selectMediaBreakpoint","appearance","disablePagination"]},{kind:"component",type:Rn,selector:"tb-output-message-type-autocomplete",inputs:["subscriptSizing","disabled","required"]},{kind:"component",type:Nn,selector:"tb-example-hint",inputs:["hintText","popupHelpLink","textAlign"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Pr,decorators:[{type:n,args:[{selector:"tb-action-node-msg-deduplication-config",template:'
\n \n {{\'tb.rulenode.interval\' | translate}}\n \n \n {{\'tb.rulenode.interval-required\' | translate}}\n \n \n {{\'tb.rulenode.interval-min-error\' | translate}}\n \n help\n \n
\n
\n
tb.rulenode.strategy
\n \n \n {{ deduplicationStrategiesTranslations.get(strategy) | translate }}\n \n \n \n \n \n \n \n \n
\n \n \n
\n
\n
\n \n \n tb.rulenode.advanced-settings\n \n
\n \n {{\'tb.rulenode.max-pending-msgs\' | translate}}\n \n \n {{\'tb.rulenode.max-pending-msgs-required\' | translate}}\n \n \n {{\'tb.rulenode.max-pending-msgs-max-error\' | translate}}\n \n \n {{\'tb.rulenode.max-pending-msgs-min-error\' | translate}}\n \n help\n \n \n {{\'tb.rulenode.max-retries\' | translate}}\n \n \n {{\'tb.rulenode.max-retries-required\' | translate}}\n \n \n {{\'tb.rulenode.max-retries-max-error\' | translate}}\n \n \n {{\'tb.rulenode.max-retries-min-error\' | translate}}\n \n help\n \n
\n
\n
\n
\n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder}]}});class Rr{}e("RulenodeCoreConfigTransformModule",Rr),Rr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Rr,deps:[],target:t.ɵɵFactoryTarget.NgModule}),Rr.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.10",ngImport:t,type:Rr,declarations:[Tr,Ir,Er,Gr,Dr,wr,Vr,Pr],imports:[$,M,Un],exports:[Tr,Ir,Er,Gr,Dr,wr,Vr,Pr]}),Rr.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Rr,imports:[$,M,Un]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Rr,decorators:[{type:c,args:[{declarations:[Tr,Ir,Er,Gr,Dr,wr,Vr,Pr],imports:[$,M,Un],exports:[Tr,Ir,Er,Gr,Dr,wr,Vr,Pr]}]}]});class Or extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.entityType=F}configForm(){return this.ruleChainInputConfigForm}onConfigurationSet(e){this.ruleChainInputConfigForm=this.fb.group({ruleChainId:[e?e.ruleChainId:null,[O.required]]})}}e("RuleChainInputComponent",Or),Or.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Or,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Or.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Or,selector:"tb-flow-node-rule-chain-input-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n
\n',dependencies:[{kind:"component",type:lt.EntityAutocompleteComponent,selector:"tb-entity-autocomplete",inputs:["entityType","entitySubtype","excludeEntityIds","labelText","requiredText","useFullEntityId","appearance","required","disabled"],outputs:["entityChanged"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Or,decorators:[{type:n,args:[{selector:"tb-flow-node-rule-chain-input-config",template:'
\n \n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class _r extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.ruleChainOutputConfigForm}onConfigurationSet(e){this.ruleChainOutputConfigForm=this.fb.group({})}}e("RuleChainOutputComponent",_r),_r.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:_r,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),_r.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:_r,selector:"tb-flow-node-rule-chain-output-config",usesInheritance:!0,ngImport:t,template:'
\n
\n
\n',dependencies:[{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:_r,decorators:[{type:n,args:[{selector:"tb-flow-node-rule-chain-output-config",template:'
\n
\n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class Br{}e("RuleNodeCoreConfigFlowModule",Br),Br.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Br,deps:[],target:t.ɵɵFactoryTarget.NgModule}),Br.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.10",ngImport:t,type:Br,declarations:[Or,_r],imports:[$,M,Un],exports:[Or,_r]}),Br.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Br,imports:[$,M,Un]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Br,decorators:[{type:c,args:[{declarations:[Or,_r],imports:[$,M,Un],exports:[Or,_r]}]}]});class Kr{constructor(e){!function(e){e.setTranslation("en_US",{tb:{rulenode:{id:"Id","additional-info":"Additional Info","advanced-settings":"Advanced settings","create-entity-if-not-exists":"Create new entity if not exists","create-entity-if-not-exists-hint":"Create a new entity set above if it does not exist.","entity-name-pattern":"Name pattern","entity-name-pattern-required":"Name pattern is required","entity-name-pattern-hint":"Name pattern field support templatization. Use $[messageKey] to extract value from the message and ${metadataKey} to extract value from the metadata.","copy-message-type":"Copy message type","entity-type-pattern":"Type pattern","entity-type-pattern-required":"Type pattern is required","message-type-value":"Message type value","message-type-value-required":"Message type value is required","message-type-value-max-length":"Message type value should be less than 256","output-message-type":"Output message type","entity-cache-expiration":"Entities cache expiration time (sec)","entity-cache-expiration-hint":"Specifies maximum time interval allowed to store found entity records. 0 value means that records will never expire.","entity-cache-expiration-required":"Entities cache expiration time is required.","entity-cache-expiration-range":"Entities cache expiration time should be greater than or equal to 0.","customer-name-pattern":"Customer name pattern","customer-name-pattern-required":"Customer name pattern is required","create-customer-if-not-exists":"Create new customer if not exists","customer-cache-expiration":"Customers cache expiration time (sec)","customer-cache-expiration-hint":"Specifies maximum time interval allowed to store found customer records. 0 value means that records will never expire.","customer-cache-expiration-required":"Customers cache expiration time is required.","customer-cache-expiration-range":"Customers cache expiration time should be greater than or equal to 0.","interval-start":"Interval start","interval-end":"Interval end","time-unit":"Time unit","fetch-mode":"Fetch mode","order-by-timestamp":"Order by timestamp",limit:"Limit","limit-hint":"Min limit value is 2, max - 1000. If you want to fetch a single entry, select fetch mode 'First' or 'Last'.","limit-required":"Limit is required.","limit-range":"Limit should be in a range from 2 to 1000.","time-unit-milliseconds":"Milliseconds","time-unit-seconds":"Seconds","time-unit-minutes":"Minutes","time-unit-hours":"Hours","time-unit-days":"Days","time-value-range":"Allowing range from 1 to 2147483647.","start-interval-value-required":"Interval start is required.","end-interval-value-required":"Interval end is required.",filter:"Filter",switch:"Switch","math-templatization-tooltip":"This field support templatization. Use $[messageKey] to extract value from the message and ${metadataKey} to extract value from the metadata.","add-message-type":"Add message type","select-message-types-required":"At least one message type should be selected.","select-message-types":"Select message types","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","attributes-keys":"Attributes keys","attributes-keys-required":"Attributes keys are required","notify-device":"Force notification to the device","send-attributes-updated-notification":"Send attributes updated notification","send-attributes-updated-notification-hint":"Send notification about updated attributes as a separate message to the rule engine queue.","send-attributes-deleted-notification":"Send attributes deleted notification","send-attributes-deleted-notification-hint":"Send notification about deleted attributes as a separate message to the rule engine queue.","update-attributes-only-on-value-change":"Save attributes only if the value changes","update-attributes-only-on-value-change-hint":"Updates the attributes on every incoming message disregarding if their value has changed. Increases API usage and reduces performance.","update-attributes-only-on-value-change-hint-enabled":"Updates the attributes only if their value has changed. If the value is not changed, no update to the attribute timestamp nor attribute change notification will be sent.","fetch-credentials-to-metadata":"Fetch credentials to metadata","notify-device-on-update-hint":"If enabled, force notification to the device about shared attributes update. If disabled, the notification behavior is controlled by the 'notifyDevice' parameter from the incoming message metadata. To turn off the notification, the message metadata must contain the 'notifyDevice' parameter set to 'false'. Any other case will trigger the notification to the device.","notify-device-on-delete-hint":"If enabled, force notification to the device about shared attributes removal. If disabled, the notification behavior is controlled by the 'notifyDevice' parameter from the incoming message metadata. To turn on the notification, the message metadata must contain the 'notifyDevice' parameter set to 'true'. In any other case, the notification will not be triggered to the device.","latest-timeseries":"Latest time-series data keys","timeseries-keys":"Timeseries keys","timeseries-keys-required":"At least one timeseries key should be selected.","add-timeseries-key":"Add timeseries key","add-message-field":"Add message field","relation-search-parameters":"Relation search parameters","add-metadata-field":"Add metadata field","data-keys":"Message field names","copy-from":"Copy from","data-to-metadata":"Data to metadata","metadata-to-data":"Metadata to data","use-regular-expression-hint":"Use regular expression to copy keys by pattern.\n\nTips & tricks:\nPress 'Enter' to complete field name input.\nPress 'Backspace' to delete field name. Multiple field names supported.",interval:"Interval","interval-required":"Interval is required","interval-hint":"Deduplication interval in seconds.","interval-min-error":"Min allowed value is 1","max-pending-msgs":"Max pending messages","max-pending-msgs-hint":"Maximum number of messages that are stored in memory for each unique deduplication id.","max-pending-msgs-required":"Max pending messages is required","max-pending-msgs-max-error":"Max allowed value is 1000","max-pending-msgs-min-error":"Min allowed value is 1","max-retries":"Max retries","max-retries-required":"Max retries is required","max-retries-hint":"Maximum number of retries to push the deduplicated messages into the queue. 10 seconds delay is used between retries","max-retries-max-error":"Max allowed value is 100","max-retries-min-error":"Min allowed value is 0",strategy:"Strategy","strategy-required":"Strategy is required","strategy-all-hint":"Return all messages that arrived during deduplication period as a single JSON array message. Where each element represents object with msg and metadata inner properties.","strategy-first-hint":"Return first message that arrived during deduplication period.","strategy-last-hint":"Return last message that arrived during deduplication period.",first:"First",last:"Last",all:"All","output-msg-type-hint":"The message type of the deduplication result.","queue-name-hint":"The queue name where the deduplication result will be published.",keys:"Keys","keys-required":"Keys are required","rename-keys-in":"Rename keys in",data:"Data",message:"Message",metadata:"Metadata","current-key-name":"Current key name","key-name-required":"Key name is required","new-key-name":"New key name","new-key-name-required":"New key name is required","metadata-keys":"Metadata field names","json-path-expression":"JSON path expression","json-path-expression-required":"JSON path expression is required","json-path-expression-hint":"JSONPath specifies a path to an element or a set of elements in a JSON structure. '$' represents the root object or array.","relations-query":"Relations query","device-relations-query":"Device relations query","max-relation-level":"Max relation level","max-relation-level-error":"Value should be greater than 0 or unspecified.","relation-type":"Relation type","relation-type-pattern":"Relation type pattern","relation-type-pattern-required":"Relation type pattern is required","relation-types-list":"Relation types to propagate","relation-types-list-hint":"If Propagate relation types are not selected, alarms will be propagated without filtering by relation type.","unlimited-level":"Unlimited level","latest-telemetry":"Latest telemetry","add-telemetry-key":"Add telemetry key","delete-from":"Delete from","use-regular-expression-delete-hint":"Use regular expression to delete keys by pattern.\n\nTips & tricks:\nPress 'Enter' to complete field name input.\nPress 'Backspace' to delete field name.\nMultiple field names supported.","fetch-into":"Fetch into","attr-mapping":"Attributes mapping:","source-attribute":"Source attribute key","source-attribute-required":"Source attribute key is required.","source-telemetry":"Source telemetry key","source-telemetry-required":"Source telemetry key is required.","target-key":"Target key","target-key-required":"Target key is required.","attr-mapping-required":"At least one mapping entry should be specified.","fields-mapping":"Fields mapping","relations-query-config-direction-suffix":"originator","profile-name":"Profile name","fetch-circle-parameter-info-from-metadata-hint":'Metadata field \'{{perimeterKeyName}}\' should be defined in next format: {"latitude":48.196, "longitude":24.6532, "radius":100.0, "radiusUnit":"METER"}',"fetch-poligon-parameter-info-from-metadata-hint":"Metadata field '{{perimeterKeyName}}' should be defined in next format: [[48.19736,24.65235],[48.19800,24.65060],...,[48.19849,24.65420]]","short-templatization-tooltip":"Use $[messageKey] to extract value from the message and ${metadataKey} to extract value from the metadata.","fields-mapping-required":"At least one field mapping should be specified.","at-least-one-field-required":"At least one input field must have a value(s) provided.","originator-fields-sv-map-hint":"Target key fields support templatization. Use $[messageKey] to extract value from the message and ${metadataKey} to extract value from the metadata.","sv-map-hint":"Only target key fields support templatization. Use $[messageKey] to extract value from the message and ${metadataKey} to extract value from the metadata.","source-field":"Source field","source-field-required":"Source field is required.","originator-source":"Originator source","new-originator":"New originator","originator-customer":"Customer","originator-tenant":"Tenant","originator-related":"Related entity","originator-alarm-originator":"Alarm Originator","originator-entity":"Entity by name pattern","clone-message":"Clone message",transform:"Transform","default-ttl":"Default TTL in seconds","default-ttl-required":"Default TTL is required.","min-default-ttl-message":"Only 0 minimum TTL is allowed.","message-count":"Message count (0 - unlimited)","message-count-required":"Message count is required.","min-message-count-message":"Only 0 minimum message count is allowed.","period-seconds":"Period in seconds","period-seconds-required":"Period is required.","use-metadata-period-in-seconds-patterns":"Use period in seconds pattern","use-metadata-period-in-seconds-patterns-hint":"If selected, rule node use period in seconds interval pattern from message metadata or data assuming that intervals are in the seconds.","period-in-seconds-pattern":"Period in seconds pattern","period-in-seconds-pattern-required":"Period in seconds pattern is required","min-period-seconds-message":"Only 1 second minimum period is allowed.",originator:"Originator","message-body":"Message body","message-metadata":"Message metadata",generate:"Generate","test-generator-function":"Test generator function",generator:"Generator","test-filter-function":"Test filter function","test-switch-function":"Test switch function","test-transformer-function":"Test transformer function",transformer:"Transformer","alarm-create-condition":"Alarm create condition","test-condition-function":"Test condition function","alarm-clear-condition":"Alarm clear condition","alarm-details-builder":"Alarm details builder","test-details-function":"Test details function","alarm-type":"Alarm type","select-entity-types":"Select entity types","alarm-type-required":"Alarm type is required.","alarm-severity":"Alarm severity","alarm-severity-required":"Alarm severity is required","alarm-severity-pattern":"Alarm severity pattern","alarm-status-filter":"Alarm status filter","alarm-status-list-empty":"Alarm status list is empty","no-alarm-status-matching":"No alarm status matching were found.",propagate:"Propagate alarm to related entities","propagate-to-owner":"Propagate alarm to entity owner (Customer or Tenant)","propagate-to-tenant":"Propagate alarm to Tenant",condition:"Condition",details:"Details","to-string":"To string","test-to-string-function":"Test to string function","from-template":"From","from-template-required":"From is required","message-to-metadata":"Message to metadata","metadata-to-message":"Metadata to message","from-message":"From message","from-metadata":"From metadata","to-template":"To","to-template-required":"To Template is required","mail-address-list-template-hint":'Comma separated address list, use ${metadataKey} for value from metadata, $[messageKey] for value from message body',"cc-template":"Cc","bcc-template":"Bcc","subject-template":"Subject","subject-template-required":"Subject Template is required","body-template":"Body","body-template-required":"Body Template is required","dynamic-mail-body-type":"Dynamic mail body type","mail-body-type":"Mail body type","body-type-template":"Body type template","request-id-metadata-attribute":"Request Id Metadata attribute name","timeout-sec":"Timeout in seconds","timeout-required":"Timeout is required","min-timeout-message":"Only 0 minimum timeout value is allowed.","endpoint-url-pattern":"Endpoint URL pattern","endpoint-url-pattern-required":"Endpoint URL pattern is required","request-method":"Request method","use-simple-client-http-factory":"Use simple client HTTP factory","ignore-request-body":"Without request body","parse-to-plain-text":"Parse to plain text","parse-to-plain-text-hint":'If selected, request body message payload will be transformed from JSON string to plain text, e.g. msg = "Hello,\\t\\"world\\"" will be parsed to Hello, "world"',"read-timeout":"Read timeout in millis","read-timeout-hint":"The value of 0 means an infinite timeout","max-parallel-requests-count":"Max number of parallel requests","max-parallel-requests-count-hint":"The value of 0 specifies no limit in parallel processing",headers:"Headers","headers-hint":'Use ${metadataKey} for value from metadata, $[messageKey] for value from message body in header/value fields',header:"Header","header-required":"Header is required",value:"Value","value-required":"Value is required","topic-pattern":"Topic pattern","key-pattern":"Key pattern","key-pattern-hint":"Optional. If a valid partition number is specified, it will be used when sending the record. If no partition is specified, the key will be used instead. If neither is specified, a partition will be assigned in a round-robin fashion.","topic-pattern-required":"Topic pattern is required",topic:"Topic","topic-required":"Topic is required","bootstrap-servers":"Bootstrap servers","bootstrap-servers-required":"Bootstrap servers value is required","other-properties":"Other properties",key:"Key","key-required":"Key is required",retries:"Automatically retry times if fails","min-retries-message":"Only 0 minimum retries is allowed.","batch-size-bytes":"Produces batch size in bytes","min-batch-size-bytes-message":"Only 0 minimum batch size is allowed.","linger-ms":"Time to buffer locally (ms)","min-linger-ms-message":"Only 0 ms minimum value is allowed.","buffer-memory-bytes":"Client buffer max size in bytes","min-buffer-memory-message":"Only 0 minimum buffer size is allowed.",acks:"Number of acknowledgments","key-serializer":"Key serializer","key-serializer-required":"Key serializer is required","value-serializer":"Value serializer","value-serializer-required":"Value serializer is required","topic-arn-pattern":"Topic ARN pattern","topic-arn-pattern-required":"Topic ARN pattern is required","aws-access-key-id":"AWS Access Key ID","aws-access-key-id-required":"AWS Access Key ID is required","aws-secret-access-key":"AWS Secret Access Key","aws-secret-access-key-required":"AWS Secret Access Key is required","aws-region":"AWS Region","aws-region-required":"AWS Region is required","exchange-name-pattern":"Exchange name pattern","routing-key-pattern":"Routing key pattern","message-properties":"Message properties",host:"Host","host-required":"Host is required",port:"Port","port-required":"Port is required","port-range":"Port should be in a range from 1 to 65535.","virtual-host":"Virtual host",username:"Username",password:"Password","automatic-recovery":"Automatic recovery","connection-timeout-ms":"Connection timeout (ms)","min-connection-timeout-ms-message":"Only 0 ms minimum value is allowed.","handshake-timeout-ms":"Handshake timeout (ms)","min-handshake-timeout-ms-message":"Only 0 ms minimum value is allowed.","client-properties":"Client properties","queue-url-pattern":"Queue URL pattern","queue-url-pattern-required":"Queue URL pattern is required","delay-seconds":"Delay (seconds)","min-delay-seconds-message":"Only 0 seconds minimum value is allowed.","max-delay-seconds-message":"Only 900 seconds maximum value is allowed.",name:"Name","name-required":"Name is required","queue-type":"Queue type","sqs-queue-standard":"Standard","sqs-queue-fifo":"FIFO","gcp-project-id":"GCP project ID","gcp-project-id-required":"GCP project ID is required","gcp-service-account-key":"GCP service account key file","gcp-service-account-key-required":"GCP service account key file is required","pubsub-topic-name":"Topic name","pubsub-topic-name-required":"Topic name is required","message-attributes":"Message attributes","message-attributes-hint":'Use ${metadataKey} for value from metadata, $[messageKey] for value from message body in name/value fields',"connect-timeout":"Connection timeout (sec)","connect-timeout-required":"Connection timeout is required.","connect-timeout-range":"Connection timeout should be in a range from 1 to 200.","client-id":"Client ID","client-id-hint":'Optional. Leave empty for auto-generated Client ID. Be careful when specifying the Client ID. Majority of the MQTT brokers will not allow multiple connections with the same Client ID. To connect to such brokers, your mqtt Client ID must be unique. When platform is running in a micro-services mode, the copy of rule node is launched in each micro-service. This will automatically lead to multiple mqtt clients with the same ID and may cause failures of the rule node. To avoid such failures enable "Add Service ID as suffix to Client ID" option below.',"append-client-id-suffix":"Add Service ID as suffix to Client ID","client-id-suffix-hint":'Optional. Applied when "Client ID" specified explicitly. If selected then Service ID will be added to Client ID as a suffix. Helps to avoid failures when platform is running in a micro-services mode.',"device-id":"Device ID","device-id-required":"Device ID is required.","clean-session":"Clean session","enable-ssl":"Enable SSL",credentials:"Credentials","credentials-type":"Credentials type","credentials-type-required":"Credentials type is required.","credentials-anonymous":"Anonymous","credentials-basic":"Basic","credentials-pem":"PEM","credentials-pem-hint":"At least Server CA certificate file or a pair of Client certificate and Client private key files are required","credentials-sas":"Shared Access Signature","sas-key":"SAS Key","sas-key-required":"SAS Key is required.",hostname:"Hostname","hostname-required":"Hostname is required.","azure-ca-cert":"CA certificate file","username-required":"Username is required.","password-required":"Password is required.","ca-cert":"Server CA certificate file","private-key":"Client private key file",cert:"Client certificate file","no-file":"No file selected.","drop-file":"Drop a file or click to select a file to upload.","private-key-password":"Private key password","use-system-smtp-settings":"Use system SMTP settings","use-metadata-dynamic-interval":"Use dynamic interval","metadata-dynamic-interval-hint":"Interval start and end input fields support templatization. Note that the substituted template value should be set in milliseconds. Use $[messageKey] to extract value from the message and ${metadataKey} to extract value from the metadata.","use-metadata-interval-patterns-hint":"If selected, rule node use start and end interval patterns from message metadata or data assuming that intervals are in the milliseconds.","use-message-alarm-data":"Use message alarm data","overwrite-alarm-details":"Overwrite alarm details","use-alarm-severity-pattern":"Use alarm severity pattern","check-all-keys":"Check that all specified fields are present","check-all-keys-hint":"If selected, checks that all specified keys are present in the message data and metadata.","check-relation-to-specific-entity":"Check relation to specific entity","check-relation-to-specific-entity-tooltip":"If enabled, checks the presence of relation with a specific entity otherwise, checks the presence of relation with any entity. In both cases, relation lookup is based on configured direction and type.","check-relation-hint":"Checks existence of relation to specific entity or to any entity based on direction and relation type.","delete-relation-to-specific-entity":"Delete relation to specific entity","delete-relation-hint":"Deletes relation from the originator of the incoming message to the specified entity or list of entities based on direction and type.","remove-current-relations":"Remove current relations","remove-current-relations-hint":"Removes current relations from the originator of the incoming message based on direction and type.","change-originator-to-related-entity":"Change originator to related entity","change-originator-to-related-entity-hint":"Used to process submitted message as a message from another entity.","start-interval":"Interval start","end-interval":"Interval end","start-interval-required":"Interval start is required.","end-interval-required":"Interval end is required.","smtp-protocol":"Protocol","smtp-host":"SMTP host","smtp-host-required":"SMTP host is required.","smtp-port":"SMTP port","smtp-port-required":"You must supply a smtp port.","smtp-port-range":"SMTP port should be in a range from 1 to 65535.","timeout-msec":"Timeout ms","min-timeout-msec-message":"Only 0 ms minimum value is allowed.","enter-username":"Enter username","enter-password":"Enter password","enable-tls":"Enable TLS","tls-version":"TLS version","enable-proxy":"Enable proxy","use-system-proxy-properties":"Use system proxy properties","proxy-host":"Proxy host","proxy-host-required":"Proxy host is required.","proxy-port":"Proxy port","proxy-port-required":"Proxy port is required.","proxy-port-range":"Proxy port should be in a range from 1 to 65535.","proxy-user":"Proxy user","proxy-password":"Proxy password","proxy-scheme":"Proxy scheme","numbers-to-template":"Phone Numbers To Template","numbers-to-template-required":"Phone Numbers To Template is required","numbers-to-template-hint":'Comma separated Phone Numbers, use ${metadataKey} for value from metadata, $[messageKey] for value from message body',"sms-message-template":"SMS message Template","sms-message-template-required":"SMS message Template is required","use-system-sms-settings":"Use system SMS provider settings","min-period-0-seconds-message":"Only 0 second minimum period is allowed.","max-pending-messages":"Maximum pending messages","max-pending-messages-required":"Maximum pending messages is required.","max-pending-messages-range":"Maximum pending messages should be in a range from 1 to 100000.","originator-types-filter":"Originator types filter","interval-seconds":"Interval in seconds","interval-seconds-required":"Interval is required.","min-interval-seconds-message":"Only 1 second minimum interval is allowed.","output-timeseries-key-prefix":"Output timeseries key prefix","output-timeseries-key-prefix-required":"Output timeseries key prefix required.","separator-hint":'Press "Enter" to complete field input.',"select-details":"Select details","entity-details-id":"Id","entity-details-title":"Title","entity-details-country":"Country","entity-details-state":"State","entity-details-city":"City","entity-details-zip":"Zip","entity-details-address":"Address","entity-details-address2":"Address2","entity-details-additional_info":"Additional Info","entity-details-phone":"Phone","entity-details-email":"Email","email-sender":"Email sender","fields-to-check":"Fields to check","add-detail":"Add detail","check-all-keys-tooltip":"If enabled, checks the presence of all fields listed in the message and metadata field names within the incoming message and its metadata.","fields-to-check-hint":'Press "Enter" to complete field name input. Multiple field names supported.',"entity-details-list-empty":"At least one detail should be selected.","alarm-status":"Alarm status","alarm-required":"At least one alarm status should be selected.","no-entity-details-matching":"No entity details matching were found.","custom-table-name":"Custom table name","custom-table-name-required":"Table Name is required","custom-table-hint":"Enter the table name without prefix 'cs_tb_'.","message-field":"Message field","message-field-required":"Message field is required.","table-col":"Table column","table-col-required":"Table column is required.","latitude-field-name":"Latitude field name","longitude-field-name":"Longitude field name","latitude-field-name-required":"Latitude field name is required.","longitude-field-name-required":"Longitude field name is required.","fetch-perimeter-info-from-metadata":"Fetch perimeter information from metadata","fetch-perimeter-info-from-metadata-tooltip":"If perimeter type is set to 'Polygon' the value of metadata field '{{perimeterKeyName}}' will be set as perimeter definition without additional parsing of the value. Otherwise, if perimeter type is set to 'Circle' the value of '{{perimeterKeyName}}' metadata field will be parsed to extract 'latitude', 'longitude', 'radius', 'radiusUnit' fields that uses for circle perimeter definition.","perimeter-key-name":"Perimeter key name","perimeter-key-name-hint":"Metadata field name that includes perimeter information.","perimeter-key-name-required":"Perimeter key name is required.","perimeter-circle":"Circle","perimeter-polygon":"Polygon","perimeter-type":"Perimeter type","circle-center-latitude":"Center latitude","circle-center-latitude-required":"Center latitude is required.","circle-center-longitude":"Center longitude","circle-center-longitude-required":"Center longitude is required.","range-unit-meter":"Meter","range-unit-kilometer":"Kilometer","range-unit-foot":"Foot","range-unit-mile":"Mile","range-unit-nautical-mile":"Nautical mile","range-units":"Range units","range-units-required":"Range units is required.",range:"Range","range-required":"Range is required.","polygon-definition":"Polygon definition","polygon-definition-required":"Polygon definition is required.","polygon-definition-hint":"Use the following format for manual definition of polygon: [[lat1,lon1],[lat2,lon2], ... ,[latN,lonN]].","min-inside-duration":"Minimal inside duration","min-inside-duration-value-required":"Minimal inside duration is required","min-inside-duration-time-unit":"Minimal inside duration time unit","min-outside-duration":"Minimal outside duration","min-outside-duration-value-required":"Minimal outside duration is required","min-outside-duration-time-unit":"Minimal outside duration time unit","tell-failure-if-absent":"Tell Failure","tell-failure-if-absent-hint":'If at least one selected key doesn\'t exist the outbound message will report "Failure".',"get-latest-value-with-ts":"Fetch timestamp for the latest telemetry values","get-latest-value-with-ts-hint":'If selected, the latest telemetry values will also include timestamp, e.g: "temp": "{"ts":1574329385897, "value":42}"',"use-redis-queue":"Use redis queue for message persistence","ignore-null-strings":"Ignore null strings","ignore-null-strings-hint":"If selected rule node will ignore entity fields with empty value.","trim-redis-queue":"Trim redis queue","redis-queue-max-size":"Redis queue max size","add-metadata-key-values-as-kafka-headers":"Add Message metadata key-value pairs to Kafka record headers","add-metadata-key-values-as-kafka-headers-hint":"If selected, key-value pairs from message metadata will be added to the outgoing records headers as byte arrays with predefined charset encoding.","charset-encoding":"Charset encoding","charset-encoding-required":"Charset encoding is required.","charset-us-ascii":"US-ASCII","charset-iso-8859-1":"ISO-8859-1","charset-utf-8":"UTF-8","charset-utf-16be":"UTF-16BE","charset-utf-16le":"UTF-16LE","charset-utf-16":"UTF-16","select-queue-hint":"The queue name can be selected from a drop-down list or add a custom name.","persist-alarm-rules":"Persist state of alarm rules","fetch-alarm-rules":"Fetch state of alarm rules","input-value-key":"Input value key","input-value-key-required":"Input value key is required.","output-value-key":"Output value key","output-value-key-required":"Output value key is required.","number-of-digits-after-floating-point":"Number of digits after floating point","number-of-digits-after-floating-point-range":"Number of digits after floating point should be in a range from 0 to 15.","failure-if-delta-negative":"Tell Failure if delta is negative","failure-if-delta-negative-tooltip":"Rule node forces failure of message processing if delta value is negative.","use-caching":"Use caching","use-caching-tooltip":'Rule node will cache the value of "{{inputValueKey}}" that arrives from the incoming message to improve performance. Note that the cache will not be updated if you modify the "{{inputValueKey}}" value elsewhere.',"add-time-difference-between-readings":'Add the time difference between "{{inputValueKey}}" readings',"add-time-difference-between-readings-tooltip":'If enabled, the rule node will add the "{{periodValueKey}}" to the outbound message.',"period-value-key":"Period value key","period-value-key-required":"Period value key is required.","general-pattern-hint":"Use ${metadataKey} for value from metadata, $[messageKey] for value from message body.","alarm-severity-pattern-hint":'Use ${metadataKey} for value from metadata, $[messageKey] for value from message body. Alarm severity should be system (CRITICAL, MAJOR etc.)',"output-node-name-hint":"The rule node name corresponds to the relation type of the output message, and it is used to forward messages to other rule nodes in the caller rule chain.","skip-latest-persistence":"Skip latest persistence","use-server-ts":"Use server ts","use-server-ts-hint":"Enable this setting to use the timestamp of the message processing instead of the timestamp from the message. Useful for all sorts of sequential processing if you merge messages from multiple sources (devices, assets, etc).","kv-map-pattern-hint":"All input fields support templatization. Use $[messageKey] to extract value from the message and ${metadataKey} to extract value from the metadata.","shared-scope":"Shared scope","server-scope":"Server scope","client-scope":"Client scope","attribute-type":"Attribute","constant-type":"Constant","time-series-type":"Time-series","message-body-type":"Message","message-metadata-type":"Metadata","argument-tile":"Arguments","no-arguments-prompt":"No arguments configured","result-title":"Result","functions-field-input":"Functions","no-option-found":"No option found","argument-source-field-input":"Source","argument-source-field-input-required":"Argument source is required.","argument-key-field-input":"Key","argument-key-field-input-required":"Argument key is required.","constant-value-field-input":"Constant value","constant-value-field-input-required":"Constant value is required.","attribute-scope-field-input":"Attribute scope","attribute-scope-field-input-required":"Attribute scope os required.","default-value-field-input":"Default value","type-field-input":"Type","type-field-input-required":"Type is required.","key-field-input":"Key","add-entity-type":"Add entity type","add-device-profile":"Add device profile","key-field-input-required":"Key is required.","number-floating-point-field-input":"Number of digits after floating point","number-floating-point-field-input-hint":"Use 0 to convert result to integer","add-to-message-field-input":"Add to message","add-to-metadata-field-input":"Add to metadata","custom-expression-field-input":"Mathematical Expression","custom-expression-field-input-required":"Mathematical expression is required","custom-expression-field-input-hint":"Specify a mathematical expression to evaluate. Default expression demonstrates how to transform Fahrenheit to Celsius","retained-message":"Retained","attributes-mapping":"Attributes mapping","latest-telemetry-mapping":"Latest telemetry mapping","add-mapped-attribute-to":"Add mapped attributes to","add-mapped-latest-telemetry-to":"Add mapped latest telemetry to","add-mapped-fields-to":"Add mapped fields to","add-selected-details-to":"Add selected details to","clear-selected-types":"Clear selected types","clear-selected-details":"Clear selected details","clear-selected-fields":"Clear selected fields","clear-selected-keys":"Clear selected keys","geofence-configuration":"Geofence configuration","coordinate-field-names":"Coordinate field names","coordinate-field-hint":"Rule node tries to retrieve the specified fields from the message. If they are not present, it will look them up in the metadata.","fetch-credentials-to":"Fetch credentials to","add-originator-attributes-to":"Add originator attributes to","originator-attributes":"Originator attributes","fetch-latest-telemetry-with-timestamp":"Fetch latest telemetry with timestamp","fetch-latest-telemetry-with-timestamp-tooltip":'If selected, latest telemetry values will be added to the outbound metadata with timestamp, e.g: "{{latestTsKeyName}}": "{"ts":1574329385897, "value":42}"',"tell-failure":"Tell failure if any of the attributes are missing","tell-failure-tooltip":'If at least one selected key doesn\'t exist the outbound message will report "Failure".',"created-time":"Created time","chip-help":"Press 'Enter' to complete {{inputName}} input. \nPress 'Backspace' to delete {{inputName}}. \nMultiple values supported.",detail:"detail","field-name":"field name","device-profile":"device profile","entity-type":"entity type","message-type":"message type","timeseries-key":"timeseries key",type:"Type","first-name":"First name","last-name":"Last name",label:"Label","originator-fields-mapping":"Originator fields mapping","add-mapped-originator-fields-to":"Add mapped originator fields to",fields:"Fields","skip-empty-fields":"Skip empty fields","skip-empty-fields-tooltip":"Fields with empty values will not be added to the output message/output metadata.","fetch-interval":"Fetch interval","fetch-strategy":"Fetch strategy","fetch-timeseries-from-to":"Fetch timeseries from {{startInterval}} {{startIntervalTimeUnit}} ago to {{endInterval}} {{endIntervalTimeUnit}} ago.","fetch-timeseries-from-to-invalid":'Fetch timeseries invalid ("Interval start" should be less than "Interval end").',"use-metadata-dynamic-interval-tooltip":"If selected, the rule node will use dynamic interval start and end based on the message and metadata patterns.","all-mode-hint":'If selected fetch mode "All" rule node will retrieve telemetry from the fetch interval with configurable query parameters.',"first-mode-hint":'If selected fetch mode "First" rule node will retrieve the closest telemetry to the fetch interval\'s start.',"last-mode-hint":'If selected fetch mode "Last" rule node will retrieve the closest telemetry to the fetch interval\'s end.',ascending:"Ascending",descending:"Descending",min:"Min",max:"Max",average:"Average",sum:"Sum",count:"Count",none:"None","last-level-relation-tooltip":"If selected, the rule node will search related entities only on the level set in the max relation level.","last-level-device-relation-tooltip":"If selected, the rule node will search related devices only on the level set in the max relation level.","data-to-fetch":"Data to fetch","mapping-of-customers":"Mapping of customer's","map-fields-required":"All mapping fields are required.",attributes:"Attributes","related-device-attributes":"Related device attributes","add-selected-attributes-to":"Add selected attributes to","device-profiles":"Device profiles","mapping-of-tenant":"Mapping of tenant's","add-attribute-key":"Add attribute key","message-template":"Message template","message-template-required":"Message template is required","use-system-slack-settings":"Use system slack settings","slack-api-token":"Slack API token","slack-api-token-required":"Slack API token is required","keys-mapping":"keys mapping","add-key":"Add key",recipients:"Recipients","message-subject-and-content":"Message subject and content","template-rules-hint":"Both input fields support templatization. Use $[messageKey] to extract value from the message and ${metadataKey} to extract value from the metadata.","originator-customer-desc":"Use customer of incoming message originator as new originator.","originator-tenant-desc":"Use current tenant as new originator.","originator-related-entity-desc":"Use related entity as new originator. Lookup based on configured relation type and direction.","originator-alarm-originator-desc":"Use alarm originator as new originator. Only if incoming message originator is alarm entity.","originator-entity-by-name-pattern-desc":"Use entity fetched from DB as new originator. Lookup based on entity type and specified name pattern.","email-from-template-hint":"Use $[messageKey] to extract value from the message and ${metadataKey} to extract value from the metadata.","recipients-block-main-hint":"Comma-separated address list. All input fields support templatization. Use $[messageKey] to extract value from the message and ${metadataKey} to extract value from the metadata."},"key-val":{key:"Key",value:"Value","see-examples":"See examples.","remove-entry":"Remove entry","remove-mapping-entry":"Remove mapping entry","add-mapping-entry":"Add mapping","add-entry":"Add entry","copy-key-values-from":"Copy key-values from","delete-key-values":"Delete key-values","delete-key-values-from":"Delete key-values from","at-least-one-key-error":"At least one key should be selected.","unique-key-value-pair-error":"'{{keyText}}' must be different from the '{{valText}}'!"},"mail-body-type":{"plain-text":"Plain text",html:"HTML",dynamic:"Dynamic","use-body-type-template":"Use body type template","plain-text-description":"Simple, unformatted text with no special styling or formating.","html-text-description":"Allows you to use HTML tags for formatting, links and images in your mai body.","dynamic-text-description":"Allows to use Plain Text or HTML body type dynamically based on templatization feature.","after-template-evaluation-hint":"After template evaluation value should be true for HTML, and false for Plain text."}}},!0)}(e)}}e("RuleNodeCoreConfigModule",Kr),Kr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Kr,deps:[{token:Z.TranslateService}],target:t.ɵɵFactoryTarget.NgModule}),Kr.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.10",ngImport:t,type:Kr,declarations:[dt],imports:[$,M],exports:[Hn,Lr,nr,gr,Rr,Br,dt]}),Kr.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Kr,imports:[$,M,Hn,Lr,nr,gr,Rr,Br]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Kr,decorators:[{type:c,args:[{declarations:[dt],imports:[$,M],exports:[Hn,Lr,nr,gr,Rr,Br,dt]}]}],ctorParameters:function(){return[{type:Z.TranslateService}]}})}}}));//# sourceMappingURL=rulenode-core-config.js.map +System.register(["@angular/core","@shared/public-api","@ngrx/store","@angular/forms","@angular/common","@angular/material/checkbox","@angular/material/input","@angular/material/form-field","@angular/flex-layout/flex","@ngx-translate/core","@angular/material/select","@angular/material/core","@angular/material/slide-toggle","@shared/components/hint-tooltip-icon.component","@core/public-api","@shared/components/js-func.component","@angular/material/button","@angular/material/icon","@angular/material/tooltip","@shared/components/script-lang.component","@angular/cdk/keycodes","@angular/material/chips","@shared/pipe/safe.pipe","@shared/components/entity/entity-type-select.component","@shared/components/entity/entity-select.component","@angular/cdk/coercion","@shared/components/tb-error.component","@angular/flex-layout/extended","@angular/material/list","@angular/cdk/drag-drop","rxjs/operators","@angular/material/autocomplete","@shared/pipe/highlight.pipe","@home/components/public-api","tslib","rxjs","@shared/components/help-popup.component","@shared/components/entity/entity-subtype-list.component","@shared/components/relation/relation-type-autocomplete.component","@home/components/relation/relation-filters.component","@angular/material/expansion","@shared/components/file-input.component","@shared/components/button/toggle-password.component","@shared/components/string-items-list.component","@shared/components/toggle-header.component","@shared/components/toggle-select.component","@shared/components/entity/entity-list.component","@shared/components/notification/template-autocomplete.component","@shared/components/tb-checkbox.component","@home/components/sms/sms-provider-configuration.component","@angular/material/radio","@shared/components/slack-conversation-autocomplete.component","@shared/components/entity/entity-autocomplete.component","@shared/components/entity/entity-type-list.component","@angular/cdk/platform"],(function(e){"use strict";var t,n,r,o,a,i,l,s,m,p,d,u,c,f,g,y,x,b,h,v,C,F,k,L,T,I,N,S,q,A,M,E,G,D,w,V,P,R,O,_,B,K,z,U,H,j,$,Q,J,Y,W,Z,X,ee,te,ne,re,oe,ae,ie,le,se,me,pe,de,ue,ce,fe,ge,ye,xe,be,he,ve,Ce,Fe,ke,Le,Te,Ie,Ne,Se,qe,Ae,Me,Ee,Ge,De,we,Ve,Pe,Re,Oe,_e,Be,Ke,ze,Ue,He,je,$e,Qe,Je,Ye,We,Ze,Xe,et,tt,nt,rt,ot,at,it,lt,st,mt,pt;return{setters:[function(e){t=e,n=e.Component,r=e.EventEmitter,o=e.ViewChild,a=e.forwardRef,i=e.Input,l=e.InjectionToken,s=e.Injectable,m=e.Inject,p=e.Optional,d=e.Directive,u=e.Output,c=e.NgModule},function(e){f=e.RuleNodeConfigurationComponent,g=e.AttributeScope,y=e.telemetryTypeTranslations,x=e.ScriptLanguage,b=e.AlarmSeverity,h=e.alarmSeverityTranslations,v=e.EntitySearchDirection,C=e.entitySearchDirectionTranslations,F=e.EntityType,k=e.entityFields,L=e.PageComponent,T=e.coerceBoolean,I=e.MessageType,N=e.messageTypeNames,S=e,q=e.AlarmStatus,A=e.alarmStatusTranslations,M=e.SharedModule,E=e.AggregationType,G=e.aggregationTranslations,D=e.NotificationType,w=e.SlackChanelType,V=e.SlackChanelTypesTranslateMap},function(e){P=e},function(e){R=e,O=e.Validators,_=e.NgControl,B=e.NG_VALUE_ACCESSOR,K=e.NG_VALIDATORS,z=e.FormArray,U=e.FormGroup},function(e){H=e,j=e.DOCUMENT,$=e.CommonModule},function(e){Q=e},function(e){J=e},function(e){Y=e},function(e){W=e},function(e){Z=e},function(e){X=e},function(e){ee=e},function(e){te=e},function(e){ne=e},function(e){re=e.getCurrentAuthState,oe=e,ae=e.isEqual,ie=e.isDefinedAndNotNull,le=e.deepTrim,se=e.isObject,me=e.isNotEmptyStr},function(e){pe=e},function(e){de=e},function(e){ue=e},function(e){ce=e},function(e){fe=e},function(e){ge=e.ENTER,ye=e.COMMA,xe=e.SEMICOLON},function(e){be=e},function(e){he=e},function(e){ve=e},function(e){Ce=e},function(e){Fe=e.coerceBooleanProperty,ke=e.coerceElement,Le=e.coerceNumberProperty},function(e){Te=e},function(e){Ie=e},function(e){Ne=e},function(e){Se=e},function(e){qe=e.tap,Ae=e.map,Me=e.startWith,Ee=e.mergeMap,Ge=e.share,De=e.takeUntil,we=e.auditTime},function(e){Ve=e},function(e){Pe=e},function(e){Re=e.HomeComponentsModule},function(e){Oe=e.__decorate},function(e){_e=e.Subject,Be=e.takeUntil,Ke=e.of,ze=e.EMPTY,Ue=e.fromEvent},function(e){He=e},function(e){je=e},function(e){$e=e},function(e){Qe=e},function(e){Je=e},function(e){Ye=e},function(e){We=e},function(e){Ze=e},function(e){Xe=e},function(e){et=e},function(e){tt=e},function(e){nt=e},function(e){rt=e},function(e){ot=e},function(e){at=e},function(e){it=e},function(e){lt=e},function(e){st=e},function(e){mt=e.normalizePassiveListenerOptions,pt=e}],execute:function(){class dt extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.emptyConfigForm}onConfigurationSet(e){this.emptyConfigForm=this.fb.group({})}}e("EmptyConfigComponent",dt),dt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:dt,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),dt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:dt,selector:"tb-node-empty-config",usesInheritance:!0,ngImport:t,template:"
",isInline:!0}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:dt,decorators:[{type:n,args:[{selector:"tb-node-empty-config",template:"
"}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class ut extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.assignCustomerConfigForm}onConfigurationSet(e){this.assignCustomerConfigForm=this.fb.group({customerNamePattern:[e?e.customerNamePattern:null,[O.required,O.pattern(/.*\S.*/)]],createCustomerIfNotExists:[!!e&&e.createCustomerIfNotExists,[]],customerCacheExpiration:[e?e.customerCacheExpiration:null,[O.required,O.min(0)]]})}prepareOutputConfig(e){return e.customerNamePattern=e.customerNamePattern.trim(),e}}e("AssignCustomerConfigComponent",ut),ut.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ut,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),ut.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:ut,selector:"tb-action-node-assign-to-customer-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.customer-name-pattern\n \n \n {{ \'tb.rulenode.customer-name-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n {{ \'tb.rulenode.create-customer-if-not-exists\' | translate }}\n \n \n tb.rulenode.customer-cache-expiration\n \n \n {{ \'tb.rulenode.customer-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.customer-cache-expiration-range\' | translate }}\n \n tb.rulenode.customer-cache-expiration-hint\n \n
\n',dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Q.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ut,decorators:[{type:n,args:[{selector:"tb-action-node-assign-to-customer-config",template:'
\n \n tb.rulenode.customer-name-pattern\n \n \n {{ \'tb.rulenode.customer-name-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n {{ \'tb.rulenode.create-customer-if-not-exists\' | translate }}\n \n \n tb.rulenode.customer-cache-expiration\n \n \n {{ \'tb.rulenode.customer-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.customer-cache-expiration-range\' | translate }}\n \n tb.rulenode.customer-cache-expiration-hint\n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class ct extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.attributeScopeMap=g,this.attributeScopes=Object.keys(g),this.telemetryTypeTranslationsMap=y}configForm(){return this.attributesConfigForm}onConfigurationSet(e){this.attributesConfigForm=this.fb.group({scope:[e?e.scope:null,[O.required]],notifyDevice:[!e||e.notifyDevice,[]],sendAttributesUpdatedNotification:[!!e&&e.sendAttributesUpdatedNotification,[]],updateAttributesOnlyOnValueChange:[!!e&&e.updateAttributesOnlyOnValueChange,[]]}),this.attributesConfigForm.get("scope").valueChanges.subscribe((e=>{e!==g.SHARED_SCOPE&&this.attributesConfigForm.get("notifyDevice").patchValue(!1,{emitEvent:!1}),e===g.CLIENT_SCOPE&&this.attributesConfigForm.get("sendAttributesUpdatedNotification").patchValue(!1,{emitEvent:!1}),this.attributesConfigForm.get("updateAttributesOnlyOnValueChange").patchValue(!1,{emitEvent:!1})}))}}e("AttributesConfigComponent",ct),ct.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ct,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),ct.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:ct,selector:"tb-action-node-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n
\n \n {{ \'tb.rulenode.update-attributes-only-on-value-change\' | translate }}\n \n
\n
\n \n {{ \'tb.rulenode.send-attributes-updated-notification\' | translate }}\n \n
\n
\n \n {{ \'tb.rulenode.notify-device\' | translate }}\n \n
\n
\n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:te.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:ne.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ct,decorators:[{type:n,args:[{selector:"tb-action-node-attributes-config",template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n
\n \n {{ \'tb.rulenode.update-attributes-only-on-value-change\' | translate }}\n \n
\n
\n \n {{ \'tb.rulenode.send-attributes-updated-notification\' | translate }}\n \n
\n
\n \n {{ \'tb.rulenode.notify-device\' | translate }}\n \n
\n
\n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class ft extends f{constructor(e,t,n,o){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=n,this.translate=o,this.tbelEnabled=re(this.store).tbelEnabled,this.scriptLanguage=x,this.changeScript=new r,this.hasScript=!0,this.testScriptLabel="tb.rulenode.test-details-function"}configForm(){return this.clearAlarmConfigForm}onConfigurationSet(e){this.clearAlarmConfigForm=this.fb.group({scriptLang:[e?e.scriptLang:x.JS,[O.required]],alarmDetailsBuildJs:[e?e.alarmDetailsBuildJs:null,[]],alarmDetailsBuildTbel:[e?e.alarmDetailsBuildTbel:null,[]],alarmType:[e?e.alarmType:null,[O.required]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.clearAlarmConfigForm.get("scriptLang").value;t!==x.TBEL||this.tbelEnabled||(t=x.JS,this.clearAlarmConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.clearAlarmConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.clearAlarmConfigForm.get("alarmDetailsBuildJs").setValidators(t===x.JS?[O.required]:[]),this.clearAlarmConfigForm.get("alarmDetailsBuildJs").updateValueAndValidity({emitEvent:e}),this.clearAlarmConfigForm.get("alarmDetailsBuildTbel").setValidators(t===x.TBEL?[O.required]:[]),this.clearAlarmConfigForm.get("alarmDetailsBuildTbel").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=x.JS)),e}testScript(e){const t=this.clearAlarmConfigForm.get("scriptLang").value,n=t===x.JS?"alarmDetailsBuildJs":"alarmDetailsBuildTbel",r=t===x.JS?"rulenode/clear_alarm_node_script_fn":"rulenode/tbel/clear_alarm_node_script_fn",o=this.clearAlarmConfigForm.get(n).value;this.nodeScriptTestService.testNodeScript(o,"json",this.translate.instant("tb.rulenode.details"),"Details",["msg","metadata","msgType"],this.ruleNodeId,r,t,e).subscribe((e=>{e&&(this.clearAlarmConfigForm.get(n).setValue(e),this.changeScript.emit())}))}onValidate(){this.clearAlarmConfigForm.get("scriptLang").value===x.JS&&this.jsFuncComponent.validateOnSubmit()}}e("ClearAlarmConfigComponent",ft),ft.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ft,deps:[{token:P.Store},{token:R.UntypedFormBuilder},{token:oe.NodeScriptTestService},{token:Z.TranslateService}],target:t.ɵɵFactoryTarget.Component}),ft.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:ft,selector:"tb-action-node-clear-alarm-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n \n \n
\n \n
\n \n tb.rulenode.alarm-type\n \n \n {{ \'tb.rulenode.alarm-type-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n
\n',dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:pe.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:de.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:de.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:fe.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ft,decorators:[{type:n,args:[{selector:"tb-action-node-clear-alarm-config",template:'
\n \n \n \n \n \n \n \n
\n \n
\n \n tb.rulenode.alarm-type\n \n \n {{ \'tb.rulenode.alarm-type-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder},{type:oe.NodeScriptTestService},{type:Z.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}});class gt extends f{constructor(e,t,n,o){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=n,this.translate=o,this.alarmSeverities=Object.keys(b),this.alarmSeverityTranslationMap=h,this.separatorKeysCodes=[ge,ye,xe],this.tbelEnabled=re(this.store).tbelEnabled,this.scriptLanguage=x,this.changeScript=new r,this.hasScript=!0,this.testScriptLabel="tb.rulenode.test-details-function"}configForm(){return this.createAlarmConfigForm}onConfigurationSet(e){this.createAlarmConfigForm=this.fb.group({scriptLang:[e?e.scriptLang:x.JS,[O.required]],alarmDetailsBuildJs:[e?e.alarmDetailsBuildJs:null,[]],alarmDetailsBuildTbel:[e?e.alarmDetailsBuildTbel:null,[]],useMessageAlarmData:[!!e&&e.useMessageAlarmData,[]],overwriteAlarmDetails:[!!e&&e.overwriteAlarmDetails,[]],alarmType:[e?e.alarmType:null,[]],severity:[e?e.severity:null,[]],propagate:[!!e&&e.propagate,[]],relationTypes:[e?e.relationTypes:null,[]],propagateToOwner:[!!e&&e.propagateToOwner,[]],propagateToTenant:[!!e&&e.propagateToTenant,[]],dynamicSeverity:!1}),this.createAlarmConfigForm.get("dynamicSeverity").valueChanges.subscribe((e=>{e?this.createAlarmConfigForm.get("severity").patchValue("",{emitEvent:!1}):this.createAlarmConfigForm.get("severity").patchValue(this.alarmSeverities[0],{emitEvent:!1})}))}validatorTriggers(){return["useMessageAlarmData","overwriteAlarmDetails","scriptLang"]}updateValidators(e){const t=this.createAlarmConfigForm.get("useMessageAlarmData").value,n=this.createAlarmConfigForm.get("overwriteAlarmDetails").value;t?(this.createAlarmConfigForm.get("alarmType").setValidators([]),this.createAlarmConfigForm.get("severity").setValidators([])):(this.createAlarmConfigForm.get("alarmType").setValidators([O.required]),this.createAlarmConfigForm.get("severity").setValidators([O.required])),this.createAlarmConfigForm.get("alarmType").updateValueAndValidity({emitEvent:e}),this.createAlarmConfigForm.get("severity").updateValueAndValidity({emitEvent:e});let r=this.createAlarmConfigForm.get("scriptLang").value;r!==x.TBEL||this.tbelEnabled||(r=x.JS,this.createAlarmConfigForm.get("scriptLang").patchValue(r,{emitEvent:!1}),setTimeout((()=>{this.createAlarmConfigForm.updateValueAndValidity({emitEvent:!0})})));const o=!1===t||!0===n;this.createAlarmConfigForm.get("alarmDetailsBuildJs").setValidators(o&&r===x.JS?[O.required]:[]),this.createAlarmConfigForm.get("alarmDetailsBuildTbel").setValidators(o&&r===x.TBEL?[O.required]:[]),this.createAlarmConfigForm.get("alarmDetailsBuildJs").updateValueAndValidity({emitEvent:e}),this.createAlarmConfigForm.get("alarmDetailsBuildTbel").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=x.JS)),e}testScript(e){const t=this.createAlarmConfigForm.get("scriptLang").value,n=t===x.JS?"alarmDetailsBuildJs":"alarmDetailsBuildTbel",r=t===x.JS?"rulenode/create_alarm_node_script_fn":"rulenode/tbel/create_alarm_node_script_fn",o=this.createAlarmConfigForm.get(n).value;this.nodeScriptTestService.testNodeScript(o,"json",this.translate.instant("tb.rulenode.details"),"Details",["msg","metadata","msgType"],this.ruleNodeId,r,t,e).subscribe((e=>{e&&(this.createAlarmConfigForm.get(n).setValue(e),this.changeScript.emit())}))}removeKey(e,t){const n=this.createAlarmConfigForm.get(t).value,r=n.indexOf(e);r>=0&&(n.splice(r,1),this.createAlarmConfigForm.get(t).setValue(n,{emitEvent:!0}))}addKey(e,t){const n=e.input;let r=e.value;if((r||"").trim()){r=r.trim();let e=this.createAlarmConfigForm.get(t).value;e&&-1!==e.indexOf(r)||(e||(e=[]),e.push(r),this.createAlarmConfigForm.get(t).setValue(e,{emitEvent:!0}))}n&&(n.value="")}onValidate(){const e=this.createAlarmConfigForm.get("useMessageAlarmData").value,t=this.createAlarmConfigForm.get("overwriteAlarmDetails").value;if(!e||t){this.createAlarmConfigForm.get("scriptLang").value===x.JS&&this.jsFuncComponent.validateOnSubmit()}}}e("CreateAlarmConfigComponent",gt),gt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:gt,deps:[{token:P.Store},{token:R.UntypedFormBuilder},{token:oe.NodeScriptTestService},{token:Z.TranslateService}],target:t.ɵɵFactoryTarget.Component}),gt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:gt,selector:"tb-action-node-create-alarm-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.use-message-alarm-data\' | translate }}\n \n \n {{ \'tb.rulenode.overwrite-alarm-details\' | translate }}\n \n
\n \n \n \n \n \n \n \n
\n \n
\n
\n
\n \n tb.rulenode.alarm-type\n \n \n {{ \'tb.rulenode.alarm-type-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n {{ \'tb.rulenode.use-alarm-severity-pattern\' | translate }}\n \n \n tb.rulenode.alarm-severity\n \n \n {{ alarmSeverityTranslationMap.get(severity) | translate }}\n \n \n \n {{ \'tb.rulenode.alarm-severity-required\' | translate }}\n \n \n \n tb.rulenode.alarm-severity-pattern\n \n \n {{ \'tb.rulenode.alarm-severity-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.propagate\' | translate }}\n \n
\n \n tb.rulenode.relation-types-list\n \n \n {{key}}\n close\n \n \n \n tb.rulenode.relation-types-list-hint\n \n
\n \n {{ \'tb.rulenode.propagate-to-owner\' | translate }}\n \n \n {{ \'tb.rulenode.propagate-to-tenant\' | translate }}\n \n
\n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:pe.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:de.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:de.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:Q.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:be.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:be.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:be.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:be.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:fe.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:he.SafePipe,name:"safe"},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:gt,decorators:[{type:n,args:[{selector:"tb-action-node-create-alarm-config",template:'
\n \n {{ \'tb.rulenode.use-message-alarm-data\' | translate }}\n \n \n {{ \'tb.rulenode.overwrite-alarm-details\' | translate }}\n \n
\n \n \n \n \n \n \n \n
\n \n
\n
\n
\n \n tb.rulenode.alarm-type\n \n \n {{ \'tb.rulenode.alarm-type-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n {{ \'tb.rulenode.use-alarm-severity-pattern\' | translate }}\n \n \n tb.rulenode.alarm-severity\n \n \n {{ alarmSeverityTranslationMap.get(severity) | translate }}\n \n \n \n {{ \'tb.rulenode.alarm-severity-required\' | translate }}\n \n \n \n tb.rulenode.alarm-severity-pattern\n \n \n {{ \'tb.rulenode.alarm-severity-required\' | translate }}\n \n \n \n \n {{ \'tb.rulenode.propagate\' | translate }}\n \n
\n \n tb.rulenode.relation-types-list\n \n \n {{key}}\n close\n \n \n \n tb.rulenode.relation-types-list-hint\n \n
\n \n {{ \'tb.rulenode.propagate-to-owner\' | translate }}\n \n \n {{ \'tb.rulenode.propagate-to-tenant\' | translate }}\n \n
\n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder},{type:oe.NodeScriptTestService},{type:Z.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}});class yt extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.directionTypes=Object.keys(v),this.directionTypeTranslations=C,this.entityType=F}configForm(){return this.createRelationConfigForm}onConfigurationSet(e){this.createRelationConfigForm=this.fb.group({direction:[e?e.direction:null,[O.required]],entityType:[e?e.entityType:null,[O.required]],entityNamePattern:[e?e.entityNamePattern:null,[]],entityTypePattern:[e?e.entityTypePattern:null,[]],relationType:[e?e.relationType:null,[O.required]],createEntityIfNotExists:[!!e&&e.createEntityIfNotExists,[]],removeCurrentRelations:[!!e&&e.removeCurrentRelations,[]],changeOriginatorToRelatedEntity:[!!e&&e.changeOriginatorToRelatedEntity,[]],entityCacheExpiration:[e?e.entityCacheExpiration:null,[O.required,O.min(0)]]})}validatorTriggers(){return["entityType"]}updateValidators(e){const t=this.createRelationConfigForm.get("entityType").value;t?this.createRelationConfigForm.get("entityNamePattern").setValidators([O.required,O.pattern(/.*\S.*/)]):this.createRelationConfigForm.get("entityNamePattern").setValidators([]),!t||t!==F.DEVICE&&t!==F.ASSET?this.createRelationConfigForm.get("entityTypePattern").setValidators([]):this.createRelationConfigForm.get("entityTypePattern").setValidators([O.required,O.pattern(/.*\S.*/)]),this.createRelationConfigForm.get("entityNamePattern").updateValueAndValidity({emitEvent:e}),this.createRelationConfigForm.get("entityTypePattern").updateValueAndValidity({emitEvent:e})}prepareOutputConfig(e){return e.entityNamePattern=e.entityNamePattern?e.entityNamePattern.trim():null,e.entityTypePattern=e.entityTypePattern?e.entityTypePattern.trim():null,e}}e("CreateRelationConfigComponent",yt),yt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:yt,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),yt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:yt,selector:"tb-action-node-create-relation-config",usesInheritance:!0,ngImport:t,template:'
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.entity-type-pattern\n \n \n {{ \'tb.rulenode.entity-type-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n
\n \n tb.rulenode.relation-type-pattern\n \n \n {{ \'tb.rulenode.relation-type-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n
\n \n {{ \'tb.rulenode.create-entity-if-not-exists\' | translate }}\n \n
tb.rulenode.create-entity-if-not-exists-hint
\n
\n \n {{ \'tb.rulenode.remove-current-relations\' | translate }}\n \n
tb.rulenode.remove-current-relations-hint
\n \n {{ \'tb.rulenode.change-originator-to-related-entity\' | translate }}\n \n
tb.rulenode.change-originator-to-related-entity-hint
\n \n tb.rulenode.entity-cache-expiration\n \n \n {{ \'tb.rulenode.entity-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.entity-cache-expiration-range\' | translate }}\n \n tb.rulenode.entity-cache-expiration-hint\n \n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ve.EntityTypeSelectComponent,selector:"tb-entity-type-select",inputs:["allowedEntityTypes","useAliasEntityTypes","filterAllowedEntityTypes","showLabel","required","disabled"]},{kind:"component",type:Q.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:yt,decorators:[{type:n,args:[{selector:"tb-action-node-create-relation-config",template:'
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.entity-type-pattern\n \n \n {{ \'tb.rulenode.entity-type-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n
\n \n tb.rulenode.relation-type-pattern\n \n \n {{ \'tb.rulenode.relation-type-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n
\n \n {{ \'tb.rulenode.create-entity-if-not-exists\' | translate }}\n \n
tb.rulenode.create-entity-if-not-exists-hint
\n
\n \n {{ \'tb.rulenode.remove-current-relations\' | translate }}\n \n
tb.rulenode.remove-current-relations-hint
\n \n {{ \'tb.rulenode.change-originator-to-related-entity\' | translate }}\n \n
tb.rulenode.change-originator-to-related-entity-hint
\n \n tb.rulenode.entity-cache-expiration\n \n \n {{ \'tb.rulenode.entity-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.entity-cache-expiration-range\' | translate }}\n \n tb.rulenode.entity-cache-expiration-hint\n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class xt extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.directionTypes=Object.keys(v),this.directionTypeTranslations=C,this.entityType=F}configForm(){return this.deleteRelationConfigForm}onConfigurationSet(e){this.deleteRelationConfigForm=this.fb.group({deleteForSingleEntity:[!!e&&e.deleteForSingleEntity,[]],direction:[e?e.direction:null,[O.required]],entityType:[e?e.entityType:null,[]],entityNamePattern:[e?e.entityNamePattern:null,[]],relationType:[e?e.relationType:null,[O.required]],entityCacheExpiration:[e?e.entityCacheExpiration:null,[O.required,O.min(0)]]})}validatorTriggers(){return["deleteForSingleEntity","entityType"]}updateValidators(e){const t=this.deleteRelationConfigForm.get("deleteForSingleEntity").value,n=this.deleteRelationConfigForm.get("entityType").value;t?this.deleteRelationConfigForm.get("entityType").setValidators([O.required]):this.deleteRelationConfigForm.get("entityType").setValidators([]),t&&n?this.deleteRelationConfigForm.get("entityNamePattern").setValidators([O.required,O.pattern(/.*\S.*/)]):this.deleteRelationConfigForm.get("entityNamePattern").setValidators([]),this.deleteRelationConfigForm.get("entityType").updateValueAndValidity({emitEvent:!1}),this.deleteRelationConfigForm.get("entityNamePattern").updateValueAndValidity({emitEvent:e})}prepareOutputConfig(e){return e.entityNamePattern=e.entityNamePattern?e.entityNamePattern.trim():null,e}}e("DeleteRelationConfigComponent",xt),xt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:xt,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),xt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:xt,selector:"tb-action-node-delete-relation-config",usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.delete-relation-to-specific-entity\' | translate }}\n \n
tb.rulenode.delete-relation-hint
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n
\n \n tb.rulenode.relation-type-pattern\n \n \n {{ \'tb.rulenode.relation-type-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.entity-cache-expiration\n \n \n {{ \'tb.rulenode.entity-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.entity-cache-expiration-range\' | translate }}\n \n tb.rulenode.entity-cache-expiration-hint\n \n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ve.EntityTypeSelectComponent,selector:"tb-entity-type-select",inputs:["allowedEntityTypes","useAliasEntityTypes","filterAllowedEntityTypes","showLabel","required","disabled"]},{kind:"component",type:Q.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:xt,decorators:[{type:n,args:[{selector:"tb-action-node-delete-relation-config",template:'
\n \n {{ \'tb.rulenode.delete-relation-to-specific-entity\' | translate }}\n \n
tb.rulenode.delete-relation-hint
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n
\n \n tb.rulenode.relation-type-pattern\n \n \n {{ \'tb.rulenode.relation-type-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.entity-cache-expiration\n \n \n {{ \'tb.rulenode.entity-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.entity-cache-expiration-range\' | translate }}\n \n tb.rulenode.entity-cache-expiration-hint\n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class bt extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.deviceProfile}onConfigurationSet(e){this.deviceProfile=this.fb.group({persistAlarmRulesState:[!!e&&e.persistAlarmRulesState,O.required],fetchAlarmRulesStateOnStart:[!!e&&e.fetchAlarmRulesStateOnStart,O.required]})}}e("DeviceProfileConfigComponent",bt),bt.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:bt,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),bt.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:bt,selector:"tb-device-profile-config",usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.persist-alarm-rules\' | translate }}\n \n \n {{ \'tb.rulenode.fetch-alarm-rules\' | translate }}\n \n
\n',dependencies:[{kind:"component",type:Q.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:bt,decorators:[{type:n,args:[{selector:"tb-device-profile-config",template:'
\n \n {{ \'tb.rulenode.persist-alarm-rules\' | translate }}\n \n \n {{ \'tb.rulenode.fetch-alarm-rules\' | translate }}\n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class ht extends f{constructor(e,t,n,o){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=n,this.translate=o,this.tbelEnabled=re(this.store).tbelEnabled,this.scriptLanguage=x,this.changeScript=new r,this.hasScript=!0,this.testScriptLabel="tb.rulenode.test-generator-function"}configForm(){return this.generatorConfigForm}onConfigurationSet(e){this.generatorConfigForm=this.fb.group({msgCount:[e?e.msgCount:null,[O.required,O.min(0)]],periodInSeconds:[e?e.periodInSeconds:null,[O.required,O.min(1)]],originator:[e?e.originator:null,[]],scriptLang:[e?e.scriptLang:x.JS,[O.required]],jsScript:[e?e.jsScript:null,[]],tbelScript:[e?e.tbelScript:null,[]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.generatorConfigForm.get("scriptLang").value;t!==x.TBEL||this.tbelEnabled||(t=x.JS,this.generatorConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.generatorConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.generatorConfigForm.get("jsScript").setValidators(t===x.JS?[O.required]:[]),this.generatorConfigForm.get("jsScript").updateValueAndValidity({emitEvent:e}),this.generatorConfigForm.get("tbelScript").setValidators(t===x.TBEL?[O.required]:[]),this.generatorConfigForm.get("tbelScript").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=x.JS),e.originatorId&&e.originatorType?e.originator={id:e.originatorId,entityType:e.originatorType}:e.originator=null,delete e.originatorId,delete e.originatorType),e}prepareOutputConfig(e){return e.originator?(e.originatorId=e.originator.id,e.originatorType=e.originator.entityType):(e.originatorId=null,e.originatorType=null),delete e.originator,e}testScript(e){const t=this.generatorConfigForm.get("scriptLang").value,n=t===x.JS?"jsScript":"tbelScript",r=t===x.JS?"rulenode/generator_node_script_fn":"rulenode/tbel/generator_node_script_fn",o=this.generatorConfigForm.get(n).value;this.nodeScriptTestService.testNodeScript(o,"generate",this.translate.instant("tb.rulenode.generator"),"Generate",["prevMsg","prevMetadata","prevMsgType"],this.ruleNodeId,r,t,e).subscribe((e=>{e&&(this.generatorConfigForm.get(n).setValue(e),this.changeScript.emit())}))}onValidate(){this.generatorConfigForm.get("scriptLang").value===x.JS&&this.jsFuncComponent.validateOnSubmit()}}var vt;e("GeneratorConfigComponent",ht),ht.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ht,deps:[{token:P.Store},{token:R.UntypedFormBuilder},{token:oe.NodeScriptTestService},{token:Z.TranslateService}],target:t.ɵɵFactoryTarget.Component}),ht.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:ht,selector:"tb-action-node-generator-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.message-count\n \n \n {{ \'tb.rulenode.message-count-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-message-count-message\' | translate }}\n \n \n \n tb.rulenode.period-seconds\n \n \n {{ \'tb.rulenode.period-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-period-seconds-message\' | translate }}\n \n \n
\n \n \n \n
\n\n \n \n \n \n \n \n \n
\n \n
\n
\n',dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Ce.EntitySelectComponent,selector:"tb-entity-select",inputs:["allowedEntityTypes","useAliasEntityTypes","required","disabled"]},{kind:"component",type:pe.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:de.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:de.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:fe.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ht,decorators:[{type:n,args:[{selector:"tb-action-node-generator-config",template:'
\n \n tb.rulenode.message-count\n \n \n {{ \'tb.rulenode.message-count-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-message-count-message\' | translate }}\n \n \n \n tb.rulenode.period-seconds\n \n \n {{ \'tb.rulenode.period-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-period-seconds-message\' | translate }}\n \n \n
\n \n \n \n
\n\n \n \n \n \n \n \n \n
\n \n
\n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder},{type:oe.NodeScriptTestService},{type:Z.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}}),function(e){e.CUSTOMER="CUSTOMER",e.TENANT="TENANT",e.RELATED="RELATED",e.ALARM_ORIGINATOR="ALARM_ORIGINATOR",e.ENTITY="ENTITY"}(vt||(vt={}));const Ct=new Map([[vt.CUSTOMER,"tb.rulenode.originator-customer"],[vt.TENANT,"tb.rulenode.originator-tenant"],[vt.RELATED,"tb.rulenode.originator-related"],[vt.ALARM_ORIGINATOR,"tb.rulenode.originator-alarm-originator"],[vt.ENTITY,"tb.rulenode.originator-entity"]]),Ft=new Map([[vt.CUSTOMER,"tb.rulenode.originator-customer-desc"],[vt.TENANT,"tb.rulenode.originator-tenant-desc"],[vt.RELATED,"tb.rulenode.originator-related-entity-desc"],[vt.ALARM_ORIGINATOR,"tb.rulenode.originator-alarm-originator-desc"],[vt.ENTITY,"tb.rulenode.originator-entity-by-name-pattern-desc"]]),kt=[k.createdTime,k.name,{value:"type",name:"tb.rulenode.profile-name",keyName:"originatorProfileName"},k.firstName,k.lastName,k.email,k.title,k.country,k.state,k.city,k.address,k.address2,k.zip,k.phone,k.label,{value:"id",name:"tb.rulenode.id",keyName:"id"},{value:"additionalInfo",name:"tb.rulenode.additional-info",keyName:"additionalInfo"}],Lt=new Map([["type","profileName"],["createdTime","createdTime"],["name","name"],["firstName","firstName"],["lastName","lastName"],["email","email"],["title","title"],["country","country"],["state","state"],["city","city"],["address","address"],["address2","address2"],["zip","zip"],["phone","phone"],["label","label"],["id","id"],["additionalInfo","additionalInfo"]]);var Tt;!function(e){e.CIRCLE="CIRCLE",e.POLYGON="POLYGON"}(Tt||(Tt={}));const It=new Map([[Tt.CIRCLE,"tb.rulenode.perimeter-circle"],[Tt.POLYGON,"tb.rulenode.perimeter-polygon"]]);var Nt;!function(e){e.MILLISECONDS="MILLISECONDS",e.SECONDS="SECONDS",e.MINUTES="MINUTES",e.HOURS="HOURS",e.DAYS="DAYS"}(Nt||(Nt={}));const St=new Map([[Nt.MILLISECONDS,"tb.rulenode.time-unit-milliseconds"],[Nt.SECONDS,"tb.rulenode.time-unit-seconds"],[Nt.MINUTES,"tb.rulenode.time-unit-minutes"],[Nt.HOURS,"tb.rulenode.time-unit-hours"],[Nt.DAYS,"tb.rulenode.time-unit-days"]]);var qt;!function(e){e.METER="METER",e.KILOMETER="KILOMETER",e.FOOT="FOOT",e.MILE="MILE",e.NAUTICAL_MILE="NAUTICAL_MILE"}(qt||(qt={}));const At=new Map([[qt.METER,"tb.rulenode.range-unit-meter"],[qt.KILOMETER,"tb.rulenode.range-unit-kilometer"],[qt.FOOT,"tb.rulenode.range-unit-foot"],[qt.MILE,"tb.rulenode.range-unit-mile"],[qt.NAUTICAL_MILE,"tb.rulenode.range-unit-nautical-mile"]]);var Mt;!function(e){e.ID="ID",e.TITLE="TITLE",e.COUNTRY="COUNTRY",e.STATE="STATE",e.CITY="CITY",e.ZIP="ZIP",e.ADDRESS="ADDRESS",e.ADDRESS2="ADDRESS2",e.PHONE="PHONE",e.EMAIL="EMAIL",e.ADDITIONAL_INFO="ADDITIONAL_INFO"}(Mt||(Mt={}));const Et=new Map([[Mt.ID,"tb.rulenode.entity-details-id"],[Mt.TITLE,"tb.rulenode.entity-details-title"],[Mt.COUNTRY,"tb.rulenode.entity-details-country"],[Mt.STATE,"tb.rulenode.entity-details-state"],[Mt.CITY,"tb.rulenode.entity-details-city"],[Mt.ZIP,"tb.rulenode.entity-details-zip"],[Mt.ADDRESS,"tb.rulenode.entity-details-address"],[Mt.ADDRESS2,"tb.rulenode.entity-details-address2"],[Mt.PHONE,"tb.rulenode.entity-details-phone"],[Mt.EMAIL,"tb.rulenode.entity-details-email"],[Mt.ADDITIONAL_INFO,"tb.rulenode.entity-details-additional_info"]]);var Gt;!function(e){e.FIRST="FIRST",e.LAST="LAST",e.ALL="ALL"}(Gt||(Gt={}));const Dt=new Map([[Gt.FIRST,"tb.rulenode.first"],[Gt.LAST,"tb.rulenode.last"],[Gt.ALL,"tb.rulenode.all"]]),wt=new Map([[Gt.FIRST,"tb.rulenode.first-mode-hint"],[Gt.LAST,"tb.rulenode.last-mode-hint"],[Gt.ALL,"tb.rulenode.all-mode-hint"]]);var Vt,Pt;!function(e){e.ASC="ASC",e.DESC="DESC"}(Vt||(Vt={})),function(e){e.ATTRIBUTES="ATTRIBUTES",e.LATEST_TELEMETRY="LATEST_TELEMETRY",e.FIELDS="FIELDS"}(Pt||(Pt={}));const Rt=new Map([[Pt.ATTRIBUTES,"tb.rulenode.attributes"],[Pt.LATEST_TELEMETRY,"tb.rulenode.latest-telemetry"],[Pt.FIELDS,"tb.rulenode.fields"]]),Ot=new Map([[Pt.ATTRIBUTES,"tb.rulenode.add-mapped-attribute-to"],[Pt.LATEST_TELEMETRY,"tb.rulenode.add-mapped-latest-telemetry-to"],[Pt.FIELDS,"tb.rulenode.add-mapped-fields-to"]]),_t=new Map([[Vt.ASC,"tb.rulenode.ascending"],[Vt.DESC,"tb.rulenode.descending"]]);var Bt;!function(e){e.STANDARD="STANDARD",e.FIFO="FIFO"}(Bt||(Bt={}));const Kt=new Map([[Bt.STANDARD,"tb.rulenode.sqs-queue-standard"],[Bt.FIFO,"tb.rulenode.sqs-queue-fifo"]]),zt=["anonymous","basic","cert.PEM"],Ut=new Map([["anonymous","tb.rulenode.credentials-anonymous"],["basic","tb.rulenode.credentials-basic"],["cert.PEM","tb.rulenode.credentials-pem"]]),Ht=["sas","cert.PEM"],jt=new Map([["sas","tb.rulenode.credentials-sas"],["cert.PEM","tb.rulenode.credentials-pem"]]);var $t;!function(e){e.GET="GET",e.POST="POST",e.PUT="PUT",e.DELETE="DELETE"}($t||($t={}));const Qt=["US-ASCII","ISO-8859-1","UTF-8","UTF-16BE","UTF-16LE","UTF-16"],Jt=new Map([["US-ASCII","tb.rulenode.charset-us-ascii"],["ISO-8859-1","tb.rulenode.charset-iso-8859-1"],["UTF-8","tb.rulenode.charset-utf-8"],["UTF-16BE","tb.rulenode.charset-utf-16be"],["UTF-16LE","tb.rulenode.charset-utf-16le"],["UTF-16","tb.rulenode.charset-utf-16"]]);var Yt;!function(e){e.CUSTOM="CUSTOM",e.ADD="ADD",e.SUB="SUB",e.MULT="MULT",e.DIV="DIV",e.SIN="SIN",e.SINH="SINH",e.COS="COS",e.COSH="COSH",e.TAN="TAN",e.TANH="TANH",e.ACOS="ACOS",e.ASIN="ASIN",e.ATAN="ATAN",e.ATAN2="ATAN2",e.EXP="EXP",e.EXPM1="EXPM1",e.SQRT="SQRT",e.CBRT="CBRT",e.GET_EXP="GET_EXP",e.HYPOT="HYPOT",e.LOG="LOG",e.LOG10="LOG10",e.LOG1P="LOG1P",e.CEIL="CEIL",e.FLOOR="FLOOR",e.FLOOR_DIV="FLOOR_DIV",e.FLOOR_MOD="FLOOR_MOD",e.ABS="ABS",e.MIN="MIN",e.MAX="MAX",e.POW="POW",e.SIGNUM="SIGNUM",e.RAD="RAD",e.DEG="DEG"}(Yt||(Yt={}));const Wt=new Map([[Yt.CUSTOM,{value:Yt.CUSTOM,name:"Custom Function",description:"Use this function to specify complex mathematical expression.",minArgs:1,maxArgs:16}],[Yt.ADD,{value:Yt.ADD,name:"Addition",description:"x + y",minArgs:2,maxArgs:2}],[Yt.SUB,{value:Yt.SUB,name:"Subtraction",description:"x - y",minArgs:2,maxArgs:2}],[Yt.MULT,{value:Yt.MULT,name:"Multiplication",description:"x * y",minArgs:2,maxArgs:2}],[Yt.DIV,{value:Yt.DIV,name:"Division",description:"x / y",minArgs:2,maxArgs:2}],[Yt.SIN,{value:Yt.SIN,name:"Sine",description:"Returns the trigonometric sine of an angle in radians.",minArgs:1,maxArgs:1}],[Yt.SINH,{value:Yt.SINH,name:"Hyperbolic sine",description:"Returns the hyperbolic sine of an argument.",minArgs:1,maxArgs:1}],[Yt.COS,{value:Yt.COS,name:"Cosine",description:"Returns the trigonometric cosine of an angle in radians.",minArgs:1,maxArgs:1}],[Yt.COSH,{value:Yt.COSH,name:"Hyperbolic cosine",description:"Returns the hyperbolic cosine of an argument.",minArgs:1,maxArgs:1}],[Yt.TAN,{value:Yt.TAN,name:"Tangent",description:"Returns the trigonometric tangent of an angle in radians",minArgs:1,maxArgs:1}],[Yt.TANH,{value:Yt.TANH,name:"Hyperbolic tangent",description:"Returns the hyperbolic tangent of an argument",minArgs:1,maxArgs:1}],[Yt.ACOS,{value:Yt.ACOS,name:"Arc cosine",description:"Returns the arc cosine of an argument",minArgs:1,maxArgs:1}],[Yt.ASIN,{value:Yt.ASIN,name:"Arc sine",description:"Returns the arc sine of an argument",minArgs:1,maxArgs:1}],[Yt.ATAN,{value:Yt.ATAN,name:"Arc tangent",description:"Returns the arc tangent of an argument",minArgs:1,maxArgs:1}],[Yt.ATAN2,{value:Yt.ATAN2,name:"2-argument arc tangent",description:"Returns the angle theta from the conversion of rectangular coordinates (x, y) to polar coordinates (r, theta)",minArgs:2,maxArgs:2}],[Yt.EXP,{value:Yt.EXP,name:"Exponential",description:"Returns Euler's number e raised to the power of an argument",minArgs:1,maxArgs:1}],[Yt.EXPM1,{value:Yt.EXPM1,name:"Exponential minus one",description:"Returns Euler's number e raised to the power of an argument minus one",minArgs:1,maxArgs:1}],[Yt.SQRT,{value:Yt.SQRT,name:"Square",description:"Returns the correctly rounded positive square root of an argument",minArgs:1,maxArgs:1}],[Yt.CBRT,{value:Yt.CBRT,name:"Cube root",description:"Returns the cube root of an argument",minArgs:1,maxArgs:1}],[Yt.GET_EXP,{value:Yt.GET_EXP,name:"Get exponent",description:"Returns the unbiased exponent used in the representation of an argument",minArgs:1,maxArgs:1}],[Yt.HYPOT,{value:Yt.HYPOT,name:"Square root",description:"Returns the square root of the squares of the arguments",minArgs:2,maxArgs:2}],[Yt.LOG,{value:Yt.LOG,name:"Logarithm",description:"Returns the natural logarithm of an argument",minArgs:1,maxArgs:1}],[Yt.LOG10,{value:Yt.LOG10,name:"Base 10 logarithm",description:"Returns the base 10 logarithm of an argument",minArgs:1,maxArgs:1}],[Yt.LOG1P,{value:Yt.LOG1P,name:"Logarithm of the sum",description:"Returns the natural logarithm of the sum of an argument",minArgs:1,maxArgs:1}],[Yt.CEIL,{value:Yt.CEIL,name:"Ceiling",description:"Returns the smallest (closest to negative infinity) of an argument",minArgs:1,maxArgs:1}],[Yt.FLOOR,{value:Yt.FLOOR,name:"Floor",description:"Returns the largest (closest to positive infinity) of an argument",minArgs:1,maxArgs:1}],[Yt.FLOOR_DIV,{value:Yt.FLOOR_DIV,name:"Floor division",description:"Returns the largest (closest to positive infinity) of the arguments",minArgs:2,maxArgs:2}],[Yt.FLOOR_MOD,{value:Yt.FLOOR_MOD,name:"Floor modulus",description:"Returns the floor modulus of the arguments",minArgs:2,maxArgs:2}],[Yt.ABS,{value:Yt.ABS,name:"Absolute",description:"Returns the absolute value of an argument",minArgs:1,maxArgs:1}],[Yt.MIN,{value:Yt.MIN,name:"Min",description:"Returns the smaller of the arguments",minArgs:2,maxArgs:2}],[Yt.MAX,{value:Yt.MAX,name:"Max",description:"Returns the greater of the arguments",minArgs:2,maxArgs:2}],[Yt.POW,{value:Yt.POW,name:"Raise to a power",description:"Returns the value of the first argument raised to the power of the second argument",minArgs:2,maxArgs:2}],[Yt.SIGNUM,{value:Yt.SIGNUM,name:"Sign of a real number",description:"Returns the signum function of the argument",minArgs:1,maxArgs:1}],[Yt.RAD,{value:Yt.RAD,name:"Radian",description:"Converts an angle measured in degrees to an approximately equivalent angle measured in radians",minArgs:1,maxArgs:1}],[Yt.DEG,{value:Yt.DEG,name:"Degrees",description:"Converts an angle measured in radians to an approximately equivalent angle measured in degrees.",minArgs:1,maxArgs:1}]]);var Zt,Xt,en;!function(e){e.MESSAGE_BODY="MESSAGE_BODY",e.MESSAGE_METADATA="MESSAGE_METADATA",e.ATTRIBUTE="ATTRIBUTE",e.TIME_SERIES="TIME_SERIES",e.CONSTANT="CONSTANT"}(Zt||(Zt={})),function(e){e.MESSAGE_BODY="MESSAGE_BODY",e.MESSAGE_METADATA="MESSAGE_METADATA",e.ATTRIBUTE="ATTRIBUTE",e.TIME_SERIES="TIME_SERIES"}(Xt||(Xt={})),function(e){e.DATA="DATA",e.METADATA="METADATA"}(en||(en={}));const tn=new Map([[en.DATA,"tb.rulenode.message-to-metadata"],[en.METADATA,"tb.rulenode.metadata-to-message"]]),nn=(new Map([[en.DATA,"tb.rulenode.from-message"],[en.METADATA,"tb.rulenode.from-metadata"]]),new Map([[en.DATA,"tb.rulenode.message"],[en.METADATA,"tb.rulenode.metadata"]])),rn=new Map([[en.DATA,"tb.rulenode.message"],[en.METADATA,"tb.rulenode.message-metadata"]]),on=new Map([[Zt.MESSAGE_BODY,{name:"tb.rulenode.message-body-type",description:"Fetch argument value from incoming message"}],[Zt.MESSAGE_METADATA,{name:"tb.rulenode.message-metadata-type",description:"Fetch argument value from incoming message metadata"}],[Zt.ATTRIBUTE,{name:"tb.rulenode.attribute-type",description:"Fetch attribute value from database"}],[Zt.TIME_SERIES,{name:"tb.rulenode.time-series-type",description:"Fetch latest time-series value from database"}],[Zt.CONSTANT,{name:"tb.rulenode.constant-type",description:"Define constant value"}]]),an=new Map([[Xt.MESSAGE_BODY,{name:"tb.rulenode.message-body-type",description:"Add result to the outgoing message"}],[Xt.MESSAGE_METADATA,{name:"tb.rulenode.message-metadata-type",description:"Add result to the outgoing message metadata"}],[Xt.ATTRIBUTE,{name:"tb.rulenode.attribute-type",description:"Store result as an entity attribute in the database"}],[Xt.TIME_SERIES,{name:"tb.rulenode.time-series-type",description:"Store result as an entity time-series in the database"}]]),ln=["x","y","z","a","b","c","d","k","l","m","n","o","p","r","s","t"];var sn,mn;!function(e){e.SHARED_SCOPE="SHARED_SCOPE",e.SERVER_SCOPE="SERVER_SCOPE",e.CLIENT_SCOPE="CLIENT_SCOPE"}(sn||(sn={})),function(e){e.SHARED_SCOPE="SHARED_SCOPE",e.SERVER_SCOPE="SERVER_SCOPE"}(mn||(mn={}));const pn=new Map([[sn.SHARED_SCOPE,"tb.rulenode.shared-scope"],[sn.SERVER_SCOPE,"tb.rulenode.server-scope"],[sn.CLIENT_SCOPE,"tb.rulenode.client-scope"]]);class dn extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.perimeterType=Tt,this.perimeterTypes=Object.keys(Tt),this.perimeterTypeTranslationMap=It,this.rangeUnits=Object.keys(qt),this.rangeUnitTranslationMap=At,this.timeUnits=Object.keys(Nt),this.timeUnitsTranslationMap=St}configForm(){return this.geoActionConfigForm}onConfigurationSet(e){this.geoActionConfigForm=this.fb.group({latitudeKeyName:[e?e.latitudeKeyName:null,[O.required]],longitudeKeyName:[e?e.longitudeKeyName:null,[O.required]],perimeterType:[e?e.perimeterType:null,[O.required]],fetchPerimeterInfoFromMessageMetadata:[!!e&&e.fetchPerimeterInfoFromMessageMetadata,[]],perimeterKeyName:[e?e.perimeterKeyName:null,[]],centerLatitude:[e?e.centerLatitude:null,[]],centerLongitude:[e?e.centerLatitude:null,[]],range:[e?e.range:null,[]],rangeUnit:[e?e.rangeUnit:null,[]],polygonsDefinition:[e?e.polygonsDefinition:null,[]],minInsideDuration:[e?e.minInsideDuration:null,[O.required,O.min(1),O.max(2147483647)]],minInsideDurationTimeUnit:[e?e.minInsideDurationTimeUnit:null,[O.required]],minOutsideDuration:[e?e.minOutsideDuration:null,[O.required,O.min(1),O.max(2147483647)]],minOutsideDurationTimeUnit:[e?e.minOutsideDurationTimeUnit:null,[O.required]]})}validatorTriggers(){return["fetchPerimeterInfoFromMessageMetadata","perimeterType"]}updateValidators(e){const t=this.geoActionConfigForm.get("fetchPerimeterInfoFromMessageMetadata").value,n=this.geoActionConfigForm.get("perimeterType").value;t?this.geoActionConfigForm.get("perimeterKeyName").setValidators([O.required]):this.geoActionConfigForm.get("perimeterKeyName").setValidators([]),t||n!==Tt.CIRCLE?(this.geoActionConfigForm.get("centerLatitude").setValidators([]),this.geoActionConfigForm.get("centerLongitude").setValidators([]),this.geoActionConfigForm.get("range").setValidators([]),this.geoActionConfigForm.get("rangeUnit").setValidators([])):(this.geoActionConfigForm.get("centerLatitude").setValidators([O.required,O.min(-90),O.max(90)]),this.geoActionConfigForm.get("centerLongitude").setValidators([O.required,O.min(-180),O.max(180)]),this.geoActionConfigForm.get("range").setValidators([O.required,O.min(0)]),this.geoActionConfigForm.get("rangeUnit").setValidators([O.required])),t||n!==Tt.POLYGON?this.geoActionConfigForm.get("polygonsDefinition").setValidators([]):this.geoActionConfigForm.get("polygonsDefinition").setValidators([O.required]),this.geoActionConfigForm.get("perimeterKeyName").updateValueAndValidity({emitEvent:e}),this.geoActionConfigForm.get("centerLatitude").updateValueAndValidity({emitEvent:e}),this.geoActionConfigForm.get("centerLongitude").updateValueAndValidity({emitEvent:e}),this.geoActionConfigForm.get("range").updateValueAndValidity({emitEvent:e}),this.geoActionConfigForm.get("rangeUnit").updateValueAndValidity({emitEvent:e}),this.geoActionConfigForm.get("polygonsDefinition").updateValueAndValidity({emitEvent:e})}}e("GpsGeoActionConfigComponent",dn),dn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:dn,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),dn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:dn,selector:"tb-action-node-gps-geofencing-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.latitude-key-name\n \n \n {{ \'tb.rulenode.latitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.longitude-key-name\n \n \n {{ \'tb.rulenode.longitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.perimeter-type\n \n \n {{ perimeterTypeTranslationMap.get(type) | translate }}\n \n \n \n \n {{ \'tb.rulenode.fetch-perimeter-info-from-metadata\' | translate }}\n \n \n tb.rulenode.perimeter-key-name\n \n \n {{ \'tb.rulenode.perimeter-key-name-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.circle-center-latitude\n \n \n {{ \'tb.rulenode.circle-center-latitude-required\' | translate }}\n \n \n \n tb.rulenode.circle-center-longitude\n \n \n {{ \'tb.rulenode.circle-center-longitude-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.range\n \n \n {{ \'tb.rulenode.range-required\' | translate }}\n \n \n \n tb.rulenode.range-units\n \n \n {{ rangeUnitTranslationMap.get(type) | translate }}\n \n \n \n
\n
\n
\n \n tb.rulenode.polygon-definition\n \n \n {{ \'tb.rulenode.polygon-definition-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.min-inside-duration\n \n \n {{ \'tb.rulenode.min-inside-duration-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n tb.rulenode.min-inside-duration-time-unit\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n \n tb.rulenode.min-outside-duration\n \n \n {{ \'tb.rulenode.min-outside-duration-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n tb.rulenode.min-outside-duration-time-unit\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Q.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:dn,decorators:[{type:n,args:[{selector:"tb-action-node-gps-geofencing-config",template:'
\n \n tb.rulenode.latitude-key-name\n \n \n {{ \'tb.rulenode.latitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.longitude-key-name\n \n \n {{ \'tb.rulenode.longitude-key-name-required\' | translate }}\n \n \n \n tb.rulenode.perimeter-type\n \n \n {{ perimeterTypeTranslationMap.get(type) | translate }}\n \n \n \n \n {{ \'tb.rulenode.fetch-perimeter-info-from-metadata\' | translate }}\n \n \n tb.rulenode.perimeter-key-name\n \n \n {{ \'tb.rulenode.perimeter-key-name-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.circle-center-latitude\n \n \n {{ \'tb.rulenode.circle-center-latitude-required\' | translate }}\n \n \n \n tb.rulenode.circle-center-longitude\n \n \n {{ \'tb.rulenode.circle-center-longitude-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.range\n \n \n {{ \'tb.rulenode.range-required\' | translate }}\n \n \n \n tb.rulenode.range-units\n \n \n {{ rangeUnitTranslationMap.get(type) | translate }}\n \n \n \n
\n
\n
\n \n tb.rulenode.polygon-definition\n \n \n {{ \'tb.rulenode.polygon-definition-required\' | translate }}\n \n \n
\n
\n \n tb.rulenode.min-inside-duration\n \n \n {{ \'tb.rulenode.min-inside-duration-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n tb.rulenode.min-inside-duration-time-unit\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n \n tb.rulenode.min-outside-duration\n \n \n {{ \'tb.rulenode.min-outside-duration-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n tb.rulenode.min-outside-duration-time-unit\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class un extends f{constructor(e,t,n,o){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=n,this.translate=o,this.tbelEnabled=re(this.store).tbelEnabled,this.scriptLanguage=x,this.changeScript=new r,this.hasScript=!0,this.testScriptLabel="tb.rulenode.test-to-string-function"}configForm(){return this.logConfigForm}onConfigurationSet(e){this.logConfigForm=this.fb.group({scriptLang:[e?e.scriptLang:x.JS,[O.required]],jsScript:[e?e.jsScript:null,[]],tbelScript:[e?e.tbelScript:null,[]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.logConfigForm.get("scriptLang").value;t!==x.TBEL||this.tbelEnabled||(t=x.JS,this.logConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.logConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.logConfigForm.get("jsScript").setValidators(t===x.JS?[O.required]:[]),this.logConfigForm.get("jsScript").updateValueAndValidity({emitEvent:e}),this.logConfigForm.get("tbelScript").setValidators(t===x.TBEL?[O.required]:[]),this.logConfigForm.get("tbelScript").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=x.JS)),e}testScript(e){const t=this.logConfigForm.get("scriptLang").value,n=t===x.JS?"jsScript":"tbelScript",r=t===x.JS?"rulenode/log_node_script_fn":"rulenode/tbel/log_node_script_fn",o=this.logConfigForm.get(n).value;this.nodeScriptTestService.testNodeScript(o,"string",this.translate.instant("tb.rulenode.to-string"),"ToString",["msg","metadata","msgType"],this.ruleNodeId,r,t,e).subscribe((e=>{e&&(this.logConfigForm.get(n).setValue(e),this.changeScript.emit())}))}onValidate(){this.logConfigForm.get("scriptLang").value===x.JS&&this.jsFuncComponent.validateOnSubmit()}}e("LogConfigComponent",un),un.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:un,deps:[{token:P.Store},{token:R.UntypedFormBuilder},{token:oe.NodeScriptTestService},{token:Z.TranslateService}],target:t.ɵɵFactoryTarget.Component}),un.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:un,selector:"tb-action-node-log-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n \n \n
\n \n
\n
\n',dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:pe.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:de.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:de.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:fe.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:un,decorators:[{type:n,args:[{selector:"tb-action-node-log-config",template:'
\n \n \n \n \n \n \n \n
\n \n
\n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder},{type:oe.NodeScriptTestService},{type:Z.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}});class cn extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.msgCountConfigForm}onConfigurationSet(e){this.msgCountConfigForm=this.fb.group({interval:[e?e.interval:null,[O.required,O.min(1)]],telemetryPrefix:[e?e.telemetryPrefix:null,[O.required]]})}}e("MsgCountConfigComponent",cn),cn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:cn,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),cn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:cn,selector:"tb-action-node-msg-count-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.interval-seconds\n \n \n {{ \'tb.rulenode.interval-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-interval-seconds-message\' | translate }}\n \n \n \n tb.rulenode.output-timeseries-key-prefix\n \n \n {{ \'tb.rulenode.output-timeseries-key-prefix-required\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:cn,decorators:[{type:n,args:[{selector:"tb-action-node-msg-count-config",template:'
\n \n tb.rulenode.interval-seconds\n \n \n {{ \'tb.rulenode.interval-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-interval-seconds-message\' | translate }}\n \n \n \n tb.rulenode.output-timeseries-key-prefix\n \n \n {{ \'tb.rulenode.output-timeseries-key-prefix-required\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class fn extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.msgDelayConfigForm}onConfigurationSet(e){this.msgDelayConfigForm=this.fb.group({useMetadataPeriodInSecondsPatterns:[!!e&&e.useMetadataPeriodInSecondsPatterns,[]],periodInSeconds:[e?e.periodInSeconds:null,[]],periodInSecondsPattern:[e?e.periodInSecondsPattern:null,[]],maxPendingMsgs:[e?e.maxPendingMsgs:null,[O.required,O.min(1),O.max(1e5)]]})}validatorTriggers(){return["useMetadataPeriodInSecondsPatterns"]}updateValidators(e){this.msgDelayConfigForm.get("useMetadataPeriodInSecondsPatterns").value?(this.msgDelayConfigForm.get("periodInSecondsPattern").setValidators([O.required]),this.msgDelayConfigForm.get("periodInSeconds").setValidators([])):(this.msgDelayConfigForm.get("periodInSecondsPattern").setValidators([]),this.msgDelayConfigForm.get("periodInSeconds").setValidators([O.required,O.min(0)])),this.msgDelayConfigForm.get("periodInSecondsPattern").updateValueAndValidity({emitEvent:e}),this.msgDelayConfigForm.get("periodInSeconds").updateValueAndValidity({emitEvent:e})}}e("MsgDelayConfigComponent",fn),fn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:fn,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),fn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:fn,selector:"tb-action-node-msg-delay-config",usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.use-metadata-period-in-seconds-patterns\' | translate }}\n \n
tb.rulenode.use-metadata-period-in-seconds-patterns-hint
\n \n tb.rulenode.period-seconds\n \n \n {{ \'tb.rulenode.period-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-period-0-seconds-message\' | translate }}\n \n \n \n \n tb.rulenode.period-in-seconds-pattern\n \n \n {{ \'tb.rulenode.period-in-seconds-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n \n tb.rulenode.max-pending-messages\n \n \n {{ \'tb.rulenode.max-pending-messages-required\' | translate }}\n \n \n {{ \'tb.rulenode.max-pending-messages-range\' | translate }}\n \n \n {{ \'tb.rulenode.max-pending-messages-range\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Q.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:fn,decorators:[{type:n,args:[{selector:"tb-action-node-msg-delay-config",template:'
\n \n {{ \'tb.rulenode.use-metadata-period-in-seconds-patterns\' | translate }}\n \n
tb.rulenode.use-metadata-period-in-seconds-patterns-hint
\n \n tb.rulenode.period-seconds\n \n \n {{ \'tb.rulenode.period-seconds-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-period-0-seconds-message\' | translate }}\n \n \n \n \n tb.rulenode.period-in-seconds-pattern\n \n \n {{ \'tb.rulenode.period-in-seconds-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n \n tb.rulenode.max-pending-messages\n \n \n {{ \'tb.rulenode.max-pending-messages-required\' | translate }}\n \n \n {{ \'tb.rulenode.max-pending-messages-range\' | translate }}\n \n \n {{ \'tb.rulenode.max-pending-messages-range\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class gn extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.attributeScopes=Object.keys(g),this.telemetryTypeTranslationsMap=y}configForm(){return this.pushToCloudConfigForm}onConfigurationSet(e){this.pushToCloudConfigForm=this.fb.group({scope:[e?e.scope:null,[O.required]]})}}e("PushToCloudConfigComponent",gn),gn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:gn,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),gn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:gn,selector:"tb-action-node-push-to-cloud-config",usesInheritance:!0,ngImport:t,template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:gn,decorators:[{type:n,args:[{selector:"tb-action-node-push-to-cloud-config",template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class yn extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.attributeScopes=Object.keys(g),this.telemetryTypeTranslationsMap=y}configForm(){return this.pushToEdgeConfigForm}onConfigurationSet(e){this.pushToEdgeConfigForm=this.fb.group({scope:[e?e.scope:null,[O.required]]})}}e("PushToEdgeConfigComponent",yn),yn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:yn,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),yn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:yn,selector:"tb-action-node-push-to-edge-config",usesInheritance:!0,ngImport:t,template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:yn,decorators:[{type:n,args:[{selector:"tb-action-node-push-to-edge-config",template:'
\n \n attribute.attributes-scope\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class xn extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.rpcReplyConfigForm}onConfigurationSet(e){this.rpcReplyConfigForm=this.fb.group({requestIdMetaDataAttribute:[e?e.requestIdMetaDataAttribute:null,[]]})}}e("RpcReplyConfigComponent",xn),xn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:xn,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),xn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:xn,selector:"tb-action-node-rpc-reply-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.request-id-metadata-attribute\n \n \n
\n',dependencies:[{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:xn,decorators:[{type:n,args:[{selector:"tb-action-node-rpc-reply-config",template:'
\n \n tb.rulenode.request-id-metadata-attribute\n \n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class bn extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.rpcRequestConfigForm}onConfigurationSet(e){this.rpcRequestConfigForm=this.fb.group({timeoutInSeconds:[e?e.timeoutInSeconds:null,[O.required,O.min(0)]]})}}e("RpcRequestConfigComponent",bn),bn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:bn,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),bn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:bn,selector:"tb-action-node-rpc-request-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.timeout-sec\n \n \n {{ \'tb.rulenode.timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-timeout-message\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:bn,decorators:[{type:n,args:[{selector:"tb-action-node-rpc-request-config",template:'
\n \n tb.rulenode.timeout-sec\n \n \n {{ \'tb.rulenode.timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-timeout-message\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class hn extends L{get required(){return this.requiredValue}set required(e){this.requiredValue=Fe(e)}constructor(e,t,n,r){super(e),this.store=e,this.translate=t,this.injector=n,this.fb=r,this.propagateChange=null,this.valueChangeSubscription=null}ngOnInit(){this.ngControl=this.injector.get(_),null!=this.ngControl&&(this.ngControl.valueAccessor=this),this.kvListFormGroup=this.fb.group({}),this.kvListFormGroup.addControl("keyVals",this.fb.array([]))}keyValsFormArray(){return this.kvListFormGroup.get("keyVals")}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.kvListFormGroup.disable({emitEvent:!1}):this.kvListFormGroup.enable({emitEvent:!1})}writeValue(e){this.valueChangeSubscription&&this.valueChangeSubscription.unsubscribe();const t=[];if(e)for(const n of Object.keys(e))Object.prototype.hasOwnProperty.call(e,n)&&t.push(this.fb.group({key:[n,[O.required]],value:[e[n],[O.required]]}));this.kvListFormGroup.setControl("keyVals",this.fb.array(t)),this.valueChangeSubscription=this.kvListFormGroup.valueChanges.subscribe((()=>{this.updateModel()}))}removeKeyVal(e){this.kvListFormGroup.get("keyVals").removeAt(e)}addKeyVal(){this.kvListFormGroup.get("keyVals").push(this.fb.group({key:["",[O.required]],value:["",[O.required]]}))}validate(e){const t=this.kvListFormGroup.get("keyVals").value;if(!t.length&&this.required)return{kvMapRequired:!0};if(!this.kvListFormGroup.valid)return{kvFieldsRequired:!0};if(this.uniqueKeyValuePairValidator)for(const e of t)if(e.key===e.value)return{uniqueKeyValuePair:!0};return null}updateModel(){const e=this.kvListFormGroup.get("keyVals").value;if(this.required&&!e.length||!this.kvListFormGroup.valid)this.propagateChange(null);else{const t={};e.forEach((e=>{t[e.key]=e.value})),this.propagateChange(t)}}}e("KvMapConfigOldComponent",hn),hn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:hn,deps:[{token:P.Store},{token:Z.TranslateService},{token:t.Injector},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),hn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:hn,selector:"tb-kv-map-config-old",inputs:{disabled:"disabled",uniqueKeyValuePairValidator:"uniqueKeyValuePairValidator",requiredText:"requiredText",keyText:"keyText",keyRequiredText:"keyRequiredText",valText:"valText",valRequiredText:"valRequiredText",hintText:"hintText",required:"required"},providers:[{provide:B,useExisting:a((()=>hn)),multi:!0},{provide:K,useExisting:a((()=>hn)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n
\n {{ keyText | translate }}\n {{ valText | translate }}\n \n
\n
\n
\n \n \n \n {{ keyRequiredText | translate }}\n \n \n \n \n \n {{ valRequiredText | translate }}\n \n \n \n
\n
\n
\n \n
\n \n
\n
\n',styles:[":host .tb-kv-map-config{margin-bottom:16px}:host .tb-kv-map-config .header{padding-left:5px;padding-right:5px;padding-bottom:5px}:host .tb-kv-map-config .header .cell{padding-left:5px;padding-right:5px;color:#757575;font-size:12px;font-weight:700;white-space:nowrap}:host .tb-kv-map-config .header .tb-required:after{color:#757575;font-size:12px;font-weight:700}:host .tb-kv-map-config .body{padding-left:5px;padding-right:5px;padding-bottom:0;max-height:300px;overflow:auto}:host .tb-kv-map-config .body .cell{padding-left:5px;padding-right:5px}:host .tb-kv-map-config tb-error{display:block;margin-top:-12px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Te.TbErrorComponent,selector:"tb-error",inputs:["noMargin","error"]},{kind:"component",type:de.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:de.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:W.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:Ie.DefaultShowHideDirective,selector:" [fxShow], [fxShow.print], [fxShow.xs], [fxShow.sm], [fxShow.md], [fxShow.lg], [fxShow.xl], [fxShow.lt-sm], [fxShow.lt-md], [fxShow.lt-lg], [fxShow.lt-xl], [fxShow.gt-xs], [fxShow.gt-sm], [fxShow.gt-md], [fxShow.gt-lg], [fxHide], [fxHide.print], [fxHide.xs], [fxHide.sm], [fxHide.md], [fxHide.lg], [fxHide.xl], [fxHide.lt-sm], [fxHide.lt-md], [fxHide.lt-lg], [fxHide.lt-xl], [fxHide.gt-xs], [fxHide.gt-sm], [fxHide.gt-md], [fxHide.gt-lg]",inputs:["fxShow","fxShow.print","fxShow.xs","fxShow.sm","fxShow.md","fxShow.lg","fxShow.xl","fxShow.lt-sm","fxShow.lt-md","fxShow.lt-lg","fxShow.lt-xl","fxShow.gt-xs","fxShow.gt-sm","fxShow.gt-md","fxShow.gt-lg","fxHide","fxHide.print","fxHide.xs","fxHide.sm","fxHide.md","fxHide.lg","fxHide.xl","fxHide.lt-sm","fxHide.lt-md","fxHide.lt-lg","fxHide.lt-xl","fxHide.gt-xs","fxHide.gt-sm","fxHide.gt-md","fxHide.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormControlDirective,selector:"[formControl]",inputs:["formControl","disabled","ngModel"],outputs:["ngModelChange"],exportAs:["ngForm"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormArrayName,selector:"[formArrayName]",inputs:["formArrayName"]},{kind:"pipe",type:H.AsyncPipe,name:"async"},{kind:"pipe",type:he.SafePipe,name:"safe"},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:hn,decorators:[{type:n,args:[{selector:"tb-kv-map-config-old",providers:[{provide:B,useExisting:a((()=>hn)),multi:!0},{provide:K,useExisting:a((()=>hn)),multi:!0}],template:'
\n
\n {{ keyText | translate }}\n {{ valText | translate }}\n \n
\n
\n
\n \n \n \n {{ keyRequiredText | translate }}\n \n \n \n \n \n {{ valRequiredText | translate }}\n \n \n \n
\n
\n
\n \n
\n \n
\n
\n',styles:[":host .tb-kv-map-config{margin-bottom:16px}:host .tb-kv-map-config .header{padding-left:5px;padding-right:5px;padding-bottom:5px}:host .tb-kv-map-config .header .cell{padding-left:5px;padding-right:5px;color:#757575;font-size:12px;font-weight:700;white-space:nowrap}:host .tb-kv-map-config .header .tb-required:after{color:#757575;font-size:12px;font-weight:700}:host .tb-kv-map-config .body{padding-left:5px;padding-right:5px;padding-bottom:0;max-height:300px;overflow:auto}:host .tb-kv-map-config .body .cell{padding-left:5px;padding-right:5px}:host .tb-kv-map-config tb-error{display:block;margin-top:-12px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:P.Store},{type:Z.TranslateService},{type:t.Injector},{type:R.FormBuilder}]},propDecorators:{disabled:[{type:i}],uniqueKeyValuePairValidator:[{type:i}],requiredText:[{type:i}],keyText:[{type:i}],keyRequiredText:[{type:i}],valText:[{type:i}],valRequiredText:[{type:i}],hintText:[{type:i}],required:[{type:i}]}});class vn extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.saveToCustomTableConfigForm}onConfigurationSet(e){this.saveToCustomTableConfigForm=this.fb.group({tableName:[e?e.tableName:null,[O.required,O.pattern(/.*\S.*/)]],fieldsMapping:[e?e.fieldsMapping:null,[O.required]]})}prepareOutputConfig(e){return e.tableName=e.tableName.trim(),e}}e("SaveToCustomTableConfigComponent",vn),vn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:vn,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),vn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:vn,selector:"tb-action-node-custom-table-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.custom-table-name\n \n \n {{ \'tb.rulenode.custom-table-name-required\' | translate }}\n \n tb.rulenode.custom-table-hint\n \n \n \n \n
\n',dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:hn,selector:"tb-kv-map-config-old",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:vn,decorators:[{type:n,args:[{selector:"tb-action-node-custom-table-config",template:'
\n \n tb.rulenode.custom-table-name\n \n \n {{ \'tb.rulenode.custom-table-name-required\' | translate }}\n \n tb.rulenode.custom-table-hint\n \n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class Cn extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.timeseriesConfigForm}onConfigurationSet(e){this.timeseriesConfigForm=this.fb.group({defaultTTL:[e?e.defaultTTL:null,[O.required,O.min(0)]],skipLatestPersistence:[!!e&&e.skipLatestPersistence,[]],useServerTs:[!!e&&e.useServerTs,[]]})}}e("TimeseriesConfigComponent",Cn),Cn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Cn,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Cn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Cn,selector:"tb-action-node-timeseries-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.default-ttl\n \n \n {{ \'tb.rulenode.default-ttl-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-default-ttl-message\' | translate }}\n \n \n \n {{ \'tb.rulenode.skip-latest-persistence\' | translate }}\n \n \n {{ \'tb.rulenode.use-server-ts\' | translate }}\n \n
tb.rulenode.use-server-ts-hint
\n
\n',dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Q.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Cn,decorators:[{type:n,args:[{selector:"tb-action-node-timeseries-config",template:'
\n \n tb.rulenode.default-ttl\n \n \n {{ \'tb.rulenode.default-ttl-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-default-ttl-message\' | translate }}\n \n \n \n {{ \'tb.rulenode.skip-latest-persistence\' | translate }}\n \n \n {{ \'tb.rulenode.use-server-ts\' | translate }}\n \n
tb.rulenode.use-server-ts-hint
\n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class Fn extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.unassignCustomerConfigForm}onConfigurationSet(e){this.unassignCustomerConfigForm=this.fb.group({customerNamePattern:[e?e.customerNamePattern:null,[O.required,O.pattern(/.*\S.*/)]],customerCacheExpiration:[e?e.customerCacheExpiration:null,[O.required,O.min(0)]]})}prepareOutputConfig(e){return e.customerNamePattern=e.customerNamePattern.trim(),e}}e("UnassignCustomerConfigComponent",Fn),Fn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Fn,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Fn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Fn,selector:"tb-action-node-un-assign-to-customer-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.customer-name-pattern\n \n \n {{ \'tb.rulenode.customer-name-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.customer-cache-expiration\n \n \n {{ \'tb.rulenode.customer-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.customer-cache-expiration-range\' | translate }}\n \n tb.rulenode.customer-cache-expiration-hint\n \n
\n',dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Fn,decorators:[{type:n,args:[{selector:"tb-action-node-un-assign-to-customer-config",template:'
\n \n tb.rulenode.customer-name-pattern\n \n \n {{ \'tb.rulenode.customer-name-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.customer-cache-expiration\n \n \n {{ \'tb.rulenode.customer-cache-expiration-required\' | translate }}\n \n \n {{ \'tb.rulenode.customer-cache-expiration-range\' | translate }}\n \n tb.rulenode.customer-cache-expiration-hint\n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class kn extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.attributeScopeMap=g,this.attributeScopes=Object.keys(g),this.telemetryTypeTranslationsMap=y,this.separatorKeysCodes=[ge,ye,xe]}configForm(){return this.deleteAttributesConfigForm}onConfigurationSet(e){this.deleteAttributesConfigForm=this.fb.group({scope:[e?e.scope:null,[O.required]],keys:[e?e.keys:null,[O.required]],sendAttributesDeletedNotification:[!!e&&e.sendAttributesDeletedNotification,[]],notifyDevice:[!!e&&e.notifyDevice,[]]}),this.deleteAttributesConfigForm.get("scope").valueChanges.subscribe((e=>{e!==g.SHARED_SCOPE&&this.deleteAttributesConfigForm.get("notifyDevice").patchValue(!1,{emitEvent:!1})}))}removeKey(e){const t=this.deleteAttributesConfigForm.get("keys").value,n=t.indexOf(e);n>=0&&(t.splice(n,1),this.deleteAttributesConfigForm.get("keys").patchValue(t,{emitEvent:!0}))}addKey(e){const t=e.input;let n=e.value;if((n||"").trim()){n=n.trim();let e=this.deleteAttributesConfigForm.get("keys").value;e&&-1!==e.indexOf(n)||(e||(e=[]),e.push(n),this.deleteAttributesConfigForm.get("keys").patchValue(e,{emitEvent:!0}))}t&&(t.value="")}}e("DeleteAttributesConfigComponent",kn),kn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:kn,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),kn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:kn,selector:"tb-action-node-delete-attributes-config",viewQueries:[{propertyName:"attributeChipList",first:!0,predicate:["attributeChipList"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'attribute.attributes-scope\' | translate }}\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n \n {{ \'tb.rulenode.attributes-keys\' | translate }}\n \n \n {{key}}\n close\n \n \n \n {{ \'tb.rulenode.attributes-keys-required\' | translate }}\n tb.rulenode.general-pattern-hint\n \n \n {{ \'tb.rulenode.send-attributes-deleted-notification\' | translate }}\n \n
tb.rulenode.send-attributes-deleted-notification-hint
\n
\n \n {{ \'tb.rulenode.notify-device\' | translate }}\n \n
tb.rulenode.notify-device-on-delete-hint
\n
\n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Q.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:be.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:be.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:be.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:be.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:kn,decorators:[{type:n,args:[{selector:"tb-action-node-delete-attributes-config",template:'
\n \n {{ \'attribute.attributes-scope\' | translate }}\n \n \n {{ telemetryTypeTranslationsMap.get(scope) | translate }}\n \n \n \n \n {{ \'tb.rulenode.attributes-keys\' | translate }}\n \n \n {{key}}\n close\n \n \n \n {{ \'tb.rulenode.attributes-keys-required\' | translate }}\n tb.rulenode.general-pattern-hint\n \n \n {{ \'tb.rulenode.send-attributes-deleted-notification\' | translate }}\n \n
tb.rulenode.send-attributes-deleted-notification-hint
\n
\n \n {{ \'tb.rulenode.notify-device\' | translate }}\n \n
tb.rulenode.notify-device-on-delete-hint
\n
\n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]},propDecorators:{attributeChipList:[{type:o,args:["attributeChipList"]}]}});class Ln extends L{get function(){return this.functionValue}set function(e){e&&this.functionValue!==e&&(this.functionValue=e,this.setupArgumentsFormGroup(!0))}constructor(e,t){super(e),this.store=e,this.fb=t,this.maxArgs=16,this.minArgs=1,this.displayArgumentName=!1,this.mathFunctionMap=Wt,this.ArgumentType=Zt,this.attributeScopeMap=pn,this.argumentTypeMap=on,this.arguments=Object.values(Zt),this.attributeScope=Object.values(sn),this.propagateChange=null,this.valueChangeSubscription=[]}ngOnInit(){this.argumentsFormGroup=this.fb.group({arguments:this.fb.array([])}),this.valueChangeSubscription.push(this.argumentsFormGroup.valueChanges.subscribe((()=>{this.updateModel()}))),this.setupArgumentsFormGroup()}onDrop(e){const t=this.argumentsFormArray,n=t.at(e.previousIndex);t.removeAt(e.previousIndex),t.insert(e.currentIndex,n),this.updateArgumentNames()}get argumentsFormArray(){return this.argumentsFormGroup.get("arguments")}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.argumentsFormGroup.disable({emitEvent:!1}):(this.argumentsFormGroup.enable({emitEvent:!1}),this.argumentsFormArray.controls.forEach((e=>this.updateArgumentControlValidators(e))))}ngOnDestroy(){this.valueChangeSubscription.length&&this.valueChangeSubscription.forEach((e=>e.unsubscribe()))}writeValue(e){const t=[];e&&e.forEach(((e,n)=>{t.push(this.createArgumentControl(e,n))})),this.argumentsFormGroup.setControl("arguments",this.fb.array(t),{emitEvent:!1}),this.setupArgumentsFormGroup()}removeArgument(e){this.argumentsFormArray.removeAt(e),this.updateArgumentNames()}addArgument(e=!0){const t=this.argumentsFormArray,n=this.createArgumentControl(null,t.length);t.push(n,{emitEvent:e})}validate(e){return this.argumentsFormGroup.valid?null:{argumentsRequired:!0}}setupArgumentsFormGroup(e=!1){if(this.function&&(this.maxArgs=this.mathFunctionMap.get(this.function).maxArgs,this.minArgs=this.mathFunctionMap.get(this.function).minArgs,this.displayArgumentName=this.function===Yt.CUSTOM),this.argumentsFormGroup){for(this.argumentsFormGroup.get("arguments").setValidators([O.minLength(this.minArgs),O.maxLength(this.maxArgs)]);this.argumentsFormArray.length>this.maxArgs;)this.removeArgument(this.maxArgs-1);for(;this.argumentsFormArray.length{this.updateArgumentControlValidators(n),n.get("attributeScope").updateValueAndValidity({emitEvent:!1}),n.get("defaultValue").updateValueAndValidity({emitEvent:!1})}))),n}updateArgumentControlValidators(e){const t=e.get("type").value;t===Zt.ATTRIBUTE?e.get("attributeScope").enable({emitEvent:!1}):e.get("attributeScope").disable({emitEvent:!1}),t&&t!==Zt.CONSTANT?e.get("defaultValue").enable({emitEvent:!1}):e.get("defaultValue").disable({emitEvent:!1})}updateArgumentNames(){this.argumentsFormArray.controls.forEach(((e,t)=>{e.get("name").setValue(ln[t])}))}updateModel(){const e=this.argumentsFormArray.value;e.length&&this.argumentsFormGroup.valid?this.propagateChange(e):this.propagateChange(null)}}e("ArgumentsMapConfigComponent",Ln),Ln.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Ln,deps:[{token:P.Store},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Ln.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Ln,selector:"tb-arguments-map-config",inputs:{disabled:"disabled",function:"function"},providers:[{provide:B,useExisting:a((()=>Ln)),multi:!0},{provide:K,useExisting:a((()=>Ln)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n\n
\n \n \n
\n \n
\n {{argumentControl.get(\'name\').value}}.\n
\n \n tb.rulenode.argument-source-field-input\n \n \n {{ argumentTypeMap.get(argumentControl.get(\'type\').value)?.name | translate }}\n \n \n {{ argumentTypeMap.get(argument).name | translate }}\n \n {{ argumentTypeMap.get(argument).description }}\n \n \n \n \n tb.rulenode.argument-source-field-input-required\n \n \n
\n \n tb.rulenode.argument-key-field-input\n \n \n help\n \n \n tb.rulenode.argument-key-field-input-required\n \n \n \n tb.rulenode.constant-value-field-input\n \n \n tb.rulenode.constant-value-field-input-required\n \n \n \n tb.rulenode.default-value-field-input\n \n \n
\n \n tb.rulenode.attribute-scope-field-input\n \n \n {{ attributeScopeMap.get(scope) | translate }}\n \n \n \n tb.rulenode.attribute-scope-field-input-required\n \n \n
\n \n
\n
\n
\n
\n
\n
\n tb.rulenode.no-arguments-prompt\n
\n \n
\n',styles:[":host .mat-mdc-list-item.tb-argument{border:solid rgba(0,0,0,.25) 1px;border-radius:4px;padding:10px 0;margin-bottom:16px}:host .arguments-list{padding:0}\n"],dependencies:[{kind:"directive",type:H.NgClass,selector:"[ngClass]",inputs:["class","ngClass"]},{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:de.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:de.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Y.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"directive",type:X.MatSelectTrigger,selector:"mat-select-trigger"},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:Ne.MatList,selector:"mat-list",exportAs:["matList"]},{kind:"component",type:Ne.MatListItem,selector:"mat-list-item, a[mat-list-item], button[mat-list-item]",inputs:["activated"],exportAs:["matListItem"]},{kind:"directive",type:Se.CdkDropList,selector:"[cdkDropList], cdk-drop-list",inputs:["cdkDropListConnectedTo","cdkDropListData","cdkDropListOrientation","id","cdkDropListLockAxis","cdkDropListDisabled","cdkDropListSortingDisabled","cdkDropListEnterPredicate","cdkDropListSortPredicate","cdkDropListAutoScrollDisabled","cdkDropListAutoScrollStep"],outputs:["cdkDropListDropped","cdkDropListEntered","cdkDropListExited","cdkDropListSorted"],exportAs:["cdkDropList"]},{kind:"directive",type:Se.CdkDrag,selector:"[cdkDrag]",inputs:["cdkDragData","cdkDragLockAxis","cdkDragRootElement","cdkDragBoundary","cdkDragStartDelay","cdkDragFreeDragPosition","cdkDragDisabled","cdkDragConstrainPosition","cdkDragPreviewClass","cdkDragPreviewContainer"],outputs:["cdkDragStarted","cdkDragReleased","cdkDragEnded","cdkDragEntered","cdkDragExited","cdkDragDropped","cdkDragMoved"],exportAs:["cdkDrag"]},{kind:"directive",type:Se.CdkDragHandle,selector:"[cdkDragHandle]",inputs:["cdkDragHandleDisabled"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:W.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:Ie.DefaultClassDirective,selector:" [ngClass], [ngClass.xs], [ngClass.sm], [ngClass.md], [ngClass.lg], [ngClass.xl], [ngClass.lt-sm], [ngClass.lt-md], [ngClass.lt-lg], [ngClass.lt-xl], [ngClass.gt-xs], [ngClass.gt-sm], [ngClass.gt-md], [ngClass.gt-lg]",inputs:["ngClass","ngClass.xs","ngClass.sm","ngClass.md","ngClass.lg","ngClass.xl","ngClass.lt-sm","ngClass.lt-md","ngClass.lt-lg","ngClass.lt-xl","ngClass.gt-xs","ngClass.gt-sm","ngClass.gt-md","ngClass.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.FormControlDirective,selector:"[formControl]",inputs:["formControl","disabled","ngModel"],outputs:["ngModelChange"],exportAs:["ngForm"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormArrayName,selector:"[formArrayName]",inputs:["formArrayName"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Ln,decorators:[{type:n,args:[{selector:"tb-arguments-map-config",providers:[{provide:B,useExisting:a((()=>Ln)),multi:!0},{provide:K,useExisting:a((()=>Ln)),multi:!0}],template:'
\n\n
\n \n \n
\n \n
\n {{argumentControl.get(\'name\').value}}.\n
\n \n tb.rulenode.argument-source-field-input\n \n \n {{ argumentTypeMap.get(argumentControl.get(\'type\').value)?.name | translate }}\n \n \n {{ argumentTypeMap.get(argument).name | translate }}\n \n {{ argumentTypeMap.get(argument).description }}\n \n \n \n \n tb.rulenode.argument-source-field-input-required\n \n \n
\n \n tb.rulenode.argument-key-field-input\n \n \n help\n \n \n tb.rulenode.argument-key-field-input-required\n \n \n \n tb.rulenode.constant-value-field-input\n \n \n tb.rulenode.constant-value-field-input-required\n \n \n \n tb.rulenode.default-value-field-input\n \n \n
\n \n tb.rulenode.attribute-scope-field-input\n \n \n {{ attributeScopeMap.get(scope) | translate }}\n \n \n \n tb.rulenode.attribute-scope-field-input-required\n \n \n
\n \n
\n
\n
\n
\n
\n
\n tb.rulenode.no-arguments-prompt\n
\n \n
\n',styles:[":host .mat-mdc-list-item.tb-argument{border:solid rgba(0,0,0,.25) 1px;border-radius:4px;padding:10px 0;margin-bottom:16px}:host .arguments-list{padding:0}\n"]}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder}]},propDecorators:{disabled:[{type:i}],function:[{type:i}]}});class Tn extends L{get required(){return this.requiredValue}set required(e){this.requiredValue=Fe(e)}constructor(e,t,n,r){super(e),this.store=e,this.translate=t,this.injector=n,this.fb=r,this.searchText="",this.dirty=!1,this.mathOperation=[...Wt.values()],this.propagateChange=null}ngOnInit(){this.mathFunctionForm=this.fb.group({operation:[""]}),this.filteredOptions=this.mathFunctionForm.get("operation").valueChanges.pipe(qe((e=>{let t;t="string"==typeof e&&Yt[e]?Yt[e]:null,this.updateView(t)})),Ae((e=>(this.searchText=e||"",e?this._filter(e):this.mathOperation.slice()))))}_filter(e){const t=e.toLowerCase();return this.mathOperation.filter((e=>e.name.toLowerCase().includes(t)||e.value.toLowerCase().includes(t)))}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.mathFunctionForm.disable({emitEvent:!1}):this.mathFunctionForm.enable({emitEvent:!1})}mathFunctionDisplayFn(e){if(e){const t=Wt.get(e);return t.value+" | "+t.name}return""}writeValue(e){this.modelValue=e,this.mathFunctionForm.get("operation").setValue(e,{emitEvent:!1}),this.dirty=!0}updateView(e){this.modelValue!==e&&(this.modelValue=e,this.propagateChange(this.modelValue))}onFocus(){this.dirty&&(this.mathFunctionForm.get("operation").updateValueAndValidity({onlySelf:!0}),this.dirty=!1)}clear(){this.mathFunctionForm.get("operation").patchValue(""),setTimeout((()=>{this.operationInput.nativeElement.blur(),this.operationInput.nativeElement.focus()}),0)}}e("MathFunctionAutocompleteComponent",Tn),Tn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Tn,deps:[{token:P.Store},{token:Z.TranslateService},{token:t.Injector},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Tn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Tn,selector:"tb-math-function-autocomplete",inputs:{required:"required",disabled:"disabled"},providers:[{provide:B,useExisting:a((()=>Tn)),multi:!0}],viewQueries:[{propertyName:"operationInput",first:!0,predicate:["operationInput"],descendants:!0,static:!0}],usesInheritance:!0,ngImport:t,template:'\n tb.rulenode.functions-field-input\n \n \n \n \n \n \n {{ option.description }}\n \n \n \n tb.rulenode.no-option-found\n \n \n\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:de.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:Ve.MatAutocomplete,selector:"mat-autocomplete",inputs:["disableRipple","hideSingleSelectionIndicator"],exportAs:["matAutocomplete"]},{kind:"directive",type:Ve.MatAutocompleteTrigger,selector:"input[matAutocomplete], textarea[matAutocomplete]",exportAs:["matAutocompleteTrigger"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:H.AsyncPipe,name:"async"},{kind:"pipe",type:Pe.HighlightPipe,name:"highlight"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Tn,decorators:[{type:n,args:[{selector:"tb-math-function-autocomplete",providers:[{provide:B,useExisting:a((()=>Tn)),multi:!0}],template:'\n tb.rulenode.functions-field-input\n \n \n \n \n \n \n {{ option.description }}\n \n \n \n tb.rulenode.no-option-found\n \n \n\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:Z.TranslateService},{type:t.Injector},{type:R.UntypedFormBuilder}]},propDecorators:{required:[{type:i}],disabled:[{type:i}],operationInput:[{type:o,args:["operationInput",{static:!0}]}]}});class In extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.MathFunction=Yt,this.ArgumentTypeResult=Xt,this.argumentTypeResultMap=an,this.attributeScopeMap=pn,this.argumentsResult=Object.values(Xt),this.attributeScopeResult=Object.values(mn)}configForm(){return this.mathFunctionConfigForm}onConfigurationSet(e){this.mathFunctionConfigForm=this.fb.group({operation:[e?e.operation:null,[O.required]],arguments:[e?e.arguments:null,[O.required]],customFunction:[e?e.customFunction:"",[O.required]],result:this.fb.group({type:[e?e.result.type:null,[O.required]],attributeScope:[e?e.result.attributeScope:null,[O.required]],key:[e?e.result.key:"",[O.required]],resultValuePrecision:[e?e.result.resultValuePrecision:0],addToBody:[!!e&&e.result.addToBody],addToMetadata:[!!e&&e.result.addToMetadata]})})}updateValidators(e){const t=this.mathFunctionConfigForm.get("operation").value,n=this.mathFunctionConfigForm.get("result.type").value;t===Yt.CUSTOM?(this.mathFunctionConfigForm.get("customFunction").enable({emitEvent:!1}),null===this.mathFunctionConfigForm.get("customFunction").value&&this.mathFunctionConfigForm.get("customFunction").patchValue("(x - 32) / 1.8",{emitEvent:!1})):this.mathFunctionConfigForm.get("customFunction").disable({emitEvent:!1}),n===Xt.ATTRIBUTE?this.mathFunctionConfigForm.get("result.attributeScope").enable({emitEvent:!1}):this.mathFunctionConfigForm.get("result.attributeScope").disable({emitEvent:!1}),this.mathFunctionConfigForm.get("customFunction").updateValueAndValidity({emitEvent:e}),this.mathFunctionConfigForm.get("result.attributeScope").updateValueAndValidity({emitEvent:e})}validatorTriggers(){return["operation","result.type"]}}e("MathFunctionConfigComponent",In),In.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:In,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),In.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:In,selector:"tb-action-node-math-function-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n
\n tb.rulenode.argument-tile\n \n \n
\n
\n {{\'tb.rulenode.custom-expression-field-input\' | translate }} *\n \n \n \n tb.rulenode.custom-expression-field-input-required\n \n tb.rulenode.custom-expression-field-input-hint\n \n
\n
\n tb.rulenode.result-title\n
\n \n tb.rulenode.type-field-input\n \n \n {{ argumentTypeResultMap.get(mathFunctionConfigForm.get(\'result.type\').value)?.name | translate }}\n \n \n {{ argumentTypeResultMap.get(argument).name | translate }}\n \n {{ argumentTypeResultMap.get(argument).description }}\n \n \n \n \n tb.rulenode.type-field-input-required\n \n \n
\n \n tb.rulenode.attribute-scope-field-input\n \n \n {{ attributeScopeMap.get(scope) | translate }}\n \n \n \n \n tb.rulenode.key-field-input\n \n help\n \n tb.rulenode.key-field-input-required\n \n \n
\n
\n \n tb.rulenode.number-floating-point-field-input\n \n \n \n
\n
\n \n {{\'tb.rulenode.add-to-message-field-input\' | translate }}\n \n \n {{\'tb.rulenode.add-to-metadata-field-input\' | translate}}\n \n
\n
\n
\n
\n',styles:[":host ::ng-deep .fields-group{padding:0 16px 8px;margin:10px 0;border:1px groove rgba(0,0,0,.25);border-radius:4px}:host ::ng-deep .fields-group .mat-mdc-form-field .mat-mdc-form-field-infix{width:100%}:host ::ng-deep .fields-group legend{color:#000000b3;width:-moz-fit-content;width:fit-content}:host ::ng-deep .fields-group legend+*{display:block}:host ::ng-deep .fields-group legend+*.no-margin-top{margin-top:0}\n"],dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Q.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Y.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"directive",type:X.MatSelectTrigger,selector:"mat-select-trigger"},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:W.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:R.FormGroupName,selector:"[formGroupName]",inputs:["formGroupName"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Ln,selector:"tb-arguments-map-config",inputs:["disabled","function"]},{kind:"component",type:Tn,selector:"tb-math-function-autocomplete",inputs:["required","disabled"]},{kind:"pipe",type:he.SafePipe,name:"safe"},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:In,decorators:[{type:n,args:[{selector:"tb-action-node-math-function-config",template:'
\n \n \n
\n tb.rulenode.argument-tile\n \n \n
\n
\n {{\'tb.rulenode.custom-expression-field-input\' | translate }} *\n \n \n \n tb.rulenode.custom-expression-field-input-required\n \n tb.rulenode.custom-expression-field-input-hint\n \n
\n
\n tb.rulenode.result-title\n
\n \n tb.rulenode.type-field-input\n \n \n {{ argumentTypeResultMap.get(mathFunctionConfigForm.get(\'result.type\').value)?.name | translate }}\n \n \n {{ argumentTypeResultMap.get(argument).name | translate }}\n \n {{ argumentTypeResultMap.get(argument).description }}\n \n \n \n \n tb.rulenode.type-field-input-required\n \n \n
\n \n tb.rulenode.attribute-scope-field-input\n \n \n {{ attributeScopeMap.get(scope) | translate }}\n \n \n \n \n tb.rulenode.key-field-input\n \n help\n \n tb.rulenode.key-field-input-required\n \n \n
\n
\n \n tb.rulenode.number-floating-point-field-input\n \n \n \n
\n
\n \n {{\'tb.rulenode.add-to-message-field-input\' | translate }}\n \n \n {{\'tb.rulenode.add-to-metadata-field-input\' | translate}}\n \n
\n
\n
\n
\n',styles:[":host ::ng-deep .fields-group{padding:0 16px 8px;margin:10px 0;border:1px groove rgba(0,0,0,.25);border-radius:4px}:host ::ng-deep .fields-group .mat-mdc-form-field .mat-mdc-form-field-infix{width:100%}:host ::ng-deep .fields-group legend{color:#000000b3;width:-moz-fit-content;width:fit-content}:host ::ng-deep .fields-group legend+*{display:block}:host ::ng-deep .fields-group legend+*.no-margin-top{margin-top:0}\n"]}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class Nn{constructor(){this.textAlign="left"}}e("ExampleHintComponent",Nn),Nn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Nn,deps:[],target:t.ɵɵFactoryTarget.Component}),Nn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Nn,selector:"tb-example-hint",inputs:{hintText:"hintText",popupHelpLink:"popupHelpLink",textAlign:"textAlign"},ngImport:t,template:'
\n
\n
\n
\n
\n',styles:[":host .space-between{display:flex;justify-content:space-between;gap:20px}:host .space-between .see-example{display:flex;flex-shrink:0}:host .hint-text{width:100%}\n"],dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:He.HelpPopupComponent,selector:"[tb-help-popup], [tb-help-popup-content]",inputs:["tb-help-popup","tb-help-popup-content","trigger-text","trigger-style","tb-help-popup-placement","tb-help-popup-style","hintMode"]},{kind:"pipe",type:he.SafePipe,name:"safe"},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Nn,decorators:[{type:n,args:[{selector:"tb-example-hint",template:'
\n
\n
\n
\n
\n',styles:[":host .space-between{display:flex;justify-content:space-between;gap:20px}:host .space-between .see-example{display:flex;flex-shrink:0}:host .hint-text{width:100%}\n"]}]}],propDecorators:{hintText:[{type:i}],popupHelpLink:[{type:i}],textAlign:[{type:i}]}});class Sn{constructor(e,t){this.injector=e,this.fb=t,this.propagateChange=()=>{},this.destroy$=new _e,this.disabled=!1,this.uniqueKeyValuePairValidator=!1,this.required=!1,this.duplicateValuesValidator=e=>e.controls.key.value===e.controls.value.value&&e.controls.key.value&&e.controls.value.value?{uniqueKeyValuePair:!0}:null,this.oneMapRequiredValidator=e=>e.get("keyVals").value.length,this.propagateNestedErrors=e=>{if(this.kvListFormGroup&&this.kvListFormGroup.get("keyVals")&&"VALID"===this.kvListFormGroup.get("keyVals")?.status)return null;const t={};if(this.kvListFormGroup&&this.kvListFormGroup.setErrors(null),e instanceof z||e instanceof U){if(e.errors)for(const n of Object.keys(e.errors))t[n]=!0;for(const n of Object.keys(e.controls)){const r=this.propagateNestedErrors(e.controls[n]);if(r&&Object.keys(r).length)for(const e of Object.keys(r))t[e]=!0}return t}if(e.errors)for(const n of Object.keys(e.errors))t[n]=!0;return ae(t,{})?null:t}}ngOnInit(){this.ngControl=this.injector.get(_),null!=this.ngControl&&(this.ngControl.valueAccessor=this),this.kvListFormGroup=this.fb.group({keyVals:this.fb.array([])},{validators:[this.propagateNestedErrors,this.oneMapRequiredValidator]}),this.kvListFormGroup.valueChanges.pipe(Be(this.destroy$)).subscribe((()=>{this.updateModel()}))}ngOnDestroy(){this.destroy$.next(),this.destroy$.complete()}keyValsFormArray(){return this.kvListFormGroup.get("keyVals")}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.kvListFormGroup.disable({emitEvent:!1}):this.kvListFormGroup.enable({emitEvent:!1})}writeValue(e){const t=Object.keys(e).map((t=>({key:t,value:e[t]})));if(this.keyValsFormArray().length===t.length)this.keyValsFormArray().patchValue(t,{emitEvent:!1});else{const e=[];t.forEach((t=>{e.push(this.fb.group({key:[t.key,[O.required,O.pattern(/(?:.|\s)*\S(&:.|\s)*/)]],value:[t.value,[O.required,O.pattern(/(?:.|\s)*\S(&:.|\s)*/)]]},{validators:this.uniqueKeyValuePairValidator?[this.duplicateValuesValidator]:[]}))})),this.kvListFormGroup.setControl("keyVals",this.fb.array(e,this.propagateNestedErrors),{emitEvent:!1})}}removeKeyVal(e){this.keyValsFormArray().removeAt(e)}addKeyVal(){this.keyValsFormArray().push(this.fb.group({key:["",[O.required,O.pattern(/(?:.|\s)*\S(&:.|\s)*/)]],value:["",[O.required,O.pattern(/(?:.|\s)*\S(&:.|\s)*/)]]},{validators:this.uniqueKeyValuePairValidator?[this.duplicateValuesValidator]:[]}))}validate(){const e=this.kvListFormGroup.get("keyVals").value;if(!e.length&&this.required)return{kvMapRequired:!0};if(!this.kvListFormGroup.valid)return{kvFieldsRequired:!0};if(this.uniqueKeyValuePairValidator)for(const t of e)if(t.key===t.value)return{uniqueKeyValuePair:!0};return null}updateModel(){const e=this.kvListFormGroup.get("keyVals").value;if(this.required&&!e.length||!this.kvListFormGroup.valid)this.propagateChange(null);else{const t={};e.forEach((e=>{t[e.key]=e.value})),this.propagateChange(t)}}}e("KvMapConfigComponent",Sn),Sn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Sn,deps:[{token:t.Injector},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Sn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Sn,selector:"tb-kv-map-config",inputs:{disabled:"disabled",uniqueKeyValuePairValidator:"uniqueKeyValuePairValidator",labelText:"labelText",requiredText:"requiredText",keyText:"keyText",keyRequiredText:"keyRequiredText",valText:"valText",valRequiredText:"valRequiredText",hintText:"hintText",popupHelpLink:"popupHelpLink",required:"required"},providers:[{provide:B,useExisting:a((()=>Sn)),multi:!0},{provide:K,useExisting:a((()=>Sn)),multi:!0}],ngImport:t,template:'
\n
\n
{{ labelText }}
\n
\n {{ requiredText }}\n
\n
\n tb.rulenode.map-fields-required\n
\n
\n {{ \'tb.key-val.unique-key-value-pair-error\' | translate:\n {\n valText: valText,\n keyText: keyText\n } }}\n
\n
\n
\n
\n
\n
{{ keyText }}
\n
{{ valText }}
\n
\n
\n
\n
\n \n \n \n \n \n \n
\n \n
\n
\n
\n
\n
\n
\n \n
\n \n
\n',styles:[":host .field-space{flex:1 1 50%}:host .actions-header{width:40px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:de.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:de.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.FormControlDirective,selector:"[formControl]",inputs:["formControl","disabled","ngModel"],outputs:["ngModelChange"],exportAs:["ngForm"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Nn,selector:"tb-example-hint",inputs:["hintText","popupHelpLink","textAlign"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),Oe([T()],Sn.prototype,"disabled",void 0),Oe([T()],Sn.prototype,"uniqueKeyValuePairValidator",void 0),Oe([T()],Sn.prototype,"required",void 0),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Sn,decorators:[{type:n,args:[{selector:"tb-kv-map-config",providers:[{provide:B,useExisting:a((()=>Sn)),multi:!0},{provide:K,useExisting:a((()=>Sn)),multi:!0}],template:'
\n
\n
{{ labelText }}
\n
\n {{ requiredText }}\n
\n
\n tb.rulenode.map-fields-required\n
\n
\n {{ \'tb.key-val.unique-key-value-pair-error\' | translate:\n {\n valText: valText,\n keyText: keyText\n } }}\n
\n
\n
\n
\n
\n
{{ keyText }}
\n
{{ valText }}
\n
\n
\n
\n
\n \n \n \n \n \n \n
\n \n
\n
\n
\n
\n
\n
\n \n
\n \n
\n',styles:[":host .field-space{flex:1 1 50%}:host .actions-header{width:40px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:t.Injector},{type:R.FormBuilder}]},propDecorators:{disabled:[{type:i}],uniqueKeyValuePairValidator:[{type:i}],labelText:[{type:i}],requiredText:[{type:i}],keyText:[{type:i}],keyRequiredText:[{type:i}],valText:[{type:i}],valRequiredText:[{type:i}],hintText:[{type:i}],popupHelpLink:[{type:i}],required:[{type:i}]}});class qn extends L{get required(){return this.requiredValue}set required(e){this.requiredValue=Fe(e)}constructor(e,t){super(e),this.store=e,this.fb=t,this.directionTypes=Object.values(v),this.directionTypeTranslations=C,this.entityType=F,this.propagateChange=null}ngOnInit(){this.deviceRelationsQueryFormGroup=this.fb.group({fetchLastLevelOnly:[!1,[]],direction:[null,[O.required]],maxLevel:[null,[O.min(1)]],relationType:[null],deviceTypes:[null,[O.required]]}),this.deviceRelationsQueryFormGroup.valueChanges.subscribe((e=>{this.deviceRelationsQueryFormGroup.valid?this.propagateChange(e):this.propagateChange(null)}))}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.deviceRelationsQueryFormGroup.disable({emitEvent:!1}):this.deviceRelationsQueryFormGroup.enable({emitEvent:!1})}writeValue(e){this.deviceRelationsQueryFormGroup.reset(e,{emitEvent:!1})}}e("DeviceRelationsQueryConfigComponent",qn),qn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:qn,deps:[{token:P.Store},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),qn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:qn,selector:"tb-device-relations-query-config",inputs:{disabled:"disabled",required:"required"},providers:[{provide:B,useExisting:a((()=>qn)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }} tb.rulenode.relations-query-config-direction-suffix\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n {{ \'tb.rulenode.max-relation-level-error\' | translate }}\n \n \n
\n
\n \n {{ \'alias.last-level-relation\' | translate }}\n \n
\n \n \n \n help\n \n
\n',styles:[":host .last-level-slide-toggle{margin:8px 0 24px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:je.EntitySubTypeListComponent,selector:"tb-entity-subtype-list",inputs:["required","floatLabel","label","disabled","entityType","emptyInputPlaceholder","filledInputPlaceholder","appearance","subscriptSizing","additionalClasses"]},{kind:"component",type:$e.RelationTypeAutocompleteComponent,selector:"tb-relation-type-autocomplete",inputs:["showLabel","additionalClasses","appearance","required","disabled","subscriptSizing"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Y.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:te.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:ne.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:qn,decorators:[{type:n,args:[{selector:"tb-device-relations-query-config",providers:[{provide:B,useExisting:a((()=>qn)),multi:!0}],template:'
\n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }} tb.rulenode.relations-query-config-direction-suffix\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n {{ \'tb.rulenode.max-relation-level-error\' | translate }}\n \n \n
\n
\n \n {{ \'alias.last-level-relation\' | translate }}\n \n
\n \n \n \n help\n \n
\n',styles:[":host .last-level-slide-toggle{margin:8px 0 24px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder}]},propDecorators:{disabled:[{type:i}],required:[{type:i}]}});class An extends L{get required(){return this.requiredValue}set required(e){this.requiredValue=Fe(e)}constructor(e,t){super(e),this.store=e,this.fb=t,this.directionTypes=Object.values(v),this.directionTypeTranslations=C,this.propagateChange=null}ngOnInit(){this.relationsQueryFormGroup=this.fb.group({fetchLastLevelOnly:[!1,[]],direction:[null,[O.required]],maxLevel:[null,[O.min(1)]],filters:[null]}),this.relationsQueryFormGroup.valueChanges.subscribe((e=>{this.relationsQueryFormGroup.valid?this.propagateChange(e):this.propagateChange(null)}))}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.relationsQueryFormGroup.disable({emitEvent:!1}):this.relationsQueryFormGroup.enable({emitEvent:!1})}writeValue(e){this.relationsQueryFormGroup.reset(e||{},{emitEvent:!1})}}e("RelationsQueryConfigComponent",An),An.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:An,deps:[{token:P.Store},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),An.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:An,selector:"tb-relations-query-config",inputs:{disabled:"disabled",required:"required"},providers:[{provide:B,useExisting:a((()=>An)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n
tb.rulenode.relations-query
\n
\n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }} tb.rulenode.relations-query-config-direction-suffix\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n {{ \'tb.rulenode.max-relation-level-error\' | translate }}\n \n \n
\n
\n \n {{ \'alias.last-level-relation\' | translate }}\n \n
\n
\n
\n
relation.relation-filters
\n \n \n
\n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:te.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:ne.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"component",type:Qe.RelationFiltersComponent,selector:"tb-relation-filters",inputs:["disabled","allowedEntityTypes"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:An,decorators:[{type:n,args:[{selector:"tb-relations-query-config",providers:[{provide:B,useExisting:a((()=>An)),multi:!0}],template:'
\n
tb.rulenode.relations-query
\n
\n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }} tb.rulenode.relations-query-config-direction-suffix\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n {{ \'tb.rulenode.max-relation-level-error\' | translate }}\n \n \n
\n
\n \n {{ \'alias.last-level-relation\' | translate }}\n \n
\n
\n
\n
relation.relation-filters
\n \n \n
\n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder}]},propDecorators:{disabled:[{type:i}],required:[{type:i}]}});class Mn extends L{get required(){return this.requiredValue}set required(e){this.requiredValue=Fe(e)}constructor(e,t,n,r){super(e),this.store=e,this.translate=t,this.truncate=n,this.fb=r,this.placeholder="tb.rulenode.add-message-type",this.separatorKeysCodes=[ge,ye,xe],this.messageTypes=[],this.messageTypesList=[],this.searchText="",this.propagateChange=e=>{},this.messageTypeConfigForm=this.fb.group({messageType:[null]});for(const e of Object.keys(I))this.messageTypesList.push({name:N.get(I[e]),value:e})}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}ngOnInit(){this.filteredMessageTypes=this.messageTypeConfigForm.get("messageType").valueChanges.pipe(Me(""),Ae((e=>e||"")),Ee((e=>this.fetchMessageTypes(e))),Ge())}setDisabledState(e){this.disabled=e,this.disabled?this.messageTypeConfigForm.disable({emitEvent:!1}):this.messageTypeConfigForm.enable({emitEvent:!1})}writeValue(e){this.searchText="",this.messageTypes.length=0,e&&e.forEach((e=>{const t=this.messageTypesList.find((t=>t.value===e));t?this.messageTypes.push({name:t.name,value:t.value}):this.messageTypes.push({name:e,value:e})}))}displayMessageTypeFn(e){return e?e.name:void 0}textIsNotEmpty(e){return e&&e.length>0}createMessageType(e,t){e.preventDefault(),this.transformMessageType(t)}add(e){this.transformMessageType(e.value)}fetchMessageTypes(e){if(this.searchText=e,this.searchText&&this.searchText.length){const e=this.searchText.toUpperCase();return Ke(this.messageTypesList.filter((t=>t.name.toUpperCase().includes(e))))}return Ke(this.messageTypesList)}transformMessageType(e){if((e||"").trim()){let t;const n=e.trim(),r=this.messageTypesList.find((e=>e.name===n));t=r?{name:r.name,value:r.value}:{name:n,value:n},t&&this.addMessageType(t)}this.clear("")}remove(e){const t=this.messageTypes.indexOf(e);t>=0&&(this.messageTypes.splice(t,1),this.updateModel())}selected(e){this.addMessageType(e.option.value),this.clear("")}addMessageType(e){-1===this.messageTypes.findIndex((t=>t.value===e.value))&&(this.messageTypes.push(e),this.updateModel())}onFocus(){this.messageTypeConfigForm.get("messageType").updateValueAndValidity({onlySelf:!0,emitEvent:!0})}clear(e=""){this.messageTypeInput.nativeElement.value=e,this.messageTypeConfigForm.get("messageType").patchValue(null,{emitEvent:!0}),setTimeout((()=>{this.messageTypeInput.nativeElement.blur(),this.messageTypeInput.nativeElement.focus()}),0)}updateModel(){const e=this.messageTypes.map((e=>e.value));this.required?(this.chipList.errorState=!e.length,this.propagateChange(e.length>0?e:null)):(this.chipList.errorState=!1,this.propagateChange(e))}}e("MessageTypesConfigComponent",Mn),Mn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Mn,deps:[{token:P.Store},{token:Z.TranslateService},{token:S.TruncatePipe},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Mn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Mn,selector:"tb-message-types-config",inputs:{required:"required",label:"label",placeholder:"placeholder",disabled:"disabled"},providers:[{provide:B,useExisting:a((()=>Mn)),multi:!0}],viewQueries:[{propertyName:"chipList",first:!0,predicate:["chipList"],descendants:!0},{propertyName:"matAutocomplete",first:!0,predicate:["messageTypeAutocomplete"],descendants:!0},{propertyName:"messageTypeInput",first:!0,predicate:["messageTypeInput"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'\n {{ label }}\n \n \n {{messageType.name}}\n close\n \n \n \n \n \n \n \n \n
\n
\n tb.rulenode.no-message-types-found\n
\n \n \n {{ \'tb.rulenode.no-message-type-matching\' | translate :\n {messageType: truncate.transform(searchText, true, 6, '...')}\n }}\n \n \n \n tb.rulenode.create-new-message-type\n \n
\n
\n
\n help\n \n {{ \'tb.rulenode.select-message-types-required\' | translate }}\n \n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Y.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:Ve.MatAutocomplete,selector:"mat-autocomplete",inputs:["disableRipple","hideSingleSelectionIndicator"],exportAs:["matAutocomplete"]},{kind:"directive",type:Ve.MatAutocompleteTrigger,selector:"input[matAutocomplete], textarea[matAutocomplete]",exportAs:["matAutocompleteTrigger"]},{kind:"directive",type:Ve.MatAutocompleteOrigin,selector:"[matAutocompleteOrigin]",exportAs:["matAutocompleteOrigin"]},{kind:"component",type:be.MatChipGrid,selector:"mat-chip-grid",inputs:["tabIndex","disabled","placeholder","required","value","errorStateMatcher"],outputs:["change","valueChange"]},{kind:"directive",type:be.MatChipInput,selector:"input[matChipInputFor]",inputs:["matChipInputFor","matChipInputAddOnBlur","matChipInputSeparatorKeyCodes","placeholder","id","disabled"],outputs:["matChipInputTokenEnd"],exportAs:["matChipInput","matChipInputFor"]},{kind:"directive",type:be.MatChipRemove,selector:"[matChipRemove]"},{kind:"component",type:be.MatChipRow,selector:"mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]",inputs:["color","disabled","disableRipple","tabIndex","editable"],outputs:["edited"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:H.AsyncPipe,name:"async"},{kind:"pipe",type:Pe.HighlightPipe,name:"highlight"},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Mn,decorators:[{type:n,args:[{selector:"tb-message-types-config",providers:[{provide:B,useExisting:a((()=>Mn)),multi:!0}],template:'\n {{ label }}\n \n \n {{messageType.name}}\n close\n \n \n \n \n \n \n \n \n
\n
\n tb.rulenode.no-message-types-found\n
\n \n \n {{ \'tb.rulenode.no-message-type-matching\' | translate :\n {messageType: truncate.transform(searchText, true, 6, '...')}\n }}\n \n \n \n tb.rulenode.create-new-message-type\n \n
\n
\n
\n help\n \n {{ \'tb.rulenode.select-message-types-required\' | translate }}\n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:Z.TranslateService},{type:S.TruncatePipe},{type:R.FormBuilder}]},propDecorators:{required:[{type:i}],label:[{type:i}],placeholder:[{type:i}],disabled:[{type:i}],chipList:[{type:o,args:["chipList",{static:!1}]}],matAutocomplete:[{type:o,args:["messageTypeAutocomplete",{static:!1}]}],messageTypeInput:[{type:o,args:["messageTypeInput",{static:!1}]}]}});class En extends L{get required(){return this.requiredValue}set required(e){this.requiredValue=Fe(e)}constructor(e,t){super(e),this.store=e,this.fb=t,this.subscriptions=[],this.disableCertPemCredentials=!1,this.passwordFieldRequired=!0,this.allCredentialsTypes=zt,this.credentialsTypeTranslationsMap=Ut,this.propagateChange=e=>{}}ngOnInit(){this.credentialsConfigFormGroup=this.fb.group({type:[null,[O.required]],username:[null,[]],password:[null,[]],caCert:[null,[]],caCertFileName:[null,[]],privateKey:[null,[]],privateKeyFileName:[null,[]],cert:[null,[]],certFileName:[null,[]]}),this.subscriptions.push(this.credentialsConfigFormGroup.valueChanges.subscribe((()=>{this.updateView()}))),this.subscriptions.push(this.credentialsConfigFormGroup.get("type").valueChanges.subscribe((()=>{this.credentialsTypeChanged()})))}ngOnChanges(e){for(const t of Object.keys(e)){const n=e[t];if(!n.firstChange&&n.currentValue!==n.previousValue&&n.currentValue&&"disableCertPemCredentials"===t){"cert.PEM"===this.credentialsConfigFormGroup.get("type").value&&setTimeout((()=>{this.credentialsConfigFormGroup.get("type").patchValue("anonymous",{emitEvent:!0})}))}}}ngOnDestroy(){this.subscriptions.forEach((e=>e.unsubscribe()))}writeValue(e){ie(e)&&(this.credentialsConfigFormGroup.reset(e,{emitEvent:!1}),this.updateValidators())}setDisabledState(e){e?this.credentialsConfigFormGroup.disable({emitEvent:!1}):(this.credentialsConfigFormGroup.enable({emitEvent:!1}),this.updateValidators())}updateView(){let e=this.credentialsConfigFormGroup.value;const t=e.type;switch(t){case"anonymous":e={type:t};break;case"basic":e={type:t,username:e.username,password:e.password};break;case"cert.PEM":delete e.username}this.propagateChange(e)}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}validate(e){return this.credentialsConfigFormGroup.valid?null:{credentialsConfig:{valid:!1}}}credentialsTypeChanged(){this.credentialsConfigFormGroup.patchValue({username:null,password:null,caCert:null,caCertFileName:null,privateKey:null,privateKeyFileName:null,cert:null,certFileName:null}),this.updateValidators()}updateValidators(e=!1){const t=this.credentialsConfigFormGroup.get("type").value;switch(e&&this.credentialsConfigFormGroup.reset({type:t},{emitEvent:!1}),this.credentialsConfigFormGroup.setValidators([]),this.credentialsConfigFormGroup.get("username").setValidators([]),this.credentialsConfigFormGroup.get("password").setValidators([]),t){case"anonymous":break;case"basic":this.credentialsConfigFormGroup.get("username").setValidators([O.required]),this.credentialsConfigFormGroup.get("password").setValidators(this.passwordFieldRequired?[O.required]:[]);break;case"cert.PEM":this.credentialsConfigFormGroup.setValidators([this.requiredFilesSelected(O.required,[["caCert","caCertFileName"],["privateKey","privateKeyFileName","cert","certFileName"]])])}this.credentialsConfigFormGroup.get("username").updateValueAndValidity({emitEvent:e}),this.credentialsConfigFormGroup.get("password").updateValueAndValidity({emitEvent:e}),this.credentialsConfigFormGroup.updateValueAndValidity({emitEvent:e})}requiredFilesSelected(e,t=null){return n=>{t||(t=[Object.keys(n.controls)]);return n?.controls&&t.some((t=>t.every((t=>!e(n.controls[t])))))?null:{notAllRequiredFilesSelected:!0}}}}e("CredentialsConfigComponent",En),En.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:En,deps:[{token:P.Store},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),En.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:En,selector:"tb-credentials-config",inputs:{required:"required",disableCertPemCredentials:"disableCertPemCredentials",passwordFieldRequired:"passwordFieldRequired"},providers:[{provide:B,useExisting:a((()=>En)),multi:!0},{provide:K,useExisting:a((()=>En)),multi:!0}],usesInheritance:!0,usesOnChanges:!0,ngImport:t,template:'
\n \n \n tb.rulenode.credentials\n \n {{ credentialsTypeTranslationsMap.get(credentialsConfigFormGroup.get(\'type\').value) | translate }}\n \n \n \n \n tb.rulenode.credentials-type\n \n \n {{ credentialsTypeTranslationsMap.get(credentialsType) | translate }}\n \n \n \n {{ \'tb.rulenode.credentials-type-required\' | translate }}\n \n \n
\n \n \n \n \n tb.rulenode.username\n \n \n {{ \'tb.rulenode.username-required\' | translate }}\n \n \n \n tb.rulenode.password\n \n \n \n {{ \'tb.rulenode.password-required\' | translate }}\n \n \n \n \n
{{ \'tb.rulenode.credentials-pem-hint\' | translate }}
\n \n \n \n \n \n \n \n tb.rulenode.private-key-password\n \n \n \n
\n
\n
\n
\n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:H.NgSwitch,selector:"[ngSwitch]",inputs:["ngSwitch"]},{kind:"directive",type:H.NgSwitchCase,selector:"[ngSwitchCase]",inputs:["ngSwitchCase"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Y.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:Je.MatExpansionPanel,selector:"mat-expansion-panel",inputs:["disabled","expanded","hideToggle","togglePosition"],outputs:["opened","closed","expandedChange","afterExpand","afterCollapse"],exportAs:["matExpansionPanel"]},{kind:"component",type:Je.MatExpansionPanelHeader,selector:"mat-expansion-panel-header",inputs:["tabIndex","expandedHeight","collapsedHeight"]},{kind:"directive",type:Je.MatExpansionPanelTitle,selector:"mat-panel-title"},{kind:"directive",type:Je.MatExpansionPanelDescription,selector:"mat-panel-description"},{kind:"directive",type:Je.MatExpansionPanelContent,selector:"ng-template[matExpansionPanelContent]"},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:Ye.FileInputComponent,selector:"tb-file-input",inputs:["label","hint","accept","noFileText","inputId","allowedExtensions","dropLabel","maxSizeByte","contentConvertFunction","required","requiredAsError","disabled","existingFileName","readAsBinary","workFromFileObj","multipleFile"],outputs:["fileNameChanged"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:We.TogglePasswordComponent,selector:"tb-toggle-password"},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:En,decorators:[{type:n,args:[{selector:"tb-credentials-config",providers:[{provide:B,useExisting:a((()=>En)),multi:!0},{provide:K,useExisting:a((()=>En)),multi:!0}],template:'
\n \n \n tb.rulenode.credentials\n \n {{ credentialsTypeTranslationsMap.get(credentialsConfigFormGroup.get(\'type\').value) | translate }}\n \n \n \n \n tb.rulenode.credentials-type\n \n \n {{ credentialsTypeTranslationsMap.get(credentialsType) | translate }}\n \n \n \n {{ \'tb.rulenode.credentials-type-required\' | translate }}\n \n \n
\n \n \n \n \n tb.rulenode.username\n \n \n {{ \'tb.rulenode.username-required\' | translate }}\n \n \n \n tb.rulenode.password\n \n \n \n {{ \'tb.rulenode.password-required\' | translate }}\n \n \n \n \n
{{ \'tb.rulenode.credentials-pem-hint\' | translate }}
\n \n \n \n \n \n \n \n tb.rulenode.private-key-password\n \n \n \n
\n
\n
\n
\n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder}]},propDecorators:{required:[{type:i}],disableCertPemCredentials:[{type:i}],passwordFieldRequired:[{type:i}]}});const Gn=new l("WindowToken","undefined"!=typeof window&&window.document?{providedIn:"root",factory:()=>window}:{providedIn:"root",factory:()=>{}});class Dn{constructor(e,t,n){this.ngZone=e,this.document=t,this.window=n,this.copySubject=new _e,this.copyResponse$=this.copySubject.asObservable(),this.config={}}configure(e){this.config=e}copy(e){if(!this.isSupported||!e)return this.pushCopyResponse({isSuccess:!1,content:e});const t=this.copyFromContent(e);return t?this.pushCopyResponse({content:e,isSuccess:t}):this.pushCopyResponse({isSuccess:!1,content:e})}get isSupported(){return!!this.document.queryCommandSupported&&!!this.document.queryCommandSupported("copy")&&!!this.window}isTargetValid(e){if(e instanceof HTMLInputElement||e instanceof HTMLTextAreaElement){if(e.hasAttribute("disabled"))throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');return!0}throw new Error("Target should be input or textarea")}copyFromInputElement(e,t=!0){try{this.selectTarget(e);const n=this.copyText();return this.clearSelection(t?e:void 0,this.window),n&&this.isCopySuccessInIE11()}catch(e){return!1}}isCopySuccessInIE11(){const e=this.window.clipboardData;return!(e&&e.getData&&!e.getData("Text"))}copyFromContent(e,t=this.document.body){if(this.tempTextArea&&!t.contains(this.tempTextArea)&&this.destroy(this.tempTextArea.parentElement||void 0),!this.tempTextArea){this.tempTextArea=this.createTempTextArea(this.document,this.window);try{t.appendChild(this.tempTextArea)}catch(e){throw new Error("Container should be a Dom element")}}this.tempTextArea.value=e;const n=this.copyFromInputElement(this.tempTextArea,!1);return this.config.cleanUpAfterCopy&&this.destroy(this.tempTextArea.parentElement||void 0),n}destroy(e=this.document.body){this.tempTextArea&&(e.removeChild(this.tempTextArea),this.tempTextArea=void 0)}selectTarget(e){return e.select(),e.setSelectionRange(0,e.value.length),e.value.length}copyText(){return this.document.execCommand("copy")}clearSelection(e,t){e&&e.focus(),t.getSelection()?.removeAllRanges()}createTempTextArea(e,t){const n="rtl"===e.documentElement.getAttribute("dir");let r;r=e.createElement("textarea"),r.style.fontSize="12pt",r.style.border="0",r.style.padding="0",r.style.margin="0",r.style.position="absolute",r.style[n?"right":"left"]="-9999px";const o=t.pageYOffset||e.documentElement.scrollTop;return r.style.top=o+"px",r.setAttribute("readonly",""),r}pushCopyResponse(e){this.copySubject.observers.length>0&&this.ngZone.run((()=>{this.copySubject.next(e)}))}pushCopyReponse(e){this.pushCopyResponse(e)}}Dn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"13.0.1",ngImport:t,type:Dn,deps:[{token:t.NgZone},{token:j},{token:Gn,optional:!0}],target:t.ɵɵFactoryTarget.Injectable}),Dn.ɵprov=t.ɵɵngDeclareInjectable({minVersion:"12.0.0",version:"13.0.1",ngImport:t,type:Dn,providedIn:"root"}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"13.0.1",ngImport:t,type:Dn,decorators:[{type:s,args:[{providedIn:"root"}]}],ctorParameters:function(){return[{type:t.NgZone},{type:void 0,decorators:[{type:m,args:[j]}]},{type:void 0,decorators:[{type:p},{type:m,args:[Gn]}]}]}});class wn{constructor(e,t,n,o){this.ngZone=e,this.host=t,this.renderer=n,this.clipboardSrv=o,this.cbOnSuccess=new r,this.cbOnError=new r,this.onClick=e=>{this.clipboardSrv.isSupported?this.targetElm&&this.clipboardSrv.isTargetValid(this.targetElm)?this.handleResult(this.clipboardSrv.copyFromInputElement(this.targetElm),this.targetElm.value,e):this.cbContent&&this.handleResult(this.clipboardSrv.copyFromContent(this.cbContent,this.container),this.cbContent,e):this.handleResult(!1,void 0,e)}}ngOnInit(){this.ngZone.runOutsideAngular((()=>{this.clickListener=this.renderer.listen(this.host.nativeElement,"click",this.onClick)}))}ngOnDestroy(){this.clickListener&&this.clickListener(),this.clipboardSrv.destroy(this.container)}handleResult(e,t,n){let r={isSuccess:e,content:t,successMessage:this.cbSuccessMsg,event:n};e?this.cbOnSuccess.observed&&this.ngZone.run((()=>{this.cbOnSuccess.emit(r)})):this.cbOnError.observed&&this.ngZone.run((()=>{this.cbOnError.emit(r)})),this.clipboardSrv.pushCopyResponse(r)}}wn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"13.0.1",ngImport:t,type:wn,deps:[{token:t.NgZone},{token:t.ElementRef},{token:t.Renderer2},{token:Dn}],target:t.ɵɵFactoryTarget.Directive}),wn.ɵdir=t.ɵɵngDeclareDirective({minVersion:"12.0.0",version:"13.0.1",type:wn,selector:"[ngxClipboard]",inputs:{targetElm:["ngxClipboard","targetElm"],container:"container",cbContent:"cbContent",cbSuccessMsg:"cbSuccessMsg"},outputs:{cbOnSuccess:"cbOnSuccess",cbOnError:"cbOnError"},ngImport:t}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"13.0.1",ngImport:t,type:wn,decorators:[{type:d,args:[{selector:"[ngxClipboard]"}]}],ctorParameters:function(){return[{type:t.NgZone},{type:t.ElementRef},{type:t.Renderer2},{type:Dn}]},propDecorators:{targetElm:[{type:i,args:["ngxClipboard"]}],container:[{type:i}],cbContent:[{type:i}],cbSuccessMsg:[{type:i}],cbOnSuccess:[{type:u}],cbOnError:[{type:u}]}});class Vn{constructor(e,t,n){this._clipboardService=e,this._viewContainerRef=t,this._templateRef=n}ngOnInit(){this._clipboardService.isSupported&&this._viewContainerRef.createEmbeddedView(this._templateRef)}}Vn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"13.0.1",ngImport:t,type:Vn,deps:[{token:Dn},{token:t.ViewContainerRef},{token:t.TemplateRef}],target:t.ɵɵFactoryTarget.Directive}),Vn.ɵdir=t.ɵɵngDeclareDirective({minVersion:"12.0.0",version:"13.0.1",type:Vn,selector:"[ngxClipboardIfSupported]",ngImport:t}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"13.0.1",ngImport:t,type:Vn,decorators:[{type:d,args:[{selector:"[ngxClipboardIfSupported]"}]}],ctorParameters:function(){return[{type:Dn},{type:t.ViewContainerRef},{type:t.TemplateRef}]}});class Pn{}Pn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"13.0.1",ngImport:t,type:Pn,deps:[],target:t.ɵɵFactoryTarget.NgModule}),Pn.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"12.0.0",version:"13.0.1",ngImport:t,type:Pn,declarations:[wn,Vn],imports:[$],exports:[wn,Vn]}),Pn.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"13.0.1",ngImport:t,type:Pn,imports:[[$]]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"13.0.1",ngImport:t,type:Pn,decorators:[{type:c,args:[{imports:[$],declarations:[wn,Vn],exports:[wn,Vn]}]}]});class Rn{set required(e){this.requiredValue!==e&&(this.requiredValue=e,this.updateValidators())}get required(){return this.requiredValue}constructor(e){this.fb=e,this.subscriptSizing="fixed",this.messageTypes=[{name:"Post attributes",value:"POST_ATTRIBUTES_REQUEST"},{name:"Post telemetry",value:"POST_TELEMETRY_REQUEST"},{name:"Custom",value:""}],this.propagateChange=()=>{},this.destroy$=new _e,this.messageTypeFormGroup=this.fb.group({messageTypeAlias:[null,[O.required]],messageType:[{value:null,disabled:!0},[O.maxLength(255)]]}),this.messageTypeFormGroup.get("messageTypeAlias").valueChanges.pipe(Be(this.destroy$)).subscribe((e=>this.updateMessageTypeValue(e))),this.messageTypeFormGroup.valueChanges.pipe(Be(this.destroy$)).subscribe((()=>this.updateView()))}ngOnDestroy(){this.destroy$.next(),this.destroy$.complete()}registerOnTouched(e){}registerOnChange(e){this.propagateChange=e}writeValue(e){this.modelValue=e;let t=this.messageTypes.find((t=>t.value===e));t||(t=this.messageTypes.find((e=>""===e.value))),this.messageTypeFormGroup.get("messageTypeAlias").patchValue(t,{emitEvent:!1}),this.messageTypeFormGroup.get("messageType").patchValue(e,{emitEvent:!1})}validate(){return this.messageTypeFormGroup.valid?null:{messageTypeInvalid:!0}}setDisabledState(e){this.disabled=e,e?this.messageTypeFormGroup.disable({emitEvent:!1}):(this.messageTypeFormGroup.enable({emitEvent:!1}),"Custom"!==this.messageTypeFormGroup.get("messageTypeAlias").value?.name&&this.messageTypeFormGroup.get("messageType").disable({emitEvent:!1}))}updateView(){const e=this.messageTypeFormGroup.getRawValue().messageType;this.modelValue!==e&&(this.modelValue=e,this.propagateChange(this.modelValue))}updateValidators(){this.messageTypeFormGroup.get("messageType").setValidators(this.required?[O.required,O.maxLength(255)]:[O.maxLength(255)]),this.messageTypeFormGroup.get("messageType").updateValueAndValidity({emitEvent:!1})}updateMessageTypeValue(e){"Custom"!==e?.name?this.messageTypeFormGroup.get("messageType").disable({emitEvent:!1}):this.messageTypeFormGroup.get("messageType").enable({emitEvent:!1}),this.messageTypeFormGroup.get("messageType").patchValue(e.value??null)}}e("OutputMessageTypeAutocompleteComponent",Rn),Rn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Rn,deps:[{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Rn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Rn,selector:"tb-output-message-type-autocomplete",inputs:{subscriptSizing:"subscriptSizing",disabled:"disabled",required:"required"},providers:[{provide:B,useExisting:a((()=>Rn)),multi:!0},{provide:K,useExisting:a((()=>Rn)),multi:!0}],ngImport:t,template:'
\n \n {{\'tb.rulenode.output-message-type\' | translate}}\n \n \n {{msgType.name}}\n \n \n \n \n {{\'tb.rulenode.message-type-value\' | translate}}\n \n \n \n {{ \'tb.rulenode.message-type-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.message-type-value-max-length\' | translate }}\n \n \n
\n\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:de.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Y.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:wn,selector:"[ngxClipboard]",inputs:["ngxClipboard","container","cbContent","cbSuccessMsg"],outputs:["cbOnSuccess","cbOnError"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),Oe([T()],Rn.prototype,"disabled",void 0),Oe([T()],Rn.prototype,"required",null),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Rn,decorators:[{type:n,args:[{selector:"tb-output-message-type-autocomplete",providers:[{provide:B,useExisting:a((()=>Rn)),multi:!0},{provide:K,useExisting:a((()=>Rn)),multi:!0}],template:'
\n \n {{\'tb.rulenode.output-message-type\' | translate}}\n \n \n {{msgType.name}}\n \n \n \n \n {{\'tb.rulenode.message-type-value\' | translate}}\n \n \n \n {{ \'tb.rulenode.message-type-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.message-type-value-max-length\' | translate }}\n \n \n
\n\n'}]}],ctorParameters:function(){return[{type:R.FormBuilder}]},propDecorators:{subscriptSizing:[{type:i}],disabled:[{type:i}],required:[{type:i}]}});class On{constructor(e,t){this.fb=e,this.translate=t,this.translation=nn,this.propagateChange=()=>{},this.destroy$=new _e,this.selectOptions=[]}ngOnInit(){this.initOptions(),this.chipControlGroup=this.fb.group({chipControl:[null,[]]}),this.chipControlGroup.get("chipControl").valueChanges.pipe(De(this.destroy$)).subscribe((e=>{e&&this.propagateChange(e)}))}ngOnDestroy(){this.destroy$.next(),this.destroy$.complete()}initOptions(){for(const e of this.translation.keys())this.selectOptions.push({value:e,name:this.translate.instant(this.translation.get(e))})}writeValue(e){this.chipControlGroup.get("chipControl").patchValue(e,{emitEvent:!1})}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){e?this.chipControlGroup.disable({emitEvent:!1}):this.chipControlGroup.enable({emitEvent:!1})}}e("MsgMetadataChipComponent",On),On.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:On,deps:[{token:R.FormBuilder},{token:Z.TranslateService}],target:t.ɵɵFactoryTarget.Component}),On.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:On,selector:"tb-msg-metadata-chip",inputs:{labelText:"labelText",translation:"translation"},providers:[{provide:B,useExisting:a((()=>On)),multi:!0}],ngImport:t,template:'
\n
{{ labelText }}
\n \n {{ option.name }}\n \n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"component",type:be.MatChipListbox,selector:"mat-chip-listbox",inputs:["tabIndex","multiple","aria-orientation","selectable","compareWith","required","hideSingleSelectionIndicator","value"],outputs:["change"]},{kind:"component",type:be.MatChipOption,selector:"mat-basic-chip-option, [mat-basic-chip-option], mat-chip-option, [mat-chip-option]",inputs:["color","disabled","disableRipple","tabIndex","selectable","selected"],outputs:["selectionChange"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:On,decorators:[{type:n,args:[{selector:"tb-msg-metadata-chip",providers:[{provide:B,useExisting:a((()=>On)),multi:!0}],template:'
\n
{{ labelText }}
\n \n {{ option.name }}\n \n
\n'}]}],ctorParameters:function(){return[{type:R.FormBuilder},{type:Z.TranslateService}]},propDecorators:{labelText:[{type:i}],translation:[{type:i}]}});class _n extends L{constructor(e,t,n,r){super(e),this.store=e,this.translate=t,this.injector=n,this.fb=r,this.destroy$=new _e,this.sourceFieldSubcritption=[],this.propagateChange=null,this.disabled=!1,this.required=!1,this.oneMapRequiredValidator=e=>e.get("keyVals").value.length,this.propagateNestedErrors=e=>{if(this.svListFormGroup&&this.svListFormGroup.get("keyVals")&&"VALID"===this.svListFormGroup.get("keyVals")?.status)return null;const t={};if(this.svListFormGroup&&this.svListFormGroup.setErrors(null),e instanceof z||e instanceof U){if(e.errors)for(const n of Object.keys(e.errors))t[n]=!0;for(const n of Object.keys(e.controls)){const r=this.propagateNestedErrors(e.controls[n]);if(r&&Object.keys(r).length)for(const e of Object.keys(r))t[e]=!0}return t}if(e.errors)for(const n of Object.keys(e.errors))t[n]=!0;return ae(t,{})?null:t}}ngOnInit(){this.ngControl=this.injector.get(_),null!=this.ngControl&&(this.ngControl.valueAccessor=this),this.svListFormGroup=this.fb.group({keyVals:this.fb.array([])},{validators:[this.propagateNestedErrors,this.oneMapRequiredValidator]}),this.svListFormGroup.valueChanges.pipe(De(this.destroy$)).subscribe((()=>{this.updateModel()}))}ngOnDestroy(){this.destroy$.next(),this.destroy$.complete()}keyValsFormArray(){return this.svListFormGroup.get("keyVals")}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.svListFormGroup.disable({emitEvent:!1}):this.svListFormGroup.enable({emitEvent:!1})}writeValue(e){const t=Object.keys(e).map((t=>({key:t,value:e[t]})));if(this.keyValsFormArray().length===t.length)this.keyValsFormArray().patchValue(t,{emitEvent:!1});else{const e=[];t.forEach((t=>{e.push(this.fb.group({key:[t.key,[O.required]],value:[t.value,[O.required,O.pattern(/(?:.|\s)*\S(&:.|\s)*/)]]}))})),this.svListFormGroup.setControl("keyVals",this.fb.array(e,this.propagateNestedErrors),{emitEvent:!1});for(const e of this.keyValsFormArray().controls)this.keyChangeSubscribe(e)}}filterSelectOptions(e){const t=[];for(const e of this.svListFormGroup.get("keyVals").value){const n=this.selectOptions.find((t=>t.value===e.key));n&&t.push(n)}const n=[];for(const r of this.selectOptions)ie(t.find((e=>e.value===r.value)))&&r.value!==e?.get("key").value||n.push(r);return n}removeKeyVal(e){this.keyValsFormArray().removeAt(e),this.sourceFieldSubcritption[e].unsubscribe(),this.sourceFieldSubcritption.splice(e,1)}addKeyVal(){this.keyValsFormArray().push(this.fb.group({key:["",[O.required]],value:["",[O.required,O.pattern(/(?:.|\s)*\S(&:.|\s)*/)]]})),this.keyChangeSubscribe(this.keyValsFormArray().at(this.keyValsFormArray().length-1))}keyChangeSubscribe(e){this.sourceFieldSubcritption.push(e.get("key").valueChanges.pipe(De(this.destroy$)).subscribe((t=>{const n=Lt.get(t);e.get("value").patchValue(this.targetKeyPrefix+n[0].toUpperCase()+n.slice(1))})))}validate(e){return!this.svListFormGroup.get("keyVals").value.length&&this.required?{svMapRequired:!0}:this.svListFormGroup.valid?null:{svFieldsRequired:!0}}updateModel(){const e=this.svListFormGroup.get("keyVals").value;if(this.required&&!e.length||!this.svListFormGroup.valid)this.propagateChange(null);else{const t={};e.forEach((e=>{t[e.key]=e.value})),this.propagateChange(t)}}}e("SvMapConfigComponent",_n),_n.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:_n,deps:[{token:P.Store},{token:Z.TranslateService},{token:t.Injector},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),_n.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:_n,selector:"tb-sv-map-config",inputs:{selectOptions:"selectOptions",disabled:"disabled",labelText:"labelText",requiredText:"requiredText",targetKeyPrefix:"targetKeyPrefix",selectText:"selectText",selectRequiredText:"selectRequiredText",valText:"valText",valRequiredText:"valRequiredText",hintText:"hintText",popupHelpLink:"popupHelpLink",required:"required"},providers:[{provide:B,useExisting:a((()=>_n)),multi:!0},{provide:K,useExisting:a((()=>_n)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n
\n
{{ labelText }}
\n
\n tb.rulenode.map-fields-required\n
\n
\n {{ requiredText }}\n
\n
\n
\n
\n
\n
{{ selectText }}
\n
{{ valText }}
\n
\n
\n
\n
\n \n \n \n {{option.name}}\n \n \n \n \n \n \n
\n \n
\n
\n
\n
\n
\n
\n \n
\n \n
\n',styles:[":host .field-space{flex:1 1 50%}:host .actions-header{width:40px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:H.NgClass,selector:"[ngClass]",inputs:["class","ngClass"]},{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:de.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:de.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:Ie.DefaultClassDirective,selector:" [ngClass], [ngClass.xs], [ngClass.sm], [ngClass.md], [ngClass.lg], [ngClass.xl], [ngClass.lt-sm], [ngClass.lt-md], [ngClass.lt-lg], [ngClass.lt-xl], [ngClass.gt-xs], [ngClass.gt-sm], [ngClass.gt-md], [ngClass.gt-lg]",inputs:["ngClass","ngClass.xs","ngClass.sm","ngClass.md","ngClass.lg","ngClass.xl","ngClass.lt-sm","ngClass.lt-md","ngClass.lt-lg","ngClass.lt-xl","ngClass.gt-xs","ngClass.gt-sm","ngClass.gt-md","ngClass.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormControlDirective,selector:"[formControl]",inputs:["formControl","disabled","ngModel"],outputs:["ngModelChange"],exportAs:["ngForm"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Nn,selector:"tb-example-hint",inputs:["hintText","popupHelpLink","textAlign"]},{kind:"pipe",type:H.AsyncPipe,name:"async"},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),Oe([T()],_n.prototype,"disabled",void 0),Oe([T()],_n.prototype,"required",void 0),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:_n,decorators:[{type:n,args:[{selector:"tb-sv-map-config",providers:[{provide:B,useExisting:a((()=>_n)),multi:!0},{provide:K,useExisting:a((()=>_n)),multi:!0}],template:'
\n
\n
{{ labelText }}
\n
\n tb.rulenode.map-fields-required\n
\n
\n {{ requiredText }}\n
\n
\n
\n
\n
\n
{{ selectText }}
\n
{{ valText }}
\n
\n
\n
\n
\n \n \n \n {{option.name}}\n \n \n \n \n \n \n
\n \n
\n
\n
\n
\n
\n
\n \n
\n \n
\n',styles:[":host .field-space{flex:1 1 50%}:host .actions-header{width:40px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:P.Store},{type:Z.TranslateService},{type:t.Injector},{type:R.FormBuilder}]},propDecorators:{selectOptions:[{type:i}],disabled:[{type:i}],labelText:[{type:i}],requiredText:[{type:i}],targetKeyPrefix:[{type:i}],selectText:[{type:i}],selectRequiredText:[{type:i}],valText:[{type:i}],valRequiredText:[{type:i}],hintText:[{type:i}],popupHelpLink:[{type:i}],required:[{type:i}]}});class Bn extends L{get required(){return this.requiredValue}set required(e){this.requiredValue=Fe(e)}constructor(e,t){super(e),this.store=e,this.fb=t,this.directionTypes=Object.keys(v),this.directionTypeTranslations=C,this.propagateChange=null}ngOnInit(){this.relationsQueryFormGroup=this.fb.group({fetchLastLevelOnly:[!1,[]],direction:[null,[O.required]],maxLevel:[null,[]],filters:[null]}),this.relationsQueryFormGroup.valueChanges.subscribe((e=>{this.relationsQueryFormGroup.valid?this.propagateChange(e):this.propagateChange(null)}))}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}setDisabledState(e){this.disabled=e,this.disabled?this.relationsQueryFormGroup.disable({emitEvent:!1}):this.relationsQueryFormGroup.enable({emitEvent:!1})}writeValue(e){this.relationsQueryFormGroup.reset(e||{},{emitEvent:!1})}}e("RelationsQueryConfigOldComponent",Bn),Bn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Bn,deps:[{token:P.Store},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Bn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Bn,selector:"tb-relations-query-config-old",inputs:{disabled:"disabled",required:"required"},providers:[{provide:B,useExisting:a((()=>Bn)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'alias.last-level-relation\' | translate }}\n \n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n
\n
relation.relation-filters
\n \n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"component",type:Q.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Qe.RelationFiltersComponent,selector:"tb-relation-filters",inputs:["disabled","allowedEntityTypes"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Bn,decorators:[{type:n,args:[{selector:"tb-relations-query-config-old",providers:[{provide:B,useExisting:a((()=>Bn)),multi:!0}],template:'
\n \n {{ \'alias.last-level-relation\' | translate }}\n \n
\n \n relation.direction\n \n \n {{ directionTypeTranslations.get(type) | translate }}\n \n \n \n \n tb.rulenode.max-relation-level\n \n \n
\n
relation.relation-filters
\n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder}]},propDecorators:{disabled:[{type:i}],required:[{type:i}]}});class Kn{constructor(e,t){this.translate=e,this.fb=t,this.propagateChange=e=>{},this.destroy$=new _e,this.separatorKeysCodes=[ge,ye,xe],this.onTouched=()=>{}}ngOnInit(){this.attributeControlGroup=this.fb.group({clientAttributeNames:[[],[]],sharedAttributeNames:[[],[]],serverAttributeNames:[[],[]],latestTsKeyNames:[[],[]],getLatestValueWithTs:[!1,[]]},{validators:this.atLeastOne(O.required,["clientAttributeNames","sharedAttributeNames","serverAttributeNames","latestTsKeyNames"])}),this.attributeControlGroup.valueChanges.pipe(De(this.destroy$)).subscribe((e=>{this.propagateChange(this.preparePropagateValue(e))}))}preparePropagateValue(e){const t={};for(const n in e)t[n]="getLatestValueWithTs"===n||ie(e[n])?e[n]:[];return t}validate(){return this.attributeControlGroup.valid?null:{atLeastOneRequired:!0}}atLeastOne(e,t=null){return n=>{t||(t=Object.keys(n.controls));return n?.controls&&t.some((t=>!e(n.controls[t])))?null:{atLeastOne:!0}}}writeValue(e){this.attributeControlGroup.setValue(e,{emitEvent:!1})}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){this.onTouched=e}setDisabledState(e){e?this.attributeControlGroup.disable({emitEvent:!1}):this.attributeControlGroup.enable({emitEvent:!1})}ngOnDestroy(){this.destroy$.next(null),this.destroy$.complete()}}e("SelectAttributesComponent",Kn),Kn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Kn,deps:[{token:Z.TranslateService},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Kn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Kn,selector:"tb-select-attributes",inputs:{popupHelpLink:"popupHelpLink"},providers:[{provide:B,useExisting:a((()=>Kn)),multi:!0},{provide:K,useExisting:Kn,multi:!0}],ngImport:t,template:'
\n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n \n {{ \'tb.rulenode.fetch-latest-telemetry-with-timestamp\' | translate }}\n \n
\n
\n\n\n help\n\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:H.NgTemplateOutlet,selector:"[ngTemplateOutlet]",inputs:["ngTemplateOutletContext","ngTemplateOutlet","ngTemplateOutletInjector"]},{kind:"component",type:Ze.StringItemsListComponent,selector:"tb-string-items-list",inputs:["required","disabled","label","placeholder","hint","requiredText","floatLabel","appearance","editable","subscriptSizing","predefinedValues"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:Y.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:te.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:ne.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"component",type:Nn,selector:"tb-example-hint",inputs:["hintText","popupHelpLink","textAlign"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Kn,decorators:[{type:n,args:[{selector:"tb-select-attributes",providers:[{provide:B,useExisting:a((()=>Kn)),multi:!0},{provide:K,useExisting:Kn,multi:!0}],template:'
\n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n \n {{ \'tb.rulenode.fetch-latest-telemetry-with-timestamp\' | translate }}\n \n
\n
\n\n\n help\n\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:Z.TranslateService},{type:R.FormBuilder}]},propDecorators:{popupHelpLink:[{type:i}]}});class zn extends L{constructor(e,t){super(e),this.store=e,this.fb=t,this.propagateChange=null,this.destroy$=new _e,this.alarmStatus=q,this.alarmStatusTranslations=A}ngOnInit(){this.alarmStatusGroup=this.fb.group({alarmStatus:[null,[]]}),this.alarmStatusGroup.get("alarmStatus").valueChanges.pipe(De(this.destroy$)).subscribe((e=>{this.propagateChange(e)}))}setDisabledState(e){e?this.alarmStatusGroup.disable({emitEvent:!1}):this.alarmStatusGroup.enable({emitEvent:!1})}registerOnChange(e){this.propagateChange=e}registerOnTouched(e){}ngOnDestroy(){this.destroy$.next(),this.destroy$.complete()}writeValue(e){this.alarmStatusGroup.get("alarmStatus").patchValue(e,{emitEvent:!1})}}e("AlarmStatusSelectComponent",zn),zn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:zn,deps:[{token:P.Store},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),zn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:zn,selector:"tb-alarm-status-select",providers:[{provide:B,useExisting:a((()=>zn)),multi:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n
\n \n {{ alarmStatusTranslations.get(alarmStatus.ACTIVE_UNACK) | translate }}\n \n \n {{ alarmStatusTranslations.get(alarmStatus.ACTIVE_ACK) | translate }}\n \n
\n
\n \n {{ alarmStatusTranslations.get(alarmStatus.CLEARED_UNACK) | translate }}\n \n \n {{ alarmStatusTranslations.get(alarmStatus.CLEARED_ACK) | translate }}\n \n
\n
\n
\n',styles:[":host .chip-listbox{max-width:460px;width:100%}:host .chip-listbox .toggle-column{display:flex;flex:1 1 100%;gap:8px}:host .chip-listbox .option{margin:0}@media screen and (max-width: 959px){:host .chip-listbox{max-width:360px}:host .chip-listbox .toggle-column{flex-direction:column}}:host ::ng-deep .chip-listbox .mdc-evolution-chip-set__chips{gap:8px}:host ::ng-deep .chip-listbox .option button{flex-basis:100%;justify-content:start}:host ::ng-deep .chip-listbox .option .mdc-evolution-chip__graphic{flex-grow:0}\n"],dependencies:[{kind:"component",type:be.MatChipListbox,selector:"mat-chip-listbox",inputs:["tabIndex","multiple","aria-orientation","selectable","compareWith","required","hideSingleSelectionIndicator","value"],outputs:["change"]},{kind:"component",type:be.MatChipOption,selector:"mat-basic-chip-option, [mat-basic-chip-option], mat-chip-option, [mat-chip-option]",inputs:["color","disabled","disableRipple","tabIndex","selectable","selected"],outputs:["selectionChange"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:zn,decorators:[{type:n,args:[{selector:"tb-alarm-status-select",providers:[{provide:B,useExisting:a((()=>zn)),multi:!0}],template:'
\n \n
\n \n {{ alarmStatusTranslations.get(alarmStatus.ACTIVE_UNACK) | translate }}\n \n \n {{ alarmStatusTranslations.get(alarmStatus.ACTIVE_ACK) | translate }}\n \n
\n
\n \n {{ alarmStatusTranslations.get(alarmStatus.CLEARED_UNACK) | translate }}\n \n \n {{ alarmStatusTranslations.get(alarmStatus.CLEARED_ACK) | translate }}\n \n
\n
\n
\n',styles:[":host .chip-listbox{max-width:460px;width:100%}:host .chip-listbox .toggle-column{display:flex;flex:1 1 100%;gap:8px}:host .chip-listbox .option{margin:0}@media screen and (max-width: 959px){:host .chip-listbox{max-width:360px}:host .chip-listbox .toggle-column{flex-direction:column}}:host ::ng-deep .chip-listbox .mdc-evolution-chip-set__chips{gap:8px}:host ::ng-deep .chip-listbox .option button{flex-basis:100%;justify-content:start}:host ::ng-deep .chip-listbox .option .mdc-evolution-chip__graphic{flex-grow:0}\n"]}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder}]}});class Un{}e("RulenodeCoreConfigCommonModule",Un),Un.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Un,deps:[],target:t.ɵɵFactoryTarget.NgModule}),Un.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.10",ngImport:t,type:Un,declarations:[Sn,qn,An,Mn,En,Ln,Tn,Rn,hn,On,_n,Bn,Kn,zn,Nn],imports:[$,M,Re],exports:[Sn,qn,An,Mn,En,Ln,Tn,Rn,hn,On,_n,Bn,Kn,zn,Nn]}),Un.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Un,imports:[$,M,Re]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Un,decorators:[{type:c,args:[{declarations:[Sn,qn,An,Mn,En,Ln,Tn,Rn,hn,On,_n,Bn,Kn,zn,Nn],imports:[$,M,Re],exports:[Sn,qn,An,Mn,En,Ln,Tn,Rn,hn,On,_n,Bn,Kn,zn,Nn]}]}]});class Hn{}e("RuleNodeCoreConfigActionModule",Hn),Hn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Hn,deps:[],target:t.ɵɵFactoryTarget.NgModule}),Hn.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.10",ngImport:t,type:Hn,declarations:[kn,ct,Cn,bn,un,ut,ft,gt,yt,fn,xt,ht,dn,cn,xn,vn,Fn,bt,yn,gn,In],imports:[$,M,Re,Un],exports:[kn,ct,Cn,bn,un,ut,ft,gt,yt,fn,xt,ht,dn,cn,xn,vn,Fn,bt,yn,gn,In]}),Hn.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Hn,imports:[$,M,Re,Un]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Hn,decorators:[{type:c,args:[{declarations:[kn,ct,Cn,bn,un,ut,ft,gt,yt,fn,xt,ht,dn,cn,xn,vn,Fn,bt,yn,gn,In],imports:[$,M,Re,Un],exports:[kn,ct,Cn,bn,un,ut,ft,gt,yt,fn,xt,ht,dn,cn,xn,vn,Fn,bt,yn,gn,In]}]}]});class jn extends f{constructor(e,t,n){super(e),this.store=e,this.translate=t,this.fb=n,this.separatorKeysCodes=[ge,ye,xe]}configForm(){return this.calculateDeltaConfigForm}onConfigurationSet(e){this.calculateDeltaConfigForm=this.fb.group({inputValueKey:[e.inputValueKey,[O.required,O.pattern(/(?:.|\s)*\S(&:.|\s)*/)]],outputValueKey:[e.outputValueKey,[O.required,O.pattern(/(?:.|\s)*\S(&:.|\s)*/)]],useCache:[e.useCache,[]],addPeriodBetweenMsgs:[e.addPeriodBetweenMsgs,[]],periodValueKey:[e.periodValueKey,[]],round:[e.round,[O.min(0),O.max(15)]],tellFailureIfDeltaIsNegative:[e.tellFailureIfDeltaIsNegative,[]]})}prepareInputConfig(e){return{inputValueKey:ie(e?.inputValueKey)?e.inputValueKey:null,outputValueKey:ie(e?.outputValueKey)?e.outputValueKey:null,useCache:!ie(e?.useCache)||e.useCache,addPeriodBetweenMsgs:!!ie(e?.addPeriodBetweenMsgs)&&e.addPeriodBetweenMsgs,periodValueKey:ie(e?.periodValueKey)?e.periodValueKey:null,round:ie(e?.round)?e.round:null,tellFailureIfDeltaIsNegative:!ie(e?.tellFailureIfDeltaIsNegative)||e.tellFailureIfDeltaIsNegative}}prepareOutputConfig(e){return le(e)}updateValidators(e){this.calculateDeltaConfigForm.get("addPeriodBetweenMsgs").value?this.calculateDeltaConfigForm.get("periodValueKey").setValidators([O.required]):this.calculateDeltaConfigForm.get("periodValueKey").setValidators([]),this.calculateDeltaConfigForm.get("periodValueKey").updateValueAndValidity({emitEvent:e})}validatorTriggers(){return["addPeriodBetweenMsgs"]}}e("CalculateDeltaConfigComponent",jn),jn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:jn,deps:[{token:P.Store},{token:Z.TranslateService},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),jn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:jn,selector:"tb-enrichment-node-calculate-delta-config",usesInheritance:!0,ngImport:t,template:"
\n
\n \n {{ 'tb.rulenode.input-value-key' | translate }}\n \n \n {{ 'tb.rulenode.input-value-key-required' | translate }}\n \n \n \n {{ 'tb.rulenode.output-value-key' | translate }}\n \n \n {{ 'tb.rulenode.output-value-key-required' | translate }}\n \n \n
\n \n {{ 'tb.rulenode.number-of-digits-after-floating-point' | translate }}\n \n \n {{ 'tb.rulenode.number-of-digits-after-floating-point-range' | translate }}\n \n \n {{ 'tb.rulenode.number-of-digits-after-floating-point-range' | translate }}\n \n \n
\n
\n \n {{ 'tb.rulenode.failure-if-delta-negative' | translate }}\n \n
\n
\n \n {{ 'tb.rulenode.use-caching' | translate }}\n \n
\n
\n
\n \n {{ 'tb.rulenode.add-time-difference-between-readings' | translate:\n { inputValueKey: calculateDeltaConfigForm.get('inputValueKey').valid ?\n calculateDeltaConfigForm.get('inputValueKey').value : 'tb.rulenode.input-value-key' | translate } }}\n \n
\n \n {{ 'tb.rulenode.period-value-key' | translate }}\n \n \n {{ 'tb.rulenode.period-value-key-required' | translate }}\n \n \n
\n
\n
\n",dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:te.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:ne.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:jn,decorators:[{type:n,args:[{selector:"tb-enrichment-node-calculate-delta-config",template:"
\n
\n \n {{ 'tb.rulenode.input-value-key' | translate }}\n \n \n {{ 'tb.rulenode.input-value-key-required' | translate }}\n \n \n \n {{ 'tb.rulenode.output-value-key' | translate }}\n \n \n {{ 'tb.rulenode.output-value-key-required' | translate }}\n \n \n
\n \n {{ 'tb.rulenode.number-of-digits-after-floating-point' | translate }}\n \n \n {{ 'tb.rulenode.number-of-digits-after-floating-point-range' | translate }}\n \n \n {{ 'tb.rulenode.number-of-digits-after-floating-point-range' | translate }}\n \n \n
\n
\n \n {{ 'tb.rulenode.failure-if-delta-negative' | translate }}\n \n
\n
\n \n {{ 'tb.rulenode.use-caching' | translate }}\n \n
\n
\n
\n \n {{ 'tb.rulenode.add-time-difference-between-readings' | translate:\n { inputValueKey: calculateDeltaConfigForm.get('inputValueKey').valid ?\n calculateDeltaConfigForm.get('inputValueKey').value : 'tb.rulenode.input-value-key' | translate } }}\n \n
\n \n {{ 'tb.rulenode.period-value-key' | translate }}\n \n \n {{ 'tb.rulenode.period-value-key-required' | translate }}\n \n \n
\n
\n
\n"}]}],ctorParameters:function(){return[{type:P.Store},{type:Z.TranslateService},{type:R.FormBuilder}]}});class $n extends f{constructor(e,t,n){super(e),this.store=e,this.fb=t,this.translate=n,this.fetchToData=[],this.DataToFetch=Pt;for(const e of Rt.keys())e!==Pt.FIELDS&&this.fetchToData.push({value:e,name:this.translate.instant(Rt.get(e))})}configForm(){return this.customerAttributesConfigForm}prepareOutputConfig(e){const t={};for(const n of Object.keys(e.dataMapping))t[n.trim()]=e.dataMapping[n];return e.dataMapping=t,le(e)}prepareInputConfig(e){let t,n;return t=ie(e?.telemetry)?e.telemetry?Pt.LATEST_TELEMETRY:Pt.ATTRIBUTES:ie(e?.dataToFetch)?e.dataToFetch:Pt.ATTRIBUTES,n=ie(e?.attrMapping)?e.attrMapping:ie(e?.dataMapping)?e.dataMapping:null,{dataToFetch:t,dataMapping:n,fetchTo:ie(e?.fetchTo)?e.fetchTo:en.METADATA}}selectTranslation(e,t){return this.customerAttributesConfigForm.get("dataToFetch").value===Pt.LATEST_TELEMETRY?e:t}onConfigurationSet(e){this.customerAttributesConfigForm=this.fb.group({dataToFetch:[e.dataToFetch,[]],dataMapping:[e.dataMapping,[O.required]],fetchTo:[e.fetchTo]})}}e("CustomerAttributesConfigComponent",$n),$n.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:$n,deps:[{token:P.Store},{token:R.FormBuilder},{token:Z.TranslateService}],target:t.ɵɵFactoryTarget.Component}),$n.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:$n,selector:"tb-enrichment-node-customer-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n
tb.rulenode.mapping-of-customers
\n
\n
\n \n \n {{ data.name }}\n \n \n
\n
\n \n \n \n \n
\n',styles:[":host .fetch-to-data-toggle{max-width:420px;width:100%}\n"],dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:W.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"directive",type:Xe.ToggleOption,selector:"tb-toggle-option",inputs:["value"]},{kind:"component",type:et.ToggleSelectComponent,selector:"tb-toggle-select",inputs:["disabled","selectMediaBreakpoint","appearance","disablePagination"]},{kind:"component",type:Sn,selector:"tb-kv-map-config",inputs:["disabled","uniqueKeyValuePairValidator","labelText","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","popupHelpLink","required"]},{kind:"component",type:On,selector:"tb-msg-metadata-chip",inputs:["labelText","translation"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:$n,decorators:[{type:n,args:[{selector:"tb-enrichment-node-customer-attributes-config",template:'
\n
tb.rulenode.mapping-of-customers
\n
\n
\n \n \n {{ data.name }}\n \n \n
\n
\n \n \n \n \n
\n',styles:[":host .fetch-to-data-toggle{max-width:420px;width:100%}\n"]}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder},{type:Z.TranslateService}]}});class Qn extends f{constructor(e,t,n){super(e),this.store=e,this.translate=t,this.fb=n}configForm(){return this.deviceAttributesConfigForm}onConfigurationSet(e){this.deviceAttributesConfigForm=this.fb.group({deviceRelationsQuery:[e.deviceRelationsQuery,[O.required]],tellFailureIfAbsent:[e.tellFailureIfAbsent,[]],fetchTo:[e.fetchTo,[]],attributesControl:[e.attributesControl,[]]})}prepareInputConfig(e){return se(e)&&(e.attributesControl={clientAttributeNames:ie(e?.clientAttributeNames)?e.clientAttributeNames:[],latestTsKeyNames:ie(e?.latestTsKeyNames)?e.latestTsKeyNames:[],serverAttributeNames:ie(e?.serverAttributeNames)?e.serverAttributeNames:[],sharedAttributeNames:ie(e?.sharedAttributeNames)?e.sharedAttributeNames:[],getLatestValueWithTs:!!ie(e?.getLatestValueWithTs)&&e.getLatestValueWithTs}),{deviceRelationsQuery:ie(e?.deviceRelationsQuery)?e.deviceRelationsQuery:null,tellFailureIfAbsent:!ie(e?.tellFailureIfAbsent)||e.tellFailureIfAbsent,fetchTo:ie(e?.fetchTo)?e.fetchTo:en.METADATA,attributesControl:e?e.attributesControl:null}}prepareOutputConfig(e){for(const t of Object.keys(e.attributesControl))e[t]=e.attributesControl[t];return delete e.attributesControl,e}}e("DeviceAttributesConfigComponent",Qn),Qn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Qn,deps:[{token:P.Store},{token:Z.TranslateService},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Qn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Qn,selector:"tb-enrichment-node-device-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n
\n
tb.rulenode.device-relations-query
\n \n \n
\n
\n
\n
tb.rulenode.related-device-attributes
\n
\n tb.rulenode.at-least-one-field-required\n
\n
\n \n \n
\n
\n \n {{ \'tb.rulenode.tell-failure\' | translate }}\n \n
\n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"component",type:te.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:ne.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"component",type:qn,selector:"tb-device-relations-query-config",inputs:["disabled","required"]},{kind:"component",type:On,selector:"tb-msg-metadata-chip",inputs:["labelText","translation"]},{kind:"component",type:Kn,selector:"tb-select-attributes",inputs:["popupHelpLink"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Qn,decorators:[{type:n,args:[{selector:"tb-enrichment-node-device-attributes-config",template:'
\n
\n
tb.rulenode.device-relations-query
\n \n \n
\n
\n
\n
tb.rulenode.related-device-attributes
\n
\n tb.rulenode.at-least-one-field-required\n
\n
\n \n \n
\n
\n \n {{ \'tb.rulenode.tell-failure\' | translate }}\n \n
\n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:P.Store},{type:Z.TranslateService},{type:R.FormBuilder}]}});class Jn extends f{constructor(e,t,n){super(e),this.store=e,this.translate=t,this.fb=n,this.predefinedValues=[];for(const e of Object.keys(Mt))this.predefinedValues.push({value:Mt[e],name:this.translate.instant(Et.get(Mt[e]))})}ngOnInit(){super.ngOnInit()}configForm(){return this.entityDetailsConfigForm}prepareInputConfig(e){let t;return t=ie(e?.addToMetadata)?e.addToMetadata?en.METADATA:en.DATA:e?.fetchTo?e.fetchTo:en.DATA,{detailsList:ie(e?.detailsList)?e.detailsList:null,fetchTo:t}}onConfigurationSet(e){this.entityDetailsConfigForm=this.fb.group({detailsList:[e.detailsList,[O.required]],fetchTo:[e.fetchTo,[]]})}}e("EntityDetailsConfigComponent",Jn),Jn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Jn,deps:[{token:P.Store},{token:Z.TranslateService},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Jn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Jn,selector:"tb-enrichment-node-entity-details-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n help\n \n \n \n \n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"component",type:Ze.StringItemsListComponent,selector:"tb-string-items-list",inputs:["required","disabled","label","placeholder","hint","requiredText","floatLabel","appearance","editable","subscriptSizing","predefinedValues"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:Y.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:On,selector:"tb-msg-metadata-chip",inputs:["labelText","translation"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Jn,decorators:[{type:n,args:[{selector:"tb-enrichment-node-entity-details-config",template:'
\n \n \n help\n \n \n \n \n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:P.Store},{type:Z.TranslateService},{type:R.FormBuilder}]}});class Yn extends f{constructor(e,t,n){super(e),this.store=e,this.translate=t,this.fb=n,this.separatorKeysCodes=[ge,ye,xe],this.aggregationTypes=E,this.aggregations=Object.values(E),this.aggregationTypesTranslations=G,this.fetchMode=Gt,this.samplingOrders=Object.values(Vt),this.samplingOrdersTranslate=_t,this.timeUnits=Object.values(Nt),this.timeUnitsTranslationMap=St,this.deduplicationStrategiesHintTranslations=wt,this.headerOptions=[],this.timeUnitMap={[Nt.MILLISECONDS]:1,[Nt.SECONDS]:1e3,[Nt.MINUTES]:6e4,[Nt.HOURS]:36e5,[Nt.DAYS]:864e5},this.intervalValidator=()=>e=>e.get("startInterval").value*this.timeUnitMap[e.get("startIntervalTimeUnit").value]<=e.get("endInterval").value*this.timeUnitMap[e.get("endIntervalTimeUnit").value]?{intervalError:!0}:null;for(const e of Dt.keys())this.headerOptions.push({value:e,name:this.translate.instant(Dt.get(e))})}configForm(){return this.getTelemetryFromDatabaseConfigForm}onConfigurationSet(e){this.getTelemetryFromDatabaseConfigForm=this.fb.group({latestTsKeyNames:[e.latestTsKeyNames,[O.required]],aggregation:[e.aggregation,[O.required]],fetchMode:[e.fetchMode,[O.required]],orderBy:[e.orderBy,[]],limit:[e.limit,[]],useMetadataIntervalPatterns:[e.useMetadataIntervalPatterns,[]],interval:this.fb.group({startInterval:[e.interval.startInterval,[]],startIntervalTimeUnit:[e.interval.startIntervalTimeUnit,[]],endInterval:[e.interval.endInterval,[]],endIntervalTimeUnit:[e.interval.endIntervalTimeUnit,[]]}),startIntervalPattern:[e.startIntervalPattern,[]],endIntervalPattern:[e.endIntervalPattern,[]]})}validatorTriggers(){return["fetchMode","useMetadataIntervalPatterns"]}toggleChange(e){this.getTelemetryFromDatabaseConfigForm.get("fetchMode").patchValue(e,{emitEvent:!0})}prepareOutputConfig(e){return e.startInterval=e.interval.startInterval,e.startIntervalTimeUnit=e.interval.startIntervalTimeUnit,e.endInterval=e.interval.endInterval,e.endIntervalTimeUnit=e.interval.endIntervalTimeUnit,delete e.interval,le(e)}prepareInputConfig(e){return se(e)&&(e.interval={startInterval:e.startInterval,startIntervalTimeUnit:e.startIntervalTimeUnit,endInterval:e.endInterval,endIntervalTimeUnit:e.endIntervalTimeUnit}),{latestTsKeyNames:ie(e?.latestTsKeyNames)?e.latestTsKeyNames:null,aggregation:ie(e?.aggregation)?e.aggregation:E.NONE,fetchMode:ie(e?.fetchMode)?e.fetchMode:Gt.FIRST,orderBy:ie(e?.orderBy)?e.orderBy:Vt.ASC,limit:ie(e?.limit)?e.limit:1e3,useMetadataIntervalPatterns:!!ie(e?.useMetadataIntervalPatterns)&&e.useMetadataIntervalPatterns,interval:{startInterval:ie(e?.interval?.startInterval)?e.interval.startInterval:2,startIntervalTimeUnit:ie(e?.interval?.startIntervalTimeUnit)?e.interval.startIntervalTimeUnit:Nt.MINUTES,endInterval:ie(e?.interval?.endInterval)?e.interval.endInterval:1,endIntervalTimeUnit:ie(e?.interval?.endIntervalTimeUnit)?e.interval.endIntervalTimeUnit:Nt.MINUTES},startIntervalPattern:ie(e?.startIntervalPattern)?e.startIntervalPattern:null,endIntervalPattern:ie(e?.endIntervalPattern)?e.endIntervalPattern:null}}updateValidators(e){const t=this.getTelemetryFromDatabaseConfigForm.get("fetchMode").value,n=this.getTelemetryFromDatabaseConfigForm.get("useMetadataIntervalPatterns").value;t&&t===Gt.ALL?(this.getTelemetryFromDatabaseConfigForm.get("aggregation").setValidators([O.required]),this.getTelemetryFromDatabaseConfigForm.get("orderBy").setValidators([O.required]),this.getTelemetryFromDatabaseConfigForm.get("limit").setValidators([O.required,O.min(2),O.max(1e3)])):(this.getTelemetryFromDatabaseConfigForm.get("aggregation").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("orderBy").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("limit").setValidators([])),n?(this.getTelemetryFromDatabaseConfigForm.get("interval.startInterval").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("interval.startIntervalTimeUnit").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("interval.endInterval").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("interval.endIntervalTimeUnit").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("interval").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("startIntervalPattern").setValidators([O.required,O.pattern(/(?:.|\s)*\S(&:.|\s)*/)]),this.getTelemetryFromDatabaseConfigForm.get("endIntervalPattern").setValidators([O.required,O.pattern(/(?:.|\s)*\S(&:.|\s)*/)])):(this.getTelemetryFromDatabaseConfigForm.get("interval.startInterval").setValidators([O.required,O.min(1),O.max(2147483647)]),this.getTelemetryFromDatabaseConfigForm.get("interval.startIntervalTimeUnit").setValidators([O.required]),this.getTelemetryFromDatabaseConfigForm.get("interval.endInterval").setValidators([O.required,O.min(1),O.max(2147483647)]),this.getTelemetryFromDatabaseConfigForm.get("interval.endIntervalTimeUnit").setValidators([O.required]),this.getTelemetryFromDatabaseConfigForm.get("interval").setValidators([this.intervalValidator()]),this.getTelemetryFromDatabaseConfigForm.get("startIntervalPattern").setValidators([]),this.getTelemetryFromDatabaseConfigForm.get("endIntervalPattern").setValidators([])),this.getTelemetryFromDatabaseConfigForm.get("aggregation").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("orderBy").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("limit").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("interval.startInterval").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("interval.startIntervalTimeUnit").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("interval.endInterval").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("interval.endIntervalTimeUnit").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("interval").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("startIntervalPattern").updateValueAndValidity({emitEvent:e}),this.getTelemetryFromDatabaseConfigForm.get("endIntervalPattern").updateValueAndValidity({emitEvent:e})}removeKey(e,t){const n=this.getTelemetryFromDatabaseConfigForm.get(t).value,r=n.indexOf(e);r>=0&&(n.splice(r,1),this.getTelemetryFromDatabaseConfigForm.get(t).setValue(n,{emitEvent:!0}))}clearChipGrid(){this.getTelemetryFromDatabaseConfigForm.get("latestTsKeyNames").patchValue([],{emitEvent:!0})}addKey(e,t){const n=e.input;let r=e.value;if((r||"").trim()){r=r.trim();let e=this.getTelemetryFromDatabaseConfigForm.get(t).value;e&&-1!==e.indexOf(r)||(e||(e=[]),e.push(r),this.getTelemetryFromDatabaseConfigForm.get(t).setValue(e,{emitEvent:!0}))}n&&(n.value="")}defaultPaddingEnable(){return this.getTelemetryFromDatabaseConfigForm.get("fetchMode").value===Gt.ALL&&this.getTelemetryFromDatabaseConfigForm.get("aggregation").value===E.NONE}}e("GetTelemetryFromDatabaseConfigComponent",Yn),Yn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Yn,deps:[{token:P.Store},{token:Z.TranslateService},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Yn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Yn,selector:"tb-enrichment-node-get-telemetry-from-database",usesInheritance:!0,ngImport:t,template:'
\n \n
\n help\n \n
\n
\n
tb.rulenode.fetch-interval
\n
\n \n {{ \'tb.rulenode.use-metadata-dynamic-interval\' | translate }}\n \n
\n
\n
\n \n {{ \'tb.rulenode.interval-start\' | translate }}\n \n \n {{ \'tb.rulenode.start-interval-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n {{ \'tb.rulenode.time-unit\' | translate }}\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n \n {{ \'tb.rulenode.interval-end\' | translate }}\n \n \n {{ \'tb.rulenode.end-interval-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n {{ \'tb.rulenode.time-unit\' | translate }}\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n error_outline\n
\n \n {{ \'tb.rulenode.fetch-timeseries-from-to\' | translate:\n {\n startInterval: getTelemetryFromDatabaseConfigForm.get(\'interval.startInterval\').value,\n endInterval: getTelemetryFromDatabaseConfigForm.get(\'interval.endInterval\').value,\n startIntervalTimeUnit: getTelemetryFromDatabaseConfigForm.get(\'interval.startIntervalTimeUnit\').value.toLowerCase(),\n endIntervalTimeUnit: getTelemetryFromDatabaseConfigForm.get(\'interval.endIntervalTimeUnit\').value.toLowerCase()\n } }}\n \n \n {{ "tb.rulenode.fetch-timeseries-from-to-invalid" | translate }}\n \n
\n
\n
\n \n
\n \n {{ \'tb.rulenode.start-interval\' | translate }}\n \n \n {{ \'tb.rulenode.start-interval-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.end-interval\' | translate }}\n \n \n {{ \'tb.rulenode.end-interval-required\' | translate }}\n \n \n \n \n
\n
\n
\n
\n
tb.rulenode.fetch-strategy
\n
\n
\n \n \n {{ data.name }}\n \n \n
\n
\n {{ deduplicationStrategiesHintTranslations.get(getTelemetryFromDatabaseConfigForm.get(\'fetchMode\').value) | translate }}\n
\n
\n
\n \n {{ \'aggregation.function\' | translate }}\n \n \n {{ aggregationTypesTranslations.get(aggregationTypes[aggregation]) | translate }}\n \n \n \n
\n \n {{ "tb.rulenode.order-by-timestamp" | translate }} \n \n \n {{ samplingOrdersTranslate.get(order) | translate }}\n \n \n \n \n {{ "tb.rulenode.limit" | translate }}\n \n {{ "tb.rulenode.limit-hint" | translate }}\n \n {{ \'tb.rulenode.limit-required\' | translate }}\n \n \n {{ \'tb.rulenode.limit-range\' | translate }}\n \n \n {{ \'tb.rulenode.limit-range\' | translate }}\n \n \n
\n
\n
\n
\n',styles:[":host .see-example{display:inline-block}:host .description-block{display:flex;align-items:center;border-radius:6px;border:1px solid #EAEAEA}:host .description-block .description-icon{font-size:24px;height:24px;min-height:24px;width:24px;min-width:24px;line-height:24px;color:#d9d9d9;margin:4px}:host .description-block .description-text{font-size:12px;line-height:16px;letter-spacing:.25px;margin:6px}:host .description-block.error{color:var(--mdc-theme-error, #f44336)}:host .description-block.error .description-icon{color:var(--mdc-theme-error, #f44336)}:host .item-center{align-items:center}:host .item-center .fetch-mod-toggle{width:100%}:host .hint-container{width:100%}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:He.HelpPopupComponent,selector:"[tb-help-popup], [tb-help-popup-content]",inputs:["tb-help-popup","tb-help-popup-content","trigger-text","trigger-style","tb-help-popup-placement","tb-help-popup-style","hintMode"]},{kind:"component",type:Ze.StringItemsListComponent,selector:"tb-string-items-list",inputs:["required","disabled","label","placeholder","hint","requiredText","floatLabel","appearance","editable","subscriptSizing","predefinedValues"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Y.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:te.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:R.FormGroupName,selector:"[formGroupName]",inputs:["formGroupName"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"directive",type:Xe.ToggleOption,selector:"tb-toggle-option",inputs:["value"]},{kind:"component",type:et.ToggleSelectComponent,selector:"tb-toggle-select",inputs:["disabled","selectMediaBreakpoint","appearance","disablePagination"]},{kind:"component",type:ne.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"component",type:Nn,selector:"tb-example-hint",inputs:["hintText","popupHelpLink","textAlign"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Yn,decorators:[{type:n,args:[{selector:"tb-enrichment-node-get-telemetry-from-database",template:'
\n \n
\n help\n \n
\n
\n
tb.rulenode.fetch-interval
\n
\n \n {{ \'tb.rulenode.use-metadata-dynamic-interval\' | translate }}\n \n
\n
\n
\n \n {{ \'tb.rulenode.interval-start\' | translate }}\n \n \n {{ \'tb.rulenode.start-interval-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n {{ \'tb.rulenode.time-unit\' | translate }}\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n \n {{ \'tb.rulenode.interval-end\' | translate }}\n \n \n {{ \'tb.rulenode.end-interval-value-required\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n {{ \'tb.rulenode.time-value-range\' | translate }}\n \n \n \n {{ \'tb.rulenode.time-unit\' | translate }}\n \n \n {{ timeUnitsTranslationMap.get(timeUnit) | translate }}\n \n \n \n
\n
\n error_outline\n
\n \n {{ \'tb.rulenode.fetch-timeseries-from-to\' | translate:\n {\n startInterval: getTelemetryFromDatabaseConfigForm.get(\'interval.startInterval\').value,\n endInterval: getTelemetryFromDatabaseConfigForm.get(\'interval.endInterval\').value,\n startIntervalTimeUnit: getTelemetryFromDatabaseConfigForm.get(\'interval.startIntervalTimeUnit\').value.toLowerCase(),\n endIntervalTimeUnit: getTelemetryFromDatabaseConfigForm.get(\'interval.endIntervalTimeUnit\').value.toLowerCase()\n } }}\n \n \n {{ "tb.rulenode.fetch-timeseries-from-to-invalid" | translate }}\n \n
\n
\n
\n \n
\n \n {{ \'tb.rulenode.start-interval\' | translate }}\n \n \n {{ \'tb.rulenode.start-interval-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.end-interval\' | translate }}\n \n \n {{ \'tb.rulenode.end-interval-required\' | translate }}\n \n \n \n \n
\n
\n
\n
\n
tb.rulenode.fetch-strategy
\n
\n
\n \n \n {{ data.name }}\n \n \n
\n
\n {{ deduplicationStrategiesHintTranslations.get(getTelemetryFromDatabaseConfigForm.get(\'fetchMode\').value) | translate }}\n
\n
\n
\n \n {{ \'aggregation.function\' | translate }}\n \n \n {{ aggregationTypesTranslations.get(aggregationTypes[aggregation]) | translate }}\n \n \n \n
\n \n {{ "tb.rulenode.order-by-timestamp" | translate }} \n \n \n {{ samplingOrdersTranslate.get(order) | translate }}\n \n \n \n \n {{ "tb.rulenode.limit" | translate }}\n \n {{ "tb.rulenode.limit-hint" | translate }}\n \n {{ \'tb.rulenode.limit-required\' | translate }}\n \n \n {{ \'tb.rulenode.limit-range\' | translate }}\n \n \n {{ \'tb.rulenode.limit-range\' | translate }}\n \n \n
\n
\n
\n
\n',styles:[":host .see-example{display:inline-block}:host .description-block{display:flex;align-items:center;border-radius:6px;border:1px solid #EAEAEA}:host .description-block .description-icon{font-size:24px;height:24px;min-height:24px;width:24px;min-width:24px;line-height:24px;color:#d9d9d9;margin:4px}:host .description-block .description-text{font-size:12px;line-height:16px;letter-spacing:.25px;margin:6px}:host .description-block.error{color:var(--mdc-theme-error, #f44336)}:host .description-block.error .description-icon{color:var(--mdc-theme-error, #f44336)}:host .item-center{align-items:center}:host .item-center .fetch-mod-toggle{width:100%}:host .hint-container{width:100%}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:P.Store},{type:Z.TranslateService},{type:R.FormBuilder}]}});class Wn extends f{constructor(e,t,n){super(e),this.store=e,this.translate=t,this.fb=n}configForm(){return this.originatorAttributesConfigForm}onConfigurationSet(e){this.originatorAttributesConfigForm=this.fb.group({tellFailureIfAbsent:[e.tellFailureIfAbsent,[]],fetchTo:[e.fetchTo,[]],attributesControl:[e.attributesControl,[]]})}prepareInputConfig(e){return se(e)&&(e.attributesControl={clientAttributeNames:ie(e?.clientAttributeNames)?e.clientAttributeNames:[],latestTsKeyNames:ie(e?.latestTsKeyNames)?e.latestTsKeyNames:[],serverAttributeNames:ie(e?.serverAttributeNames)?e.serverAttributeNames:[],sharedAttributeNames:ie(e?.sharedAttributeNames)?e.sharedAttributeNames:[],getLatestValueWithTs:!!ie(e?.getLatestValueWithTs)&&e.getLatestValueWithTs}),{fetchTo:ie(e?.fetchTo)?e.fetchTo:en.METADATA,tellFailureIfAbsent:!!ie(e?.tellFailureIfAbsent)&&e.tellFailureIfAbsent,attributesControl:ie(e?.attributesControl)?e.attributesControl:null}}prepareOutputConfig(e){for(const t of Object.keys(e.attributesControl))e[t]=e.attributesControl[t];return delete e.attributesControl,e}}e("OriginatorAttributesConfigComponent",Wn),Wn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Wn,deps:[{token:P.Store},{token:Z.TranslateService},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Wn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Wn,selector:"tb-enrichment-node-originator-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n
\n
\n
tb.rulenode.originator-attributes
\n
\n tb.rulenode.at-least-one-field-required\n
\n
\n \n \n \n \n
\n
\n \n {{ \'tb.rulenode.tell-failure\' | translate }}\n \n
\n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"component",type:te.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:ne.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"component",type:On,selector:"tb-msg-metadata-chip",inputs:["labelText","translation"]},{kind:"component",type:Kn,selector:"tb-select-attributes",inputs:["popupHelpLink"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Wn,decorators:[{type:n,args:[{selector:"tb-enrichment-node-originator-attributes-config",template:'
\n
\n
\n
tb.rulenode.originator-attributes
\n
\n tb.rulenode.at-least-one-field-required\n
\n
\n \n \n \n \n
\n
\n \n {{ \'tb.rulenode.tell-failure\' | translate }}\n \n
\n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:P.Store},{type:Z.TranslateService},{type:R.FormBuilder}]}});class Zn extends f{constructor(e,t,n){super(e),this.store=e,this.fb=t,this.translate=n,this.originatorFields=[];for(const e of kt)this.originatorFields.push({value:e.value,name:this.translate.instant(e.name)})}configForm(){return this.originatorFieldsConfigForm}prepareOutputConfig(e){return le(e)}prepareInputConfig(e){return{dataMapping:ie(e?.dataMapping)?e.dataMapping:null,ignoreNullStrings:ie(e?.ignoreNullStrings)?e.ignoreNullStrings:null,fetchTo:ie(e?.fetchTo)?e.fetchTo:en.METADATA}}onConfigurationSet(e){this.originatorFieldsConfigForm=this.fb.group({dataMapping:[e.dataMapping,[O.required]],ignoreNullStrings:[e.ignoreNullStrings,[]],fetchTo:[e.fetchTo,[]]})}}e("OriginatorFieldsConfigComponent",Zn),Zn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Zn,deps:[{token:P.Store},{token:R.FormBuilder},{token:Z.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Zn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Zn,selector:"tb-enrichment-node-originator-fields-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n
\n \n {{ \'tb.rulenode.skip-empty-fields\' | translate }}\n \n
\n
\n',dependencies:[{kind:"component",type:te.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:ne.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"component",type:On,selector:"tb-msg-metadata-chip",inputs:["labelText","translation"]},{kind:"component",type:_n,selector:"tb-sv-map-config",inputs:["selectOptions","disabled","labelText","requiredText","targetKeyPrefix","selectText","selectRequiredText","valText","valRequiredText","hintText","popupHelpLink","required"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Zn,decorators:[{type:n,args:[{selector:"tb-enrichment-node-originator-fields-config",template:'
\n \n \n \n \n
\n \n {{ \'tb.rulenode.skip-empty-fields\' | translate }}\n \n
\n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder},{type:Z.TranslateService}]}});class Xn extends f{constructor(e,t,n){super(e),this.store=e,this.fb=t,this.translate=n,this.DataToFetch=Pt,this.msgMetadataLabelTranslations=Ot,this.originatorFields=[],this.fetchToData=[];for(const e of Object.keys(kt))this.originatorFields.push({value:kt[e].value,name:this.translate.instant(kt[e].name)});for(const e of Rt.keys())this.fetchToData.push({value:e,name:this.translate.instant(Rt.get(e))})}configForm(){return this.relatedAttributesConfigForm}prepareOutputConfig(e){e.dataToFetch===Pt.FIELDS?(e.dataMapping=e.svMap,delete e.svMap):(e.dataMapping=e.kvMap,delete e.kvMap);const t={};if(e&&e.dataMapping)for(const n of Object.keys(e.dataMapping))t[n.trim()]=e.dataMapping[n];return e.dataMapping=t,delete e.svMap,delete e.kvMap,le(e)}prepareInputConfig(e){let t,n,r={[k.name.value]:`relatedEntity${this.translate.instant(k.name.name)}`},o={serialNumber:"sn"};return t=ie(e?.telemetry)?e.telemetry?Pt.LATEST_TELEMETRY:Pt.ATTRIBUTES:ie(e?.dataToFetch)?e.dataToFetch:Pt.ATTRIBUTES,n=ie(e?.attrMapping)?e.attrMapping:ie(e?.dataMapping)?e.dataMapping:null,t===Pt.FIELDS?r=n:o=n,{relationsQuery:ie(e?.relationsQuery)?e.relationsQuery:null,dataToFetch:t,svMap:r,kvMap:o,fetchTo:ie(e?.fetchTo)?e.fetchTo:en.METADATA}}selectTranslation(e,t){return this.relatedAttributesConfigForm.get("dataToFetch").value===Pt.LATEST_TELEMETRY?e:t}onConfigurationSet(e){this.relatedAttributesConfigForm=this.fb.group({relationsQuery:[e.relationsQuery,[O.required]],dataToFetch:[e.dataToFetch,[]],kvMap:[e.kvMap,[O.required]],svMap:[e.svMap,[O.required]],fetchTo:[e.fetchTo,[]]})}validatorTriggers(){return["dataToFetch"]}updateValidators(e){this.relatedAttributesConfigForm.get("dataToFetch").value===Pt.FIELDS?(this.relatedAttributesConfigForm.get("svMap").enable({emitEvent:!1}),this.relatedAttributesConfigForm.get("kvMap").disable({emitEvent:!1}),this.relatedAttributesConfigForm.get("svMap").updateValueAndValidity()):(this.relatedAttributesConfigForm.get("svMap").disable({emitEvent:!1}),this.relatedAttributesConfigForm.get("kvMap").enable({emitEvent:!1}),this.relatedAttributesConfigForm.get("kvMap").updateValueAndValidity())}}e("RelatedAttributesConfigComponent",Xn),Xn.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Xn,deps:[{token:P.Store},{token:R.FormBuilder},{token:Z.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Xn.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Xn,selector:"tb-enrichment-node-related-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n
\n
tb.rulenode.data-to-fetch
\n \n \n {{ data.name }}\n \n \n \n \n \n \n \n \n
\n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"directive",type:Xe.ToggleOption,selector:"tb-toggle-option",inputs:["value"]},{kind:"component",type:et.ToggleSelectComponent,selector:"tb-toggle-select",inputs:["disabled","selectMediaBreakpoint","appearance","disablePagination"]},{kind:"component",type:Sn,selector:"tb-kv-map-config",inputs:["disabled","uniqueKeyValuePairValidator","labelText","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","popupHelpLink","required"]},{kind:"component",type:An,selector:"tb-relations-query-config",inputs:["disabled","required"]},{kind:"component",type:On,selector:"tb-msg-metadata-chip",inputs:["labelText","translation"]},{kind:"component",type:_n,selector:"tb-sv-map-config",inputs:["selectOptions","disabled","labelText","requiredText","targetKeyPrefix","selectText","selectRequiredText","valText","valRequiredText","hintText","popupHelpLink","required"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Xn,decorators:[{type:n,args:[{selector:"tb-enrichment-node-related-attributes-config",template:'
\n \n \n
\n
tb.rulenode.data-to-fetch
\n \n \n {{ data.name }}\n \n \n \n \n \n \n \n \n
\n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder},{type:Z.TranslateService}]}});class er extends f{constructor(e,t,n){super(e),this.store=e,this.fb=t,this.translate=n,this.fetchToData=[],this.DataToFetch=Pt;for(const e of Rt.keys())e!==Pt.FIELDS&&this.fetchToData.push({value:e,name:this.translate.instant(Rt.get(e))})}configForm(){return this.tenantAttributesConfigForm}prepareInputConfig(e){let t,n;return t=ie(e?.telemetry)?e.telemetry?Pt.LATEST_TELEMETRY:Pt.ATTRIBUTES:ie(e?.dataToFetch)?e.dataToFetch:Pt.ATTRIBUTES,n=ie(e?.attrMapping)?e.attrMapping:ie(e?.dataMapping)?e.dataMapping:null,{dataToFetch:t,dataMapping:n,fetchTo:ie(e?.fetchTo)?e.fetchTo:en.METADATA}}selectTranslation(e,t){return this.tenantAttributesConfigForm.get("dataToFetch").value===Pt.LATEST_TELEMETRY?e:t}onConfigurationSet(e){this.tenantAttributesConfigForm=this.fb.group({dataToFetch:[e.dataToFetch,[]],dataMapping:[e.dataMapping,[O.required]],fetchTo:[e.fetchTo,[]]})}}e("TenantAttributesConfigComponent",er),er.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:er,deps:[{token:P.Store},{token:R.FormBuilder},{token:Z.TranslateService}],target:t.ɵɵFactoryTarget.Component}),er.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:er,selector:"tb-enrichment-node-tenant-attributes-config",usesInheritance:!0,ngImport:t,template:'
\n
tb.rulenode.mapping-of-tenant
\n
\n
\n \n \n {{ data.name }}\n \n \n
\n
\n \n \n \n \n
\n',styles:[":host .fetch-to-data-toggle{max-width:420px;width:100%}\n"],dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:W.DefaultLayoutAlignDirective,selector:" [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]",inputs:["fxLayoutAlign","fxLayoutAlign.xs","fxLayoutAlign.sm","fxLayoutAlign.md","fxLayoutAlign.lg","fxLayoutAlign.xl","fxLayoutAlign.lt-sm","fxLayoutAlign.lt-md","fxLayoutAlign.lt-lg","fxLayoutAlign.lt-xl","fxLayoutAlign.gt-xs","fxLayoutAlign.gt-sm","fxLayoutAlign.gt-md","fxLayoutAlign.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"directive",type:Xe.ToggleOption,selector:"tb-toggle-option",inputs:["value"]},{kind:"component",type:et.ToggleSelectComponent,selector:"tb-toggle-select",inputs:["disabled","selectMediaBreakpoint","appearance","disablePagination"]},{kind:"component",type:Sn,selector:"tb-kv-map-config",inputs:["disabled","uniqueKeyValuePairValidator","labelText","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","popupHelpLink","required"]},{kind:"component",type:On,selector:"tb-msg-metadata-chip",inputs:["labelText","translation"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:er,decorators:[{type:n,args:[{selector:"tb-enrichment-node-tenant-attributes-config",template:'
\n
tb.rulenode.mapping-of-tenant
\n
\n
\n \n \n {{ data.name }}\n \n \n
\n
\n \n \n \n \n
\n',styles:[":host .fetch-to-data-toggle{max-width:420px;width:100%}\n"]}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder},{type:Z.TranslateService}]}});class tr extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.fetchDeviceCredentialsConfigForm}prepareInputConfig(e){return{fetchTo:ie(e?.fetchTo)?e.fetchTo:en.METADATA}}onConfigurationSet(e){this.fetchDeviceCredentialsConfigForm=this.fb.group({fetchTo:[e.fetchTo,[]]})}}e("FetchDeviceCredentialsConfigComponent",tr),tr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:tr,deps:[{token:P.Store},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),tr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:tr,selector:"./tb-enrichment-node-fetch-device-credentials-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n
\n',dependencies:[{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:On,selector:"tb-msg-metadata-chip",inputs:["labelText","translation"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:tr,decorators:[{type:n,args:[{selector:"./tb-enrichment-node-fetch-device-credentials-config",template:'
\n \n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder}]}});class nr{}e("RulenodeCoreConfigEnrichmentModule",nr),nr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:nr,deps:[],target:t.ɵɵFactoryTarget.NgModule}),nr.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.10",ngImport:t,type:nr,declarations:[$n,Jn,Qn,Wn,Zn,Yn,Xn,er,jn,tr],imports:[$,M,Un],exports:[$n,Jn,Qn,Wn,Zn,Yn,Xn,er,jn,tr]}),nr.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:nr,imports:[$,M,Un]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:nr,decorators:[{type:c,args:[{declarations:[$n,Jn,Qn,Wn,Zn,Yn,Xn,er,jn,tr],imports:[$,M,Un],exports:[$n,Jn,Qn,Wn,Zn,Yn,Xn,er,jn,tr]}]}]});class rr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.allAzureIotHubCredentialsTypes=Ht,this.azureIotHubCredentialsTypeTranslationsMap=jt}configForm(){return this.azureIotHubConfigForm}onConfigurationSet(e){this.azureIotHubConfigForm=this.fb.group({topicPattern:[e?e.topicPattern:null,[O.required]],host:[e?e.host:null,[O.required]],port:[e?e.port:null,[O.required,O.min(1),O.max(65535)]],connectTimeoutSec:[e?e.connectTimeoutSec:null,[O.required,O.min(1),O.max(200)]],clientId:[e?e.clientId:null,[O.required]],cleanSession:[!!e&&e.cleanSession,[]],ssl:[!!e&&e.ssl,[]],credentials:this.fb.group({type:[e&&e.credentials?e.credentials.type:null,[O.required]],sasKey:[e&&e.credentials?e.credentials.sasKey:null,[]],caCert:[e&&e.credentials?e.credentials.caCert:null,[]],caCertFileName:[e&&e.credentials?e.credentials.caCertFileName:null,[]],privateKey:[e&&e.credentials?e.credentials.privateKey:null,[]],privateKeyFileName:[e&&e.credentials?e.credentials.privateKeyFileName:null,[]],cert:[e&&e.credentials?e.credentials.cert:null,[]],certFileName:[e&&e.credentials?e.credentials.certFileName:null,[]],password:[e&&e.credentials?e.credentials.password:null,[]]})})}prepareOutputConfig(e){const t=e.credentials.type;return"sas"===t&&(e.credentials={type:t,sasKey:e.credentials.sasKey,caCert:e.credentials.caCert,caCertFileName:e.credentials.caCertFileName}),e}validatorTriggers(){return["credentials.type"]}updateValidators(e){const t=this.azureIotHubConfigForm.get("credentials"),n=t.get("type").value;switch(e&&t.reset({type:n},{emitEvent:!1}),t.get("sasKey").setValidators([]),t.get("privateKey").setValidators([]),t.get("privateKeyFileName").setValidators([]),t.get("cert").setValidators([]),t.get("certFileName").setValidators([]),n){case"sas":t.get("sasKey").setValidators([O.required]);break;case"cert.PEM":t.get("privateKey").setValidators([O.required]),t.get("privateKeyFileName").setValidators([O.required]),t.get("cert").setValidators([O.required]),t.get("certFileName").setValidators([O.required])}t.get("sasKey").updateValueAndValidity({emitEvent:e}),t.get("privateKey").updateValueAndValidity({emitEvent:e}),t.get("privateKeyFileName").updateValueAndValidity({emitEvent:e}),t.get("cert").updateValueAndValidity({emitEvent:e}),t.get("certFileName").updateValueAndValidity({emitEvent:e})}}e("AzureIotHubConfigComponent",rr),rr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:rr,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),rr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:rr,selector:"tb-external-node-azure-iot-hub-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.topic\n \n \n {{ \'tb.rulenode.topic-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.hostname\n \n \n {{ \'tb.rulenode.hostname-required\' | translate }}\n \n \n \n tb.rulenode.device-id\n \n \n {{ \'tb.rulenode.device-id-required\' | translate }}\n \n \n \n \n \n tb.rulenode.credentials\n \n {{ azureIotHubCredentialsTypeTranslationsMap.get(azureIotHubConfigForm.get(\'credentials.type\').value) | translate }}\n \n \n
\n \n tb.rulenode.credentials-type\n \n \n {{ azureIotHubCredentialsTypeTranslationsMap.get(credentialsType) | translate }}\n \n \n \n {{ \'tb.rulenode.credentials-type-required\' | translate }}\n \n \n
\n \n \n \n \n tb.rulenode.sas-key\n \n \n \n {{ \'tb.rulenode.sas-key-required\' | translate }}\n \n \n \n \n \n \n \n \n \n \n \n \n \n tb.rulenode.private-key-password\n \n \n \n \n
\n
\n
\n
\n
\n',styles:[":host .tb-mqtt-credentials-panel-group{margin:0 6px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:H.NgSwitch,selector:"[ngSwitch]",inputs:["ngSwitch"]},{kind:"directive",type:H.NgSwitchCase,selector:"[ngSwitchCase]",inputs:["ngSwitchCase"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Y.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:Je.MatAccordion,selector:"mat-accordion",inputs:["multi","hideToggle","displayMode","togglePosition"],exportAs:["matAccordion"]},{kind:"component",type:Je.MatExpansionPanel,selector:"mat-expansion-panel",inputs:["disabled","expanded","hideToggle","togglePosition"],outputs:["opened","closed","expandedChange","afterExpand","afterCollapse"],exportAs:["matExpansionPanel"]},{kind:"component",type:Je.MatExpansionPanelHeader,selector:"mat-expansion-panel-header",inputs:["tabIndex","expandedHeight","collapsedHeight"]},{kind:"directive",type:Je.MatExpansionPanelTitle,selector:"mat-panel-title"},{kind:"directive",type:Je.MatExpansionPanelDescription,selector:"mat-panel-description"},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:R.FormGroupName,selector:"[formGroupName]",inputs:["formGroupName"]},{kind:"component",type:Ye.FileInputComponent,selector:"tb-file-input",inputs:["label","hint","accept","noFileText","inputId","allowedExtensions","dropLabel","maxSizeByte","contentConvertFunction","required","requiredAsError","disabled","existingFileName","readAsBinary","workFromFileObj","multipleFile"],outputs:["fileNameChanged"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:We.TogglePasswordComponent,selector:"tb-toggle-password"},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:rr,decorators:[{type:n,args:[{selector:"tb-external-node-azure-iot-hub-config",template:'
\n \n tb.rulenode.topic\n \n \n {{ \'tb.rulenode.topic-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.hostname\n \n \n {{ \'tb.rulenode.hostname-required\' | translate }}\n \n \n \n tb.rulenode.device-id\n \n \n {{ \'tb.rulenode.device-id-required\' | translate }}\n \n \n \n \n \n tb.rulenode.credentials\n \n {{ azureIotHubCredentialsTypeTranslationsMap.get(azureIotHubConfigForm.get(\'credentials.type\').value) | translate }}\n \n \n
\n \n tb.rulenode.credentials-type\n \n \n {{ azureIotHubCredentialsTypeTranslationsMap.get(credentialsType) | translate }}\n \n \n \n {{ \'tb.rulenode.credentials-type-required\' | translate }}\n \n \n
\n \n \n \n \n tb.rulenode.sas-key\n \n \n \n {{ \'tb.rulenode.sas-key-required\' | translate }}\n \n \n \n \n \n \n \n \n \n \n \n \n \n tb.rulenode.private-key-password\n \n \n \n \n
\n
\n
\n
\n
\n',styles:[":host .tb-mqtt-credentials-panel-group{margin:0 6px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class or extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.ackValues=["all","-1","0","1"],this.ToByteStandartCharsetTypesValues=Qt,this.ToByteStandartCharsetTypeTranslationMap=Jt}configForm(){return this.kafkaConfigForm}onConfigurationSet(e){this.kafkaConfigForm=this.fb.group({topicPattern:[e?e.topicPattern:null,[O.required]],keyPattern:[e?e.keyPattern:null],bootstrapServers:[e?e.bootstrapServers:null,[O.required]],retries:[e?e.retries:null,[O.min(0)]],batchSize:[e?e.batchSize:null,[O.min(0)]],linger:[e?e.linger:null,[O.min(0)]],bufferMemory:[e?e.bufferMemory:null,[O.min(0)]],acks:[e?e.acks:null,[O.required]],keySerializer:[e?e.keySerializer:null,[O.required]],valueSerializer:[e?e.valueSerializer:null,[O.required]],otherProperties:[e?e.otherProperties:null,[]],addMetadataKeyValuesAsKafkaHeaders:[!!e&&e.addMetadataKeyValuesAsKafkaHeaders,[]],kafkaHeadersCharset:[e?e.kafkaHeadersCharset:null,[]]})}validatorTriggers(){return["addMetadataKeyValuesAsKafkaHeaders"]}updateValidators(e){this.kafkaConfigForm.get("addMetadataKeyValuesAsKafkaHeaders").value?this.kafkaConfigForm.get("kafkaHeadersCharset").setValidators([O.required]):this.kafkaConfigForm.get("kafkaHeadersCharset").setValidators([]),this.kafkaConfigForm.get("kafkaHeadersCharset").updateValueAndValidity({emitEvent:e})}}e("KafkaConfigComponent",or),or.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:or,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),or.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:or,selector:"tb-external-node-kafka-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.topic-pattern\n \n \n {{ \'tb.rulenode.topic-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.key-pattern\n \n tb.rulenode.general-pattern-hint\n \n
tb.rulenode.key-pattern-hint
\n \n tb.rulenode.bootstrap-servers\n \n \n {{ \'tb.rulenode.bootstrap-servers-required\' | translate }}\n \n \n \n tb.rulenode.retries\n \n \n {{ \'tb.rulenode.min-retries-message\' | translate }}\n \n \n \n tb.rulenode.batch-size-bytes\n \n \n {{ \'tb.rulenode.min-batch-size-bytes-message\' | translate }}\n \n \n \n tb.rulenode.linger-ms\n \n \n {{ \'tb.rulenode.min-linger-ms-message\' | translate }}\n \n \n \n tb.rulenode.buffer-memory-bytes\n \n \n {{ \'tb.rulenode.min-buffer-memory-bytes-message\' | translate }}\n \n \n \n tb.rulenode.acks\n \n \n {{ ackValue }}\n \n \n \n \n tb.rulenode.key-serializer\n \n \n {{ \'tb.rulenode.key-serializer-required\' | translate }}\n \n \n \n tb.rulenode.value-serializer\n \n \n {{ \'tb.rulenode.value-serializer-required\' | translate }}\n \n \n \n \n \n \n {{ \'tb.rulenode.add-metadata-key-values-as-kafka-headers\' | translate }}\n \n
tb.rulenode.add-metadata-key-values-as-kafka-headers-hint
\n \n tb.rulenode.charset-encoding\n \n \n {{ ToByteStandartCharsetTypeTranslationMap.get(charset) | translate }}\n \n \n \n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Q.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:hn,selector:"tb-kv-map-config-old",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:or,decorators:[{type:n,args:[{selector:"tb-external-node-kafka-config",template:'
\n \n tb.rulenode.topic-pattern\n \n \n {{ \'tb.rulenode.topic-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.key-pattern\n \n tb.rulenode.general-pattern-hint\n \n
tb.rulenode.key-pattern-hint
\n \n tb.rulenode.bootstrap-servers\n \n \n {{ \'tb.rulenode.bootstrap-servers-required\' | translate }}\n \n \n \n tb.rulenode.retries\n \n \n {{ \'tb.rulenode.min-retries-message\' | translate }}\n \n \n \n tb.rulenode.batch-size-bytes\n \n \n {{ \'tb.rulenode.min-batch-size-bytes-message\' | translate }}\n \n \n \n tb.rulenode.linger-ms\n \n \n {{ \'tb.rulenode.min-linger-ms-message\' | translate }}\n \n \n \n tb.rulenode.buffer-memory-bytes\n \n \n {{ \'tb.rulenode.min-buffer-memory-bytes-message\' | translate }}\n \n \n \n tb.rulenode.acks\n \n \n {{ ackValue }}\n \n \n \n \n tb.rulenode.key-serializer\n \n \n {{ \'tb.rulenode.key-serializer-required\' | translate }}\n \n \n \n tb.rulenode.value-serializer\n \n \n {{ \'tb.rulenode.value-serializer-required\' | translate }}\n \n \n \n \n \n \n {{ \'tb.rulenode.add-metadata-key-values-as-kafka-headers\' | translate }}\n \n
tb.rulenode.add-metadata-key-values-as-kafka-headers-hint
\n \n tb.rulenode.charset-encoding\n \n \n {{ ToByteStandartCharsetTypeTranslationMap.get(charset) | translate }}\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class ar extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.mqttConfigForm}onConfigurationSet(e){this.mqttConfigForm=this.fb.group({topicPattern:[e?e.topicPattern:null,[O.required]],host:[e?e.host:null,[O.required]],port:[e?e.port:null,[O.required,O.min(1),O.max(65535)]],connectTimeoutSec:[e?e.connectTimeoutSec:null,[O.required,O.min(1),O.max(200)]],clientId:[e?e.clientId:null,[]],appendClientIdSuffix:[{value:!!e&&e.appendClientIdSuffix,disabled:!(e&&me(e.clientId))},[]],cleanSession:[!!e&&e.cleanSession,[]],retainedMessage:[!!e&&e.retainedMessage,[]],ssl:[!!e&&e.ssl,[]],credentials:[e?e.credentials:null,[]]})}updateValidators(e){me(this.mqttConfigForm.get("clientId").value)?this.mqttConfigForm.get("appendClientIdSuffix").enable({emitEvent:!1}):this.mqttConfigForm.get("appendClientIdSuffix").disable({emitEvent:!1}),this.mqttConfigForm.get("appendClientIdSuffix").updateValueAndValidity({emitEvent:e})}validatorTriggers(){return["clientId"]}}e("MqttConfigComponent",ar),ar.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ar,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),ar.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:ar,selector:"tb-external-node-mqtt-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.topic-pattern\n \n \n {{ \'tb.rulenode.topic-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n
\n \n tb.rulenode.host\n \n \n {{ \'tb.rulenode.host-required\' | translate }}\n \n \n \n tb.rulenode.port\n \n \n {{ \'tb.rulenode.port-required\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n \n tb.rulenode.connect-timeout\n \n \n {{ \'tb.rulenode.connect-timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.connect-timeout-range\' | translate }}\n \n \n {{ \'tb.rulenode.connect-timeout-range\' | translate }}\n \n \n
\n \n tb.rulenode.client-id\n \n {{\'tb.rulenode.client-id-hint\' | translate}}\n \n \n {{ \'tb.rulenode.append-client-id-suffix\' | translate }}\n \n
{{ "tb.rulenode.client-id-suffix-hint" | translate }}
\n \n {{ \'tb.rulenode.clean-session\' | translate }}\n \n \n {{ "tb.rulenode.retained-message" | translate }}\n \n \n {{ \'tb.rulenode.enable-ssl\' | translate }}\n \n \n
\n',styles:[":host .tb-mqtt-credentials-panel-group{margin:0 6px}\n"],dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Q.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:En,selector:"tb-credentials-config",inputs:["required","disableCertPemCredentials","passwordFieldRequired"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ar,decorators:[{type:n,args:[{selector:"tb-external-node-mqtt-config",template:'
\n \n tb.rulenode.topic-pattern\n \n \n {{ \'tb.rulenode.topic-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n
\n \n tb.rulenode.host\n \n \n {{ \'tb.rulenode.host-required\' | translate }}\n \n \n \n tb.rulenode.port\n \n \n {{ \'tb.rulenode.port-required\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n \n tb.rulenode.connect-timeout\n \n \n {{ \'tb.rulenode.connect-timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.connect-timeout-range\' | translate }}\n \n \n {{ \'tb.rulenode.connect-timeout-range\' | translate }}\n \n \n
\n \n tb.rulenode.client-id\n \n {{\'tb.rulenode.client-id-hint\' | translate}}\n \n \n {{ \'tb.rulenode.append-client-id-suffix\' | translate }}\n \n
{{ "tb.rulenode.client-id-suffix-hint" | translate }}
\n \n {{ \'tb.rulenode.clean-session\' | translate }}\n \n \n {{ "tb.rulenode.retained-message" | translate }}\n \n \n {{ \'tb.rulenode.enable-ssl\' | translate }}\n \n \n
\n',styles:[":host .tb-mqtt-credentials-panel-group{margin:0 6px}\n"]}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class ir extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.notificationType=D,this.entityType=F}configForm(){return this.notificationConfigForm}onConfigurationSet(e){this.notificationConfigForm=this.fb.group({templateId:[e?e.templateId:null,[O.required]],targets:[e?e.targets:[],[O.required]]})}}e("NotificationConfigComponent",ir),ir.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ir,deps:[{token:P.Store},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),ir.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:ir,selector:"tb-external-node-notification-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n
\n',dependencies:[{kind:"component",type:tt.EntityListComponent,selector:"tb-entity-list",inputs:["entityType","subType","labelText","placeholderText","requiredText","required","disabled","subscriptSizing","hint"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:nt.TemplateAutocompleteComponent,selector:"tb-template-autocomplete",inputs:["required","allowCreate","allowEdit","disabled","notificationTypes"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ir,decorators:[{type:n,args:[{selector:"tb-external-node-notification-config",template:'
\n \n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder}]}});class lr extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.pubSubConfigForm}onConfigurationSet(e){this.pubSubConfigForm=this.fb.group({projectId:[e?e.projectId:null,[O.required]],topicName:[e?e.topicName:null,[O.required]],serviceAccountKey:[e?e.serviceAccountKey:null,[O.required]],serviceAccountKeyFileName:[e?e.serviceAccountKeyFileName:null,[O.required]],messageAttributes:[e?e.messageAttributes:null,[]]})}}e("PubSubConfigComponent",lr),lr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:lr,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),lr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:lr,selector:"tb-external-node-pub-sub-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.gcp-project-id\n \n \n {{ \'tb.rulenode.gcp-project-id-required\' | translate }}\n \n \n \n tb.rulenode.pubsub-topic-name\n \n \n {{ \'tb.rulenode.pubsub-topic-name-required\' | translate }}\n \n \n \n \n \n
\n \n \n
\n',dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:Ye.FileInputComponent,selector:"tb-file-input",inputs:["label","hint","accept","noFileText","inputId","allowedExtensions","dropLabel","maxSizeByte","contentConvertFunction","required","requiredAsError","disabled","existingFileName","readAsBinary","workFromFileObj","multipleFile"],outputs:["fileNameChanged"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:hn,selector:"tb-kv-map-config-old",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:he.SafePipe,name:"safe"},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:lr,decorators:[{type:n,args:[{selector:"tb-external-node-pub-sub-config",template:'
\n \n tb.rulenode.gcp-project-id\n \n \n {{ \'tb.rulenode.gcp-project-id-required\' | translate }}\n \n \n \n tb.rulenode.pubsub-topic-name\n \n \n {{ \'tb.rulenode.pubsub-topic-name-required\' | translate }}\n \n \n \n \n \n
\n \n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class sr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.messageProperties=[null,"BASIC","TEXT_PLAIN","MINIMAL_BASIC","MINIMAL_PERSISTENT_BASIC","PERSISTENT_BASIC","PERSISTENT_TEXT_PLAIN"]}configForm(){return this.rabbitMqConfigForm}onConfigurationSet(e){this.rabbitMqConfigForm=this.fb.group({exchangeNamePattern:[e?e.exchangeNamePattern:null,[]],routingKeyPattern:[e?e.routingKeyPattern:null,[]],messageProperties:[e?e.messageProperties:null,[]],host:[e?e.host:null,[O.required]],port:[e?e.port:null,[O.required,O.min(1),O.max(65535)]],virtualHost:[e?e.virtualHost:null,[]],username:[e?e.username:null,[]],password:[e?e.password:null,[]],automaticRecoveryEnabled:[!!e&&e.automaticRecoveryEnabled,[]],connectionTimeout:[e?e.connectionTimeout:null,[O.min(0)]],handshakeTimeout:[e?e.handshakeTimeout:null,[O.min(0)]],clientProperties:[e?e.clientProperties:null,[]]})}}e("RabbitMqConfigComponent",sr),sr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:sr,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),sr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:sr,selector:"tb-external-node-rabbit-mq-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.exchange-name-pattern\n \n \n \n tb.rulenode.routing-key-pattern\n \n \n \n tb.rulenode.message-properties\n \n \n {{ property }}\n \n \n \n
\n \n tb.rulenode.host\n \n \n {{ \'tb.rulenode.host-required\' | translate }}\n \n \n \n tb.rulenode.port\n \n \n {{ \'tb.rulenode.port-required\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n
\n \n tb.rulenode.virtual-host\n \n \n \n tb.rulenode.username\n \n \n \n tb.rulenode.password\n \n \n \n \n {{ \'tb.rulenode.automatic-recovery\' | translate }}\n \n \n tb.rulenode.connection-timeout-ms\n \n \n {{ \'tb.rulenode.min-connection-timeout-ms-message\' | translate }}\n \n \n \n tb.rulenode.handshake-timeout-ms\n \n \n {{ \'tb.rulenode.min-handshake-timeout-ms-message\' | translate }}\n \n \n \n \n \n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Q.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Y.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:We.TogglePasswordComponent,selector:"tb-toggle-password"},{kind:"component",type:hn,selector:"tb-kv-map-config-old",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:sr,decorators:[{type:n,args:[{selector:"tb-external-node-rabbit-mq-config",template:'
\n \n tb.rulenode.exchange-name-pattern\n \n \n \n tb.rulenode.routing-key-pattern\n \n \n \n tb.rulenode.message-properties\n \n \n {{ property }}\n \n \n \n
\n \n tb.rulenode.host\n \n \n {{ \'tb.rulenode.host-required\' | translate }}\n \n \n \n tb.rulenode.port\n \n \n {{ \'tb.rulenode.port-required\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n {{ \'tb.rulenode.port-range\' | translate }}\n \n \n
\n \n tb.rulenode.virtual-host\n \n \n \n tb.rulenode.username\n \n \n \n tb.rulenode.password\n \n \n \n \n {{ \'tb.rulenode.automatic-recovery\' | translate }}\n \n \n tb.rulenode.connection-timeout-ms\n \n \n {{ \'tb.rulenode.min-connection-timeout-ms-message\' | translate }}\n \n \n \n tb.rulenode.handshake-timeout-ms\n \n \n {{ \'tb.rulenode.min-handshake-timeout-ms-message\' | translate }}\n \n \n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class mr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.proxySchemes=["http","https"],this.httpRequestTypes=Object.keys($t)}configForm(){return this.restApiCallConfigForm}onConfigurationSet(e){this.restApiCallConfigForm=this.fb.group({restEndpointUrlPattern:[e?e.restEndpointUrlPattern:null,[O.required]],requestMethod:[e?e.requestMethod:null,[O.required]],useSimpleClientHttpFactory:[!!e&&e.useSimpleClientHttpFactory,[]],parseToPlainText:[!!e&&e.parseToPlainText,[]],ignoreRequestBody:[!!e&&e.ignoreRequestBody,[]],enableProxy:[!!e&&e.enableProxy,[]],useSystemProxyProperties:[!!e&&e.enableProxy,[]],proxyScheme:[e?e.proxyHost:null,[]],proxyHost:[e?e.proxyHost:null,[]],proxyPort:[e?e.proxyPort:null,[]],proxyUser:[e?e.proxyUser:null,[]],proxyPassword:[e?e.proxyPassword:null,[]],readTimeoutMs:[e?e.readTimeoutMs:null,[]],maxParallelRequestsCount:[e?e.maxParallelRequestsCount:null,[O.min(0)]],headers:[e?e.headers:null,[]],useRedisQueueForMsgPersistence:[!!e&&e.useRedisQueueForMsgPersistence,[]],trimQueue:[!!e&&e.trimQueue,[]],maxQueueSize:[e?e.maxQueueSize:null,[]],credentials:[e?e.credentials:null,[]]})}validatorTriggers(){return["useSimpleClientHttpFactory","useRedisQueueForMsgPersistence","enableProxy","useSystemProxyProperties"]}updateValidators(e){const t=this.restApiCallConfigForm.get("useSimpleClientHttpFactory").value,n=this.restApiCallConfigForm.get("useRedisQueueForMsgPersistence").value,r=this.restApiCallConfigForm.get("enableProxy").value,o=this.restApiCallConfigForm.get("useSystemProxyProperties").value;r&&!o?(this.restApiCallConfigForm.get("proxyHost").setValidators(r?[O.required]:[]),this.restApiCallConfigForm.get("proxyPort").setValidators(r?[O.required,O.min(1),O.max(65535)]:[])):(this.restApiCallConfigForm.get("proxyHost").setValidators([]),this.restApiCallConfigForm.get("proxyPort").setValidators([]),t?this.restApiCallConfigForm.get("readTimeoutMs").setValidators([]):this.restApiCallConfigForm.get("readTimeoutMs").setValidators([O.min(0)])),n?this.restApiCallConfigForm.get("maxQueueSize").setValidators([O.min(0)]):this.restApiCallConfigForm.get("maxQueueSize").setValidators([]),this.restApiCallConfigForm.get("readTimeoutMs").updateValueAndValidity({emitEvent:e}),this.restApiCallConfigForm.get("maxQueueSize").updateValueAndValidity({emitEvent:e}),this.restApiCallConfigForm.get("proxyHost").updateValueAndValidity({emitEvent:e}),this.restApiCallConfigForm.get("proxyPort").updateValueAndValidity({emitEvent:e}),this.restApiCallConfigForm.get("credentials").updateValueAndValidity({emitEvent:e})}}e("RestApiCallConfigComponent",mr),mr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:mr,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),mr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:mr,selector:"tb-external-node-rest-api-call-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.endpoint-url-pattern\n \n \n {{ \'tb.rulenode.endpoint-url-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.request-method\n \n \n {{ requestType }}\n \n \n \n \n {{ \'tb.rulenode.enable-proxy\' | translate }}\n \n \n {{ \'tb.rulenode.use-simple-client-http-factory\' | translate }}\n \n \n {{ \'tb.rulenode.parse-to-plain-text\' | translate }}\n \n
tb.rulenode.parse-to-plain-text-hint
\n \n {{ \'tb.rulenode.ignore-request-body\' | translate }}\n \n
\n \n {{ \'tb.rulenode.use-system-proxy-properties\' | translate }}\n \n
\n
\n \n tb.rulenode.proxy-scheme\n \n \n {{ proxyScheme }}\n \n \n \n \n tb.rulenode.proxy-host\n \n \n {{ \'tb.rulenode.proxy-host-required\' | translate }}\n \n \n \n tb.rulenode.proxy-port\n \n \n {{ \'tb.rulenode.proxy-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.proxy-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.proxy-user\n \n \n \n tb.rulenode.proxy-password\n \n \n
\n
\n \n tb.rulenode.read-timeout\n \n tb.rulenode.read-timeout-hint\n \n \n tb.rulenode.max-parallel-requests-count\n \n tb.rulenode.max-parallel-requests-count-hint\n \n \n
\n \n \n \n {{ \'tb.rulenode.use-redis-queue\' | translate }}\n \n
\n \n {{ \'tb.rulenode.trim-redis-queue\' | translate }}\n \n \n tb.rulenode.redis-queue-max-size\n \n \n
\n \n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Q.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:En,selector:"tb-credentials-config",inputs:["required","disableCertPemCredentials","passwordFieldRequired"]},{kind:"component",type:hn,selector:"tb-kv-map-config-old",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:he.SafePipe,name:"safe"},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:mr,decorators:[{type:n,args:[{selector:"tb-external-node-rest-api-call-config",template:'
\n \n tb.rulenode.endpoint-url-pattern\n \n \n {{ \'tb.rulenode.endpoint-url-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.request-method\n \n \n {{ requestType }}\n \n \n \n \n {{ \'tb.rulenode.enable-proxy\' | translate }}\n \n \n {{ \'tb.rulenode.use-simple-client-http-factory\' | translate }}\n \n \n {{ \'tb.rulenode.parse-to-plain-text\' | translate }}\n \n
tb.rulenode.parse-to-plain-text-hint
\n \n {{ \'tb.rulenode.ignore-request-body\' | translate }}\n \n
\n \n {{ \'tb.rulenode.use-system-proxy-properties\' | translate }}\n \n
\n
\n \n tb.rulenode.proxy-scheme\n \n \n {{ proxyScheme }}\n \n \n \n \n tb.rulenode.proxy-host\n \n \n {{ \'tb.rulenode.proxy-host-required\' | translate }}\n \n \n \n tb.rulenode.proxy-port\n \n \n {{ \'tb.rulenode.proxy-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.proxy-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.proxy-user\n \n \n \n tb.rulenode.proxy-password\n \n \n
\n
\n \n tb.rulenode.read-timeout\n \n tb.rulenode.read-timeout-hint\n \n \n tb.rulenode.max-parallel-requests-count\n \n tb.rulenode.max-parallel-requests-count-hint\n \n \n
\n \n \n \n {{ \'tb.rulenode.use-redis-queue\' | translate }}\n \n
\n \n {{ \'tb.rulenode.trim-redis-queue\' | translate }}\n \n \n tb.rulenode.redis-queue-max-size\n \n \n
\n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class pr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.smtpProtocols=["smtp","smtps"],this.tlsVersions=["TLSv1","TLSv1.1","TLSv1.2","TLSv1.3"]}configForm(){return this.sendEmailConfigForm}onConfigurationSet(e){this.sendEmailConfigForm=this.fb.group({useSystemSmtpSettings:[!!e&&e.useSystemSmtpSettings,[]],smtpProtocol:[e?e.smtpProtocol:null,[]],smtpHost:[e?e.smtpHost:null,[]],smtpPort:[e?e.smtpPort:null,[]],timeout:[e?e.timeout:null,[]],enableTls:[!!e&&e.enableTls,[]],tlsVersion:[e?e.tlsVersion:null,[]],enableProxy:[!!e&&e.enableProxy,[]],proxyHost:[e?e.proxyHost:null,[]],proxyPort:[e?e.proxyPort:null,[]],proxyUser:[e?e.proxyUser:null,[]],proxyPassword:[e?e.proxyPassword:null,[]],username:[e?e.username:null,[]],password:[e?e.password:null,[]]})}validatorTriggers(){return["useSystemSmtpSettings","enableProxy"]}updateValidators(e){const t=this.sendEmailConfigForm.get("useSystemSmtpSettings").value,n=this.sendEmailConfigForm.get("enableProxy").value;t?(this.sendEmailConfigForm.get("smtpProtocol").setValidators([]),this.sendEmailConfigForm.get("smtpHost").setValidators([]),this.sendEmailConfigForm.get("smtpPort").setValidators([]),this.sendEmailConfigForm.get("timeout").setValidators([]),this.sendEmailConfigForm.get("proxyHost").setValidators([]),this.sendEmailConfigForm.get("proxyPort").setValidators([])):(this.sendEmailConfigForm.get("smtpProtocol").setValidators([O.required]),this.sendEmailConfigForm.get("smtpHost").setValidators([O.required]),this.sendEmailConfigForm.get("smtpPort").setValidators([O.required,O.min(1),O.max(65535)]),this.sendEmailConfigForm.get("timeout").setValidators([O.required,O.min(0)]),this.sendEmailConfigForm.get("proxyHost").setValidators(n?[O.required]:[]),this.sendEmailConfigForm.get("proxyPort").setValidators(n?[O.required,O.min(1),O.max(65535)]:[])),this.sendEmailConfigForm.get("smtpProtocol").updateValueAndValidity({emitEvent:e}),this.sendEmailConfigForm.get("smtpHost").updateValueAndValidity({emitEvent:e}),this.sendEmailConfigForm.get("smtpPort").updateValueAndValidity({emitEvent:e}),this.sendEmailConfigForm.get("timeout").updateValueAndValidity({emitEvent:e}),this.sendEmailConfigForm.get("proxyHost").updateValueAndValidity({emitEvent:e}),this.sendEmailConfigForm.get("proxyPort").updateValueAndValidity({emitEvent:e})}}e("SendEmailConfigComponent",pr),pr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:pr,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),pr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:pr,selector:"tb-external-node-send-email-config",usesInheritance:!0,ngImport:t,template:'
\n \n {{ \'tb.rulenode.use-system-smtp-settings\' | translate }}\n \n
\n \n tb.rulenode.smtp-protocol\n \n \n {{ smtpProtocol.toUpperCase() }}\n \n \n \n
\n \n tb.rulenode.smtp-host\n \n \n {{ \'tb.rulenode.smtp-host-required\' | translate }}\n \n \n \n tb.rulenode.smtp-port\n \n \n {{ \'tb.rulenode.smtp-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.smtp-port-range\' | translate }}\n \n \n {{ \'tb.rulenode.smtp-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.timeout-msec\n \n \n {{ \'tb.rulenode.timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-timeout-msec-message\' | translate }}\n \n \n \n {{ \'tb.rulenode.enable-tls\' | translate }}\n \n \n tb.rulenode.tls-version\n \n \n {{ tlsVersion }}\n \n \n \n \n {{ \'tb.rulenode.enable-proxy\' | translate }}\n \n
\n
\n \n tb.rulenode.proxy-host\n \n \n {{ \'tb.rulenode.proxy-host-required\' | translate }}\n \n \n \n tb.rulenode.proxy-port\n \n \n {{ \'tb.rulenode.proxy-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.proxy-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.proxy-user\n \n \n \n tb.rulenode.proxy-password\n \n \n
\n \n tb.rulenode.username\n \n \n \n tb.rulenode.password\n \n \n \n
\n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:rt.TbCheckboxComponent,selector:"tb-checkbox",inputs:["disabled","trueValue","falseValue"],outputs:["valueChange"]},{kind:"component",type:Q.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Y.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:We.TogglePasswordComponent,selector:"tb-toggle-password"},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:pr,decorators:[{type:n,args:[{selector:"tb-external-node-send-email-config",template:'
\n \n {{ \'tb.rulenode.use-system-smtp-settings\' | translate }}\n \n
\n \n tb.rulenode.smtp-protocol\n \n \n {{ smtpProtocol.toUpperCase() }}\n \n \n \n
\n \n tb.rulenode.smtp-host\n \n \n {{ \'tb.rulenode.smtp-host-required\' | translate }}\n \n \n \n tb.rulenode.smtp-port\n \n \n {{ \'tb.rulenode.smtp-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.smtp-port-range\' | translate }}\n \n \n {{ \'tb.rulenode.smtp-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.timeout-msec\n \n \n {{ \'tb.rulenode.timeout-required\' | translate }}\n \n \n {{ \'tb.rulenode.min-timeout-msec-message\' | translate }}\n \n \n \n {{ \'tb.rulenode.enable-tls\' | translate }}\n \n \n tb.rulenode.tls-version\n \n \n {{ tlsVersion }}\n \n \n \n \n {{ \'tb.rulenode.enable-proxy\' | translate }}\n \n
\n
\n \n tb.rulenode.proxy-host\n \n \n {{ \'tb.rulenode.proxy-host-required\' | translate }}\n \n \n \n tb.rulenode.proxy-port\n \n \n {{ \'tb.rulenode.proxy-port-required\' | translate }}\n \n \n {{ \'tb.rulenode.proxy-port-range\' | translate }}\n \n \n
\n \n tb.rulenode.proxy-user\n \n \n \n tb.rulenode.proxy-password\n \n \n
\n \n tb.rulenode.username\n \n \n \n tb.rulenode.password\n \n \n \n
\n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class dr extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.sendSmsConfigForm}onConfigurationSet(e){this.sendSmsConfigForm=this.fb.group({numbersToTemplate:[e?e.numbersToTemplate:null,[O.required]],smsMessageTemplate:[e?e.smsMessageTemplate:null,[O.required]],useSystemSmsSettings:[!!e&&e.useSystemSmsSettings,[]],smsProviderConfiguration:[e?e.smsProviderConfiguration:null,[]]})}validatorTriggers(){return["useSystemSmsSettings"]}updateValidators(e){this.sendSmsConfigForm.get("useSystemSmsSettings").value?this.sendSmsConfigForm.get("smsProviderConfiguration").setValidators([]):this.sendSmsConfigForm.get("smsProviderConfiguration").setValidators([O.required]),this.sendSmsConfigForm.get("smsProviderConfiguration").updateValueAndValidity({emitEvent:e})}}e("SendSmsConfigComponent",dr),dr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:dr,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),dr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:dr,selector:"tb-external-node-send-sms-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.numbers-to-template\n \n \n {{ \'tb.rulenode.numbers-to-template-required\' | translate }}\n \n \n \n \n tb.rulenode.sms-message-template\n \n \n {{ \'tb.rulenode.sms-message-template-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n {{ \'tb.rulenode.use-system-sms-settings\' | translate }}\n \n \n \n
\n',dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Q.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:ot.SmsProviderConfigurationComponent,selector:"tb-sms-provider-configuration",inputs:["required","disabled"]},{kind:"pipe",type:he.SafePipe,name:"safe"},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:dr,decorators:[{type:n,args:[{selector:"tb-external-node-send-sms-config",template:'
\n \n tb.rulenode.numbers-to-template\n \n \n {{ \'tb.rulenode.numbers-to-template-required\' | translate }}\n \n \n \n \n tb.rulenode.sms-message-template\n \n \n {{ \'tb.rulenode.sms-message-template-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n {{ \'tb.rulenode.use-system-sms-settings\' | translate }}\n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class ur extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.slackChanelTypes=Object.keys(w),this.slackChanelTypesTranslateMap=V}configForm(){return this.slackConfigForm}onConfigurationSet(e){this.slackConfigForm=this.fb.group({botToken:[e?e.botToken:null],useSystemSettings:[!!e&&e.useSystemSettings],messageTemplate:[e?e.messageTemplate:null,[O.required]],conversationType:[e?e.conversationType:null,[O.required]],conversation:[e?e.conversation:null,[O.required]]})}validatorTriggers(){return["useSystemSettings"]}updateValidators(e){this.slackConfigForm.get("useSystemSettings").value?this.slackConfigForm.get("botToken").clearValidators():this.slackConfigForm.get("botToken").setValidators([O.required]),this.slackConfigForm.get("botToken").updateValueAndValidity({emitEvent:e})}}e("SlackConfigComponent",ur),ur.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ur,deps:[{token:P.Store},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),ur.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:ur,selector:"tb-external-node-slack-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.message-template\n \n \n {{ \'tb.rulenode.message-template-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n {{ \'tb.rulenode.use-system-slack-settings\' | translate }}\n \n \n tb.rulenode.slack-api-token\n \n \n {{ \'tb.rulenode.slack-api-token-required\' | translate }}\n \n \n \n \n \n {{ slackChanelTypesTranslateMap.get(slackChanelType) | translate }}\n \n \n \n \n
\n',styles:[":host .tb-title{display:block;padding-bottom:6px}:host ::ng-deep .mat-mdc-radio-group{display:flex;flex-direction:row;margin-bottom:22px;gap:12px}:host ::ng-deep .mat-mdc-radio-group .mat-mdc-radio-button{flex:1 1 100%;padding:4px;border:1px solid rgba(0,0,0,.12);border-radius:6px}@media screen and (max-width: 599px){:host ::ng-deep .mat-mdc-radio-group{flex-direction:column}}\n"],dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:Q.MatCheckbox,selector:"mat-checkbox",inputs:["disableRipple","color","tabIndex"],exportAs:["matCheckbox"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:at.MatRadioGroup,selector:"mat-radio-group",exportAs:["matRadioGroup"]},{kind:"component",type:at.MatRadioButton,selector:"mat-radio-button",inputs:["disableRipple","tabIndex"],exportAs:["matRadioButton"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:it.SlackConversationAutocompleteComponent,selector:"tb-slack-conversation-autocomplete",inputs:["labelText","requiredText","required","disabled","slackChanelType","token"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:ur,decorators:[{type:n,args:[{selector:"tb-external-node-slack-config",template:'
\n \n tb.rulenode.message-template\n \n \n {{ \'tb.rulenode.message-template-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n {{ \'tb.rulenode.use-system-slack-settings\' | translate }}\n \n \n tb.rulenode.slack-api-token\n \n \n {{ \'tb.rulenode.slack-api-token-required\' | translate }}\n \n \n \n \n \n {{ slackChanelTypesTranslateMap.get(slackChanelType) | translate }}\n \n \n \n \n
\n',styles:[":host .tb-title{display:block;padding-bottom:6px}:host ::ng-deep .mat-mdc-radio-group{display:flex;flex-direction:row;margin-bottom:22px;gap:12px}:host ::ng-deep .mat-mdc-radio-group .mat-mdc-radio-button{flex:1 1 100%;padding:4px;border:1px solid rgba(0,0,0,.12);border-radius:6px}@media screen and (max-width: 599px){:host ::ng-deep .mat-mdc-radio-group{flex-direction:column}}\n"]}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder}]}});class cr extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.snsConfigForm}onConfigurationSet(e){this.snsConfigForm=this.fb.group({topicArnPattern:[e?e.topicArnPattern:null,[O.required]],accessKeyId:[e?e.accessKeyId:null,[O.required]],secretAccessKey:[e?e.secretAccessKey:null,[O.required]],region:[e?e.region:null,[O.required]]})}}e("SnsConfigComponent",cr),cr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:cr,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),cr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:cr,selector:"tb-external-node-sns-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.topic-arn-pattern\n \n \n {{ \'tb.rulenode.topic-arn-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.aws-access-key-id\n \n \n {{ \'tb.rulenode.aws-access-key-id-required\' | translate }}\n \n \n \n tb.rulenode.aws-secret-access-key\n \n \n {{ \'tb.rulenode.aws-secret-access-key-required\' | translate }}\n \n \n \n tb.rulenode.aws-region\n \n \n {{ \'tb.rulenode.aws-region-required\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:cr,decorators:[{type:n,args:[{selector:"tb-external-node-sns-config",template:'
\n \n tb.rulenode.topic-arn-pattern\n \n \n {{ \'tb.rulenode.topic-arn-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.aws-access-key-id\n \n \n {{ \'tb.rulenode.aws-access-key-id-required\' | translate }}\n \n \n \n tb.rulenode.aws-secret-access-key\n \n \n {{ \'tb.rulenode.aws-secret-access-key-required\' | translate }}\n \n \n \n tb.rulenode.aws-region\n \n \n {{ \'tb.rulenode.aws-region-required\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class fr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.sqsQueueType=Bt,this.sqsQueueTypes=Object.keys(Bt),this.sqsQueueTypeTranslationsMap=Kt}configForm(){return this.sqsConfigForm}onConfigurationSet(e){this.sqsConfigForm=this.fb.group({queueType:[e?e.queueType:null,[O.required]],queueUrlPattern:[e?e.queueUrlPattern:null,[O.required]],delaySeconds:[e?e.delaySeconds:null,[O.min(0),O.max(900)]],messageAttributes:[e?e.messageAttributes:null,[]],accessKeyId:[e?e.accessKeyId:null,[O.required]],secretAccessKey:[e?e.secretAccessKey:null,[O.required]],region:[e?e.region:null,[O.required]]})}}e("SqsConfigComponent",fr),fr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:fr,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),fr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:fr,selector:"tb-external-node-sqs-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.queue-type\n \n \n {{ sqsQueueTypeTranslationsMap.get(type) | translate }}\n \n \n \n \n tb.rulenode.queue-url-pattern\n \n \n {{ \'tb.rulenode.queue-url-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.delay-seconds\n \n \n {{ \'tb.rulenode.min-delay-seconds-message\' | translate }}\n \n \n {{ \'tb.rulenode.max-delay-seconds-message\' | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.aws-access-key-id\n \n \n {{ \'tb.rulenode.aws-access-key-id-required\' | translate }}\n \n \n \n tb.rulenode.aws-secret-access-key\n \n \n {{ \'tb.rulenode.aws-secret-access-key-required\' | translate }}\n \n \n \n tb.rulenode.aws-region\n \n \n {{ \'tb.rulenode.aws-region-required\' | translate }}\n \n \n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:hn,selector:"tb-kv-map-config-old",inputs:["disabled","uniqueKeyValuePairValidator","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","required"]},{kind:"pipe",type:he.SafePipe,name:"safe"},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:fr,decorators:[{type:n,args:[{selector:"tb-external-node-sqs-config",template:'
\n \n tb.rulenode.queue-type\n \n \n {{ sqsQueueTypeTranslationsMap.get(type) | translate }}\n \n \n \n \n tb.rulenode.queue-url-pattern\n \n \n {{ \'tb.rulenode.queue-url-pattern-required\' | translate }}\n \n tb.rulenode.general-pattern-hint\n \n \n tb.rulenode.delay-seconds\n \n \n {{ \'tb.rulenode.min-delay-seconds-message\' | translate }}\n \n \n {{ \'tb.rulenode.max-delay-seconds-message\' | translate }}\n \n \n \n
\n \n \n \n tb.rulenode.aws-access-key-id\n \n \n {{ \'tb.rulenode.aws-access-key-id-required\' | translate }}\n \n \n \n tb.rulenode.aws-secret-access-key\n \n \n {{ \'tb.rulenode.aws-secret-access-key-required\' | translate }}\n \n \n \n tb.rulenode.aws-region\n \n \n {{ \'tb.rulenode.aws-region-required\' | translate }}\n \n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class gr{}e("RulenodeCoreConfigExternalModule",gr),gr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:gr,deps:[],target:t.ɵɵFactoryTarget.NgModule}),gr.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.10",ngImport:t,type:gr,declarations:[cr,fr,lr,or,ar,ir,sr,mr,pr,rr,dr,ur],imports:[$,M,Re,Un],exports:[cr,fr,lr,or,ar,ir,sr,mr,pr,rr,dr,ur]}),gr.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:gr,imports:[$,M,Re,Un]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:gr,decorators:[{type:c,args:[{declarations:[cr,fr,lr,or,ar,ir,sr,mr,pr,rr,dr,ur],imports:[$,M,Re,Un],exports:[cr,fr,lr,or,ar,ir,sr,mr,pr,rr,dr,ur]}]}]});class yr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.searchText=""}configForm(){return this.alarmStatusConfigForm}prepareInputConfig(e){return{alarmStatusList:ie(e?.alarmStatusList)?e.alarmStatusList:null}}onConfigurationSet(e){this.alarmStatusConfigForm=this.fb.group({alarmStatusList:[e.alarmStatusList,[O.required]]})}}e("CheckAlarmStatusComponent",yr),yr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:yr,deps:[{token:P.Store},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),yr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:yr,selector:"tb-filter-node-check-alarm-status-config",usesInheritance:!0,ngImport:t,template:'
\n
\n
tb.rulenode.alarm-status
\n
\n tb.rulenode.alarm-required\n
\n
\n \n
\n\n\n\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:zn,selector:"tb-alarm-status-select"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:yr,decorators:[{type:n,args:[{selector:"tb-filter-node-check-alarm-status-config",template:'
\n
\n
tb.rulenode.alarm-status
\n
\n tb.rulenode.alarm-required\n
\n
\n \n
\n\n\n\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder}]}});class xr extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.checkMessageConfigForm}prepareInputConfig(e){return{messageNames:ie(e?.messageNames)?e.messageNames:[],metadataNames:ie(e?.metadataNames)?e.metadataNames:[],checkAllKeys:!!ie(e?.checkAllKeys)&&e.checkAllKeys}}prepareOutputConfig(e){return{messageNames:ie(e?.messageNames)?e.messageNames:[],metadataNames:ie(e?.metadataNames)?e.metadataNames:[],checkAllKeys:e.checkAllKeys}}atLeastOne(e,t=null){return n=>{t||(t=Object.keys(n.controls));return n?.controls&&t.some((t=>!e(n.controls[t])))?null:{atLeastOne:!0}}}onConfigurationSet(e){this.checkMessageConfigForm=this.fb.group({messageNames:[e.messageNames,[]],metadataNames:[e.metadataNames,[]],checkAllKeys:[e.checkAllKeys,[]]},{validators:this.atLeastOne(O.required,["messageNames","metadataNames"])})}get touchedValidationControl(){return["messageNames","metadataNames"].some((e=>this.checkMessageConfigForm.get(e).touched))}}e("CheckMessageConfigComponent",xr),xr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:xr,deps:[{token:P.Store},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),xr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:xr,selector:"tb-filter-node-check-message-config",usesInheritance:!0,ngImport:t,template:'
\n
\n
tb.rulenode.fields-to-check
\n
\n tb.rulenode.at-least-one-field-required\n
\n
\n \n help\n \n \n help\n \n
\n \n {{ \'tb.rulenode.check-all-keys\' | translate }}\n \n
\n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"component",type:Ze.StringItemsListComponent,selector:"tb-string-items-list",inputs:["required","disabled","label","placeholder","hint","requiredText","floatLabel","appearance","editable","subscriptSizing","predefinedValues"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:Y.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:te.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:ne.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:xr,decorators:[{type:n,args:[{selector:"tb-filter-node-check-message-config",template:'
\n
\n
tb.rulenode.fields-to-check
\n
\n tb.rulenode.at-least-one-field-required\n
\n
\n \n help\n \n \n help\n \n
\n \n {{ \'tb.rulenode.check-all-keys\' | translate }}\n \n
\n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder}]}});class br extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.entitySearchDirection=Object.values(v),this.entitySearchDirectionTranslationsMap=C}configForm(){return this.checkRelationConfigForm}prepareInputConfig(e){return{checkForSingleEntity:!!ie(e?.checkForSingleEntity)&&e.checkForSingleEntity,direction:ie(e?.direction)?e.direction:null,entityType:ie(e?.entityType)?e.entityType:null,entityId:ie(e?.entityId)?e.entityId:null,relationType:ie(e?.relationType)?e.relationType:null}}onConfigurationSet(e){this.checkRelationConfigForm=this.fb.group({checkForSingleEntity:[e.checkForSingleEntity,[]],direction:[e.direction,[]],entityType:[e.entityType,e&&e.checkForSingleEntity?[O.required]:[]],entityId:[e.entityId,e&&e.checkForSingleEntity?[O.required]:[]],relationType:[e.relationType,[O.required]]})}validatorTriggers(){return["checkForSingleEntity"]}updateValidators(e){const t=this.checkRelationConfigForm.get("checkForSingleEntity").value;this.checkRelationConfigForm.get("entityType").setValidators(t?[O.required]:[]),this.checkRelationConfigForm.get("entityType").updateValueAndValidity({emitEvent:e}),this.checkRelationConfigForm.get("entityId").setValidators(t?[O.required]:[]),this.checkRelationConfigForm.get("entityId").updateValueAndValidity({emitEvent:e})}}e("CheckRelationConfigComponent",br),br.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:br,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),br.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:br,selector:"tb-filter-node-check-relation-config",usesInheritance:!0,ngImport:t,template:'
\n
tb.rulenode.relation-search-parameters
\n
\n \n {{ \'relation.direction\' | translate }}\n \n \n {{ entitySearchDirectionTranslationsMap.get(direction) | translate }} tb.rulenode.relations-query-config-direction-suffix\n \n \n \n \n \n
\n \n {{ \'tb.rulenode.check-relation-to-specific-entity\' | translate }}\n \n
\n
\n \n \n \n \n
\n
\n
\n',styles:[":host .slide-toggle{margin-bottom:18px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:lt.EntityAutocompleteComponent,selector:"tb-entity-autocomplete",inputs:["entityType","entitySubtype","excludeEntityIds","labelText","requiredText","useFullEntityId","appearance","required","disabled"],outputs:["entityChanged"]},{kind:"component",type:ve.EntityTypeSelectComponent,selector:"tb-entity-type-select",inputs:["allowedEntityTypes","useAliasEntityTypes","filterAllowedEntityTypes","showLabel","required","disabled"]},{kind:"component",type:$e.RelationTypeAutocompleteComponent,selector:"tb-relation-type-autocomplete",inputs:["showLabel","additionalClasses","appearance","required","disabled","subscriptSizing"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:te.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:ne.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:br,decorators:[{type:n,args:[{selector:"tb-filter-node-check-relation-config",template:'
\n
tb.rulenode.relation-search-parameters
\n
\n \n {{ \'relation.direction\' | translate }}\n \n \n {{ entitySearchDirectionTranslationsMap.get(direction) | translate }} tb.rulenode.relations-query-config-direction-suffix\n \n \n \n \n \n
\n \n {{ \'tb.rulenode.check-relation-to-specific-entity\' | translate }}\n \n
\n
\n \n \n \n \n
\n
\n
\n',styles:[":host .slide-toggle{margin-bottom:18px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class hr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.perimeterType=Tt,this.perimeterTypes=Object.values(Tt),this.perimeterTypeTranslationMap=It,this.rangeUnits=Object.values(qt),this.rangeUnitTranslationMap=At,this.defaultPaddingEnable=!0}configForm(){return this.geoFilterConfigForm}prepareInputConfig(e){return{latitudeKeyName:ie(e?.latitudeKeyName)?e.latitudeKeyName:null,longitudeKeyName:ie(e?.longitudeKeyName)?e.longitudeKeyName:null,perimeterType:ie(e?.perimeterType)?e.perimeterType:null,fetchPerimeterInfoFromMessageMetadata:!!ie(e?.fetchPerimeterInfoFromMessageMetadata)&&e.fetchPerimeterInfoFromMessageMetadata,perimeterKeyName:ie(e?.perimeterKeyName)?e.perimeterKeyName:null,centerLatitude:ie(e?.centerLatitude)?e.centerLatitude:null,centerLongitude:ie(e?.centerLongitude)?e.centerLongitude:null,range:ie(e?.range)?e.range:null,rangeUnit:ie(e?.rangeUnit)?e.rangeUnit:null,polygonsDefinition:ie(e?.polygonsDefinition)?e.polygonsDefinition:null}}onConfigurationSet(e){this.geoFilterConfigForm=this.fb.group({latitudeKeyName:[e.latitudeKeyName,[O.required]],longitudeKeyName:[e.longitudeKeyName,[O.required]],perimeterType:[e.perimeterType,[O.required]],fetchPerimeterInfoFromMessageMetadata:[e.fetchPerimeterInfoFromMessageMetadata,[]],perimeterKeyName:[e.perimeterKeyName,[]],centerLatitude:[e.centerLatitude,[]],centerLongitude:[e.centerLongitude,[]],range:[e.range,[]],rangeUnit:[e.rangeUnit,[]],polygonsDefinition:[e.polygonsDefinition,[]]})}validatorTriggers(){return["fetchPerimeterInfoFromMessageMetadata","perimeterType"]}updateValidators(e){const t=this.geoFilterConfigForm.get("fetchPerimeterInfoFromMessageMetadata").value,n=this.geoFilterConfigForm.get("perimeterType").value;t?this.geoFilterConfigForm.get("perimeterKeyName").setValidators([O.required]):this.geoFilterConfigForm.get("perimeterKeyName").setValidators([]),t||n!==Tt.CIRCLE?(this.geoFilterConfigForm.get("centerLatitude").setValidators([]),this.geoFilterConfigForm.get("centerLongitude").setValidators([]),this.geoFilterConfigForm.get("range").setValidators([]),this.geoFilterConfigForm.get("rangeUnit").setValidators([]),this.defaultPaddingEnable=!0):(this.geoFilterConfigForm.get("centerLatitude").setValidators([O.required,O.min(-90),O.max(90)]),this.geoFilterConfigForm.get("centerLongitude").setValidators([O.required,O.min(-180),O.max(180)]),this.geoFilterConfigForm.get("range").setValidators([O.required,O.min(0)]),this.geoFilterConfigForm.get("rangeUnit").setValidators([O.required]),this.defaultPaddingEnable=!1),t||n!==Tt.POLYGON?this.geoFilterConfigForm.get("polygonsDefinition").setValidators([]):this.geoFilterConfigForm.get("polygonsDefinition").setValidators([O.required]),this.geoFilterConfigForm.get("perimeterKeyName").updateValueAndValidity({emitEvent:e}),this.geoFilterConfigForm.get("centerLatitude").updateValueAndValidity({emitEvent:e}),this.geoFilterConfigForm.get("centerLongitude").updateValueAndValidity({emitEvent:e}),this.geoFilterConfigForm.get("range").updateValueAndValidity({emitEvent:e}),this.geoFilterConfigForm.get("rangeUnit").updateValueAndValidity({emitEvent:e}),this.geoFilterConfigForm.get("polygonsDefinition").updateValueAndValidity({emitEvent:e})}}e("GpsGeoFilterConfigComponent",hr),hr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:hr,deps:[{token:P.Store},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),hr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:hr,selector:"tb-filter-node-gps-geofencing-config",usesInheritance:!0,ngImport:t,template:'
\n
\n
tb.rulenode.coordinate-field-names
\n
\n
\n \n {{ \'tb.rulenode.latitude-field-name\' | translate }}\n \n \n {{ \'tb.rulenode.latitude-field-name-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.longitude-field-name\' | translate }}\n \n \n {{ \'tb.rulenode.longitude-field-name-required\' | translate }}\n \n \n
\n
tb.rulenode.coordinate-field-hint
\n
\n
\n
\n
tb.rulenode.geofence-configuration
\n
\n \n {{ \'tb.rulenode.perimeter-type\' | translate }}\n \n \n {{ perimeterTypeTranslationMap.get(type) | translate }}\n \n \n \n
\n \n {{ \'tb.rulenode.fetch-perimeter-info-from-metadata\' | translate }}\n \n
\n \n {{ \'tb.rulenode.perimeter-key-name\' | translate }}\n \n \n {{ \'tb.rulenode.perimeter-key-name-required\' | translate }}\n \n {{ \'tb.rulenode.perimeter-key-name-hint\' | translate }}\n \n
\n
\n \n {{ \'tb.rulenode.circle-center-latitude\' | translate }}\n \n \n {{ \'tb.rulenode.circle-center-latitude-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.circle-center-longitude\' | translate }}\n \n \n {{ \'tb.rulenode.circle-center-longitude-required\' | translate }}\n \n \n
\n
\n \n {{ \'tb.rulenode.range\' | translate }}\n \n \n {{ \'tb.rulenode.range-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.range-units\' | translate }}\n \n \n {{ rangeUnitTranslationMap.get(type) | translate }}\n \n \n \n {{ \'tb.rulenode.range-units-required\' | translate }}\n \n \n
\n
\n \n {{ \'tb.rulenode.polygon-definition\' | translate }}\n \n {{ \'tb.rulenode.polygon-definition-hint\' | translate }}\n \n {{ \'tb.rulenode.polygon-definition-required\' | translate }}\n \n \n
\n
\n
\n',styles:[":host .slide-toggle{margin-bottom:18px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"component",type:te.MatSlideToggle,selector:"mat-slide-toggle",inputs:["disabled","disableRipple","color","tabIndex"],exportAs:["matSlideToggle"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:W.DefaultLayoutGapDirective,selector:" [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]",inputs:["fxLayoutGap","fxLayoutGap.xs","fxLayoutGap.sm","fxLayoutGap.md","fxLayoutGap.lg","fxLayoutGap.xl","fxLayoutGap.lt-sm","fxLayoutGap.lt-md","fxLayoutGap.lt-lg","fxLayoutGap.lt-xl","fxLayoutGap.gt-xs","fxLayoutGap.gt-sm","fxLayoutGap.gt-md","fxLayoutGap.gt-lg"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.MinValidator,selector:"input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]",inputs:["min"]},{kind:"directive",type:R.MaxValidator,selector:"input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]",inputs:["max"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:ne.HintTooltipIconComponent,selector:"[tb-hint-tooltip-icon]",inputs:["tb-hint-tooltip-icon","tooltipPosition","hintIcon"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:hr,decorators:[{type:n,args:[{selector:"tb-filter-node-gps-geofencing-config",template:'
\n
\n
tb.rulenode.coordinate-field-names
\n
\n
\n \n {{ \'tb.rulenode.latitude-field-name\' | translate }}\n \n \n {{ \'tb.rulenode.latitude-field-name-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.longitude-field-name\' | translate }}\n \n \n {{ \'tb.rulenode.longitude-field-name-required\' | translate }}\n \n \n
\n
tb.rulenode.coordinate-field-hint
\n
\n
\n
\n
tb.rulenode.geofence-configuration
\n
\n \n {{ \'tb.rulenode.perimeter-type\' | translate }}\n \n \n {{ perimeterTypeTranslationMap.get(type) | translate }}\n \n \n \n
\n \n {{ \'tb.rulenode.fetch-perimeter-info-from-metadata\' | translate }}\n \n
\n \n {{ \'tb.rulenode.perimeter-key-name\' | translate }}\n \n \n {{ \'tb.rulenode.perimeter-key-name-required\' | translate }}\n \n {{ \'tb.rulenode.perimeter-key-name-hint\' | translate }}\n \n
\n
\n \n {{ \'tb.rulenode.circle-center-latitude\' | translate }}\n \n \n {{ \'tb.rulenode.circle-center-latitude-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.circle-center-longitude\' | translate }}\n \n \n {{ \'tb.rulenode.circle-center-longitude-required\' | translate }}\n \n \n
\n
\n \n {{ \'tb.rulenode.range\' | translate }}\n \n \n {{ \'tb.rulenode.range-required\' | translate }}\n \n \n \n {{ \'tb.rulenode.range-units\' | translate }}\n \n \n {{ rangeUnitTranslationMap.get(type) | translate }}\n \n \n \n {{ \'tb.rulenode.range-units-required\' | translate }}\n \n \n
\n
\n \n {{ \'tb.rulenode.polygon-definition\' | translate }}\n \n {{ \'tb.rulenode.polygon-definition-hint\' | translate }}\n \n {{ \'tb.rulenode.polygon-definition-required\' | translate }}\n \n \n
\n
\n
\n',styles:[":host .slide-toggle{margin-bottom:18px}\n",':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder}]}});class vr extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.messageTypeConfigForm}prepareInputConfig(e){return{messageTypes:ie(e?.messageTypes)?e.messageTypes:null}}onConfigurationSet(e){this.messageTypeConfigForm=this.fb.group({messageTypes:[e.messageTypes,[O.required]]})}}e("MessageTypeConfigComponent",vr),vr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:vr,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),vr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:vr,selector:"tb-filter-node-message-type-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n
\n',dependencies:[{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:Mn,selector:"tb-message-types-config",inputs:["required","label","placeholder","disabled"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:vr,decorators:[{type:n,args:[{selector:"tb-filter-node-message-type-config",template:'
\n \n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class Cr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.allowedEntityTypes=[F.DEVICE,F.ASSET,F.ENTITY_VIEW,F.TENANT,F.CUSTOMER,F.USER,F.DASHBOARD,F.RULE_CHAIN,F.RULE_NODE]}configForm(){return this.originatorTypeConfigForm}prepareInputConfig(e){return{originatorTypes:ie(e?.originatorTypes)?e.originatorTypes:null}}onConfigurationSet(e){this.originatorTypeConfigForm=this.fb.group({originatorTypes:[e.originatorTypes,[O.required]]})}}e("OriginatorTypeConfigComponent",Cr),Cr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Cr,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Cr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Cr,selector:"tb-filter-node-originator-type-config",usesInheritance:!0,ngImport:t,template:'
\n \n help\n \n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"component",type:st.EntityTypeListComponent,selector:"tb-entity-type-list",inputs:["required","additionalClasses","appearance","label","floatLabel","disabled","subscriptSizing","allowedEntityTypes","emptyInputPlaceholder","filledInputPlaceholder","ignoreAuthorityFilter"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:Y.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:W.DefaultFlexDirective,selector:" [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]",inputs:["fxFlex","fxFlex.xs","fxFlex.sm","fxFlex.md","fxFlex.lg","fxFlex.xl","fxFlex.lt-sm","fxFlex.lt-md","fxFlex.lt-lg","fxFlex.lt-xl","fxFlex.gt-xs","fxFlex.gt-sm","fxFlex.gt-md","fxFlex.gt-lg"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Cr,decorators:[{type:n,args:[{selector:"tb-filter-node-originator-type-config",template:'
\n \n help\n \n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class Fr extends f{constructor(e,t,n,o){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=n,this.translate=o,this.tbelEnabled=re(this.store).tbelEnabled,this.scriptLanguage=x,this.changeScript=new r,this.hasScript=!0,this.testScriptLabel="tb.rulenode.test-filter-function"}configForm(){return this.scriptConfigForm}onConfigurationSet(e){this.scriptConfigForm=this.fb.group({scriptLang:[e.scriptLang,[O.required]],jsScript:[e.jsScript,[]],tbelScript:[e.tbelScript,[]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.scriptConfigForm.get("scriptLang").value;t!==x.TBEL||this.tbelEnabled||(t=x.JS,this.scriptConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.scriptConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.scriptConfigForm.get("jsScript").setValidators(t===x.JS?[O.required]:[]),this.scriptConfigForm.get("jsScript").updateValueAndValidity({emitEvent:e}),this.scriptConfigForm.get("tbelScript").setValidators(t===x.TBEL?[O.required]:[]),this.scriptConfigForm.get("tbelScript").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=x.JS)),{scriptLang:ie(e?.scriptLang)?e.scriptLang:x.JS,jsScript:ie(e?.jsScript)?e.jsScript:null,tbelScript:ie(e?.tbelScript)?e.tbelScript:null}}testScript(e){const t=this.scriptConfigForm.get("scriptLang").value,n=t===x.JS?"jsScript":"tbelScript",r=t===x.JS?"rulenode/filter_node_script_fn":"rulenode/tbel/filter_node_script_fn",o=this.scriptConfigForm.get(n).value;this.nodeScriptTestService.testNodeScript(o,"filter",this.translate.instant("tb.rulenode.filter"),"Filter",["msg","metadata","msgType"],this.ruleNodeId,r,t,e).subscribe((e=>{e&&(this.scriptConfigForm.get(n).setValue(e),this.changeScript.emit())}))}onValidate(){this.scriptConfigForm.get("scriptLang").value===x.JS&&this.jsFuncComponent.validateOnSubmit()}}e("ScriptConfigComponent",Fr),Fr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Fr,deps:[{token:P.Store},{token:R.UntypedFormBuilder},{token:oe.NodeScriptTestService},{token:Z.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Fr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Fr,selector:"tb-filter-node-script-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n \n \n \n
\n',dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:pe.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:de.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:de.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:fe.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Fr,decorators:[{type:n,args:[{selector:"tb-filter-node-script-config",template:'
\n \n \n \n \n \n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder},{type:oe.NodeScriptTestService},{type:Z.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}});class kr extends f{constructor(e,t,n,o){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=n,this.translate=o,this.tbelEnabled=re(this.store).tbelEnabled,this.scriptLanguage=x,this.changeScript=new r,this.hasScript=!0,this.testScriptLabel="tb.rulenode.test-switch-function"}configForm(){return this.switchConfigForm}onConfigurationSet(e){this.switchConfigForm=this.fb.group({scriptLang:[e.scriptLang,[O.required]],jsScript:[e.jsScript,[]],tbelScript:[e.tbelScript,[]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.switchConfigForm.get("scriptLang").value;t!==x.TBEL||this.tbelEnabled||(t=x.JS,this.switchConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.switchConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.switchConfigForm.get("jsScript").setValidators(t===x.JS?[O.required]:[]),this.switchConfigForm.get("jsScript").updateValueAndValidity({emitEvent:e}),this.switchConfigForm.get("tbelScript").setValidators(t===x.TBEL?[O.required]:[]),this.switchConfigForm.get("tbelScript").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=x.JS)),{scriptLang:ie(e?.scriptLang)?e.scriptLang:x.JS,jsScript:ie(e?.jsScript)?e.jsScript:null,tbelScript:ie(e?.tbelScript)?e.tbelScript:null}}testScript(e){const t=this.switchConfigForm.get("scriptLang").value,n=t===x.JS?"jsScript":"tbelScript",r=t===x.JS?"rulenode/switch_node_script_fn":"rulenode/tbel/switch_node_script_fn",o=this.switchConfigForm.get(n).value;this.nodeScriptTestService.testNodeScript(o,"switch",this.translate.instant("tb.rulenode.switch"),"Switch",["msg","metadata","msgType"],this.ruleNodeId,r,t,e).subscribe((e=>{e&&(this.switchConfigForm.get(n).setValue(e),this.changeScript.emit())}))}onValidate(){this.switchConfigForm.get("scriptLang").value===x.JS&&this.jsFuncComponent.validateOnSubmit()}}e("SwitchConfigComponent",kr),kr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:kr,deps:[{token:P.Store},{token:R.UntypedFormBuilder},{token:oe.NodeScriptTestService},{token:Z.TranslateService}],target:t.ɵɵFactoryTarget.Component}),kr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:kr,selector:"tb-filter-node-switch-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n \n \n \n
\n',dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:pe.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:de.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:de.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:fe.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:kr,decorators:[{type:n,args:[{selector:"tb-filter-node-switch-config",template:'
\n \n \n \n \n \n \n \n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder},{type:oe.NodeScriptTestService},{type:Z.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}});class Lr{}e("RuleNodeCoreConfigFilterModule",Lr),Lr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Lr,deps:[],target:t.ɵɵFactoryTarget.NgModule}),Lr.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.10",ngImport:t,type:Lr,declarations:[xr,br,hr,vr,Cr,Fr,kr,yr],imports:[$,M,Un],exports:[xr,br,hr,vr,Cr,Fr,kr,yr]}),Lr.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Lr,imports:[$,M,Un]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Lr,decorators:[{type:c,args:[{declarations:[xr,br,hr,vr,Cr,Fr,kr,yr],imports:[$,M,Un],exports:[xr,br,hr,vr,Cr,Fr,kr,yr]}]}]});class Tr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.originatorSource=vt,this.originatorSources=Object.keys(vt),this.originatorSourceTranslationMap=Ct,this.originatorSourceDescTranslationMap=Ft,this.allowedEntityTypes=[F.DEVICE,F.ASSET,F.ENTITY_VIEW,F.USER,F.EDGE]}configForm(){return this.changeOriginatorConfigForm}onConfigurationSet(e){this.changeOriginatorConfigForm=this.fb.group({originatorSource:[e?e.originatorSource:null,[O.required]],entityType:[e?e.entityType:null,[]],entityNamePattern:[e?e.entityNamePattern:null,[]],relationsQuery:[e?e.relationsQuery:null,[]]})}validatorTriggers(){return["originatorSource"]}updateValidators(e){const t=this.changeOriginatorConfigForm.get("originatorSource").value;t===vt.RELATED?this.changeOriginatorConfigForm.get("relationsQuery").setValidators([O.required]):this.changeOriginatorConfigForm.get("relationsQuery").setValidators([]),t===vt.ENTITY?(this.changeOriginatorConfigForm.get("entityType").setValidators([O.required]),this.changeOriginatorConfigForm.get("entityNamePattern").setValidators([O.required,O.pattern(/.*\S.*/)])):(this.changeOriginatorConfigForm.get("entityType").patchValue(null,{emitEvent:e}),this.changeOriginatorConfigForm.get("entityNamePattern").patchValue(null,{emitEvent:e}),this.changeOriginatorConfigForm.get("entityType").setValidators([]),this.changeOriginatorConfigForm.get("entityNamePattern").setValidators([])),this.changeOriginatorConfigForm.get("relationsQuery").updateValueAndValidity({emitEvent:e}),this.changeOriginatorConfigForm.get("entityType").updateValueAndValidity({emitEvent:e}),this.changeOriginatorConfigForm.get("entityNamePattern").updateValueAndValidity({emitEvent:e})}}e("ChangeOriginatorConfigComponent",Tr),Tr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Tr,deps:[{token:P.Store},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Tr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Tr,selector:"tb-transformation-node-change-originator-config",usesInheritance:!0,ngImport:t,template:'
\n \n tb.rulenode.new-originator\n \n \n \n {{ originatorSourceTranslationMap.get(changeOriginatorConfigForm.get(\'originatorSource\').value) | translate }}\n \n \n \n \n {{ originatorSourceTranslationMap.get(source) | translate }}\n \n
\n \n {{ originatorSourceDescTranslationMap.get(source) | translate }}\n \n
\n
\n
\n
\n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n \n
\n
\n \n \n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ve.EntityTypeSelectComponent,selector:"tb-entity-type-select",inputs:["allowedEntityTypes","useAliasEntityTypes","filterAllowedEntityTypes","showLabel","required","disabled"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"directive",type:X.MatSelectTrigger,selector:"mat-select-trigger"},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:Ne.MatListItemTitle,selector:"[matListItemTitle]"},{kind:"directive",type:Ne.MatListItemMeta,selector:"[matListItemMeta]"},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:An,selector:"tb-relations-query-config",inputs:["disabled","required"]},{kind:"component",type:Nn,selector:"tb-example-hint",inputs:["hintText","popupHelpLink","textAlign"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Tr,decorators:[{type:n,args:[{selector:"tb-transformation-node-change-originator-config",template:'
\n \n tb.rulenode.new-originator\n \n \n \n {{ originatorSourceTranslationMap.get(changeOriginatorConfigForm.get(\'originatorSource\').value) | translate }}\n \n \n \n \n {{ originatorSourceTranslationMap.get(source) | translate }}\n \n
\n \n {{ originatorSourceDescTranslationMap.get(source) | translate }}\n \n
\n
\n
\n
\n \n \n
\n \n \n \n tb.rulenode.entity-name-pattern\n \n \n {{ \'tb.rulenode.entity-name-pattern-required\' | translate }}\n \n \n
\n
\n \n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder}]}});class Ir extends f{constructor(e,t,n,o){super(e),this.store=e,this.fb=t,this.nodeScriptTestService=n,this.translate=o,this.tbelEnabled=re(this.store).tbelEnabled,this.scriptLanguage=x,this.changeScript=new r,this.hasScript=!0,this.testScriptLabel="tb.rulenode.test-transformer-function"}configForm(){return this.scriptConfigForm}onConfigurationSet(e){this.scriptConfigForm=this.fb.group({scriptLang:[e?e.scriptLang:x.JS,[O.required]],jsScript:[e?e.jsScript:null,[O.required]],tbelScript:[e?e.tbelScript:null,[]]})}validatorTriggers(){return["scriptLang"]}updateValidators(e){let t=this.scriptConfigForm.get("scriptLang").value;t!==x.TBEL||this.tbelEnabled||(t=x.JS,this.scriptConfigForm.get("scriptLang").patchValue(t,{emitEvent:!1}),setTimeout((()=>{this.scriptConfigForm.updateValueAndValidity({emitEvent:!0})}))),this.scriptConfigForm.get("jsScript").setValidators(t===x.JS?[O.required]:[]),this.scriptConfigForm.get("jsScript").updateValueAndValidity({emitEvent:e}),this.scriptConfigForm.get("tbelScript").setValidators(t===x.TBEL?[O.required]:[]),this.scriptConfigForm.get("tbelScript").updateValueAndValidity({emitEvent:e})}prepareInputConfig(e){return e&&(e.scriptLang||(e.scriptLang=x.JS)),e}testScript(e){const t=this.scriptConfigForm.get("scriptLang").value,n=t===x.JS?"jsScript":"tbelScript",r=t===x.JS?"rulenode/transformation_node_script_fn":"rulenode/tbel/transformation_node_script_fn",o=this.scriptConfigForm.get(n).value;this.nodeScriptTestService.testNodeScript(o,"update",this.translate.instant("tb.rulenode.transformer"),"Transform",["msg","metadata","msgType"],this.ruleNodeId,r,t,e).subscribe((e=>{e&&(this.scriptConfigForm.get(n).setValue(e),this.changeScript.emit())}))}onValidate(){this.scriptConfigForm.get("scriptLang").value===x.JS&&this.jsFuncComponent.validateOnSubmit()}}e("TransformScriptConfigComponent",Ir),Ir.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Ir,deps:[{token:P.Store},{token:R.FormBuilder},{token:oe.NodeScriptTestService},{token:Z.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Ir.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Ir,selector:"tb-transformation-node-script-config",viewQueries:[{propertyName:"jsFuncComponent",first:!0,predicate:["jsFuncComponent"],descendants:!0},{propertyName:"tbelFuncComponent",first:!0,predicate:["tbelFuncComponent"],descendants:!0}],usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n \n \n \n
\n \n
\n
\n',dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:pe.JsFuncComponent,selector:"tb-js-func",inputs:["functionTitle","functionName","functionArgs","validationArgs","resultType","disabled","fillHeight","minHeight","editorCompleter","globalVariables","disableUndefinedCheck","helpId","scriptLanguage","noValidate","required"]},{kind:"component",type:de.MatButton,selector:" button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:de.MatIconButton,selector:"button[mat-icon-button]",inputs:["disabled","disableRipple","color"],exportAs:["matButton"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:fe.TbScriptLangComponent,selector:"tb-script-lang",inputs:["disabled"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Ir,decorators:[{type:n,args:[{selector:"tb-transformation-node-script-config",template:'
\n \n \n \n \n \n \n \n
\n \n
\n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder},{type:oe.NodeScriptTestService},{type:Z.TranslateService}]},propDecorators:{jsFuncComponent:[{type:o,args:["jsFuncComponent",{static:!1}]}],tbelFuncComponent:[{type:o,args:["tbelFuncComponent",{static:!1}]}]}}); + /** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.io/license + */ + const Nr=mt({passive:!0});class Sr{constructor(e,t){this._platform=e,this._ngZone=t,this._monitoredElements=new Map}monitor(e){if(!this._platform.isBrowser)return ze;const t=ke(e),n=this._monitoredElements.get(t);if(n)return n.subject;const r=new _e,o="cdk-text-field-autofilled",a=e=>{"cdk-text-field-autofill-start"!==e.animationName||t.classList.contains(o)?"cdk-text-field-autofill-end"===e.animationName&&t.classList.contains(o)&&(t.classList.remove(o),this._ngZone.run((()=>r.next({target:e.target,isAutofilled:!1})))):(t.classList.add(o),this._ngZone.run((()=>r.next({target:e.target,isAutofilled:!0}))))};return this._ngZone.runOutsideAngular((()=>{t.addEventListener("animationstart",a,Nr),t.classList.add("cdk-text-field-autofill-monitored")})),this._monitoredElements.set(t,{subject:r,unlisten:()=>{t.removeEventListener("animationstart",a,Nr)}}),r}stopMonitoring(e){const t=ke(e),n=this._monitoredElements.get(t);n&&(n.unlisten(),n.subject.complete(),t.classList.remove("cdk-text-field-autofill-monitored"),t.classList.remove("cdk-text-field-autofilled"),this._monitoredElements.delete(t))}ngOnDestroy(){this._monitoredElements.forEach(((e,t)=>this.stopMonitoring(t)))}}Sr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.0-rc.0",ngImport:t,type:Sr,deps:[{token:pt.Platform},{token:t.NgZone}],target:t.ɵɵFactoryTarget.Injectable}),Sr.ɵprov=t.ɵɵngDeclareInjectable({minVersion:"12.0.0",version:"15.2.0-rc.0",ngImport:t,type:Sr,providedIn:"root"}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.0-rc.0",ngImport:t,type:Sr,decorators:[{type:s,args:[{providedIn:"root"}]}],ctorParameters:function(){return[{type:pt.Platform},{type:t.NgZone}]}});class qr{constructor(e,t){this._elementRef=e,this._autofillMonitor=t,this.cdkAutofill=new r}ngOnInit(){this._autofillMonitor.monitor(this._elementRef).subscribe((e=>this.cdkAutofill.emit(e)))}ngOnDestroy(){this._autofillMonitor.stopMonitoring(this._elementRef)}}qr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.0-rc.0",ngImport:t,type:qr,deps:[{token:t.ElementRef},{token:Sr}],target:t.ɵɵFactoryTarget.Directive}),qr.ɵdir=t.ɵɵngDeclareDirective({minVersion:"14.0.0",version:"15.2.0-rc.0",type:qr,selector:"[cdkAutofill]",outputs:{cdkAutofill:"cdkAutofill"},ngImport:t}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.0-rc.0",ngImport:t,type:qr,decorators:[{type:d,args:[{selector:"[cdkAutofill]"}]}],ctorParameters:function(){return[{type:t.ElementRef},{type:Sr}]},propDecorators:{cdkAutofill:[{type:u}]}}); + /** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.io/license + */ + class Ar{get minRows(){return this._minRows}set minRows(e){this._minRows=Le(e),this._setMinHeight()}get maxRows(){return this._maxRows}set maxRows(e){this._maxRows=Le(e),this._setMaxHeight()}get enabled(){return this._enabled}set enabled(e){e=Fe(e),this._enabled!==e&&((this._enabled=e)?this.resizeToFitContent(!0):this.reset())}get placeholder(){return this._textareaElement.placeholder}set placeholder(e){this._cachedPlaceholderHeight=void 0,e?this._textareaElement.setAttribute("placeholder",e):this._textareaElement.removeAttribute("placeholder"),this._cacheTextareaPlaceholderHeight()}constructor(e,t,n,r){this._elementRef=e,this._platform=t,this._ngZone=n,this._destroyed=new _e,this._enabled=!0,this._previousMinRows=-1,this._isViewInited=!1,this._handleFocusEvent=e=>{this._hasFocus="focus"===e.type},this._document=r,this._textareaElement=this._elementRef.nativeElement}_setMinHeight(){const e=this.minRows&&this._cachedLineHeight?this.minRows*this._cachedLineHeight+"px":null;e&&(this._textareaElement.style.minHeight=e)}_setMaxHeight(){const e=this.maxRows&&this._cachedLineHeight?this.maxRows*this._cachedLineHeight+"px":null;e&&(this._textareaElement.style.maxHeight=e)}ngAfterViewInit(){this._platform.isBrowser&&(this._initialHeight=this._textareaElement.style.height,this.resizeToFitContent(),this._ngZone.runOutsideAngular((()=>{const e=this._getWindow();Ue(e,"resize").pipe(we(16),De(this._destroyed)).subscribe((()=>this.resizeToFitContent(!0))),this._textareaElement.addEventListener("focus",this._handleFocusEvent),this._textareaElement.addEventListener("blur",this._handleFocusEvent)})),this._isViewInited=!0,this.resizeToFitContent(!0))}ngOnDestroy(){this._textareaElement.removeEventListener("focus",this._handleFocusEvent),this._textareaElement.removeEventListener("blur",this._handleFocusEvent),this._destroyed.next(),this._destroyed.complete()}_cacheTextareaLineHeight(){if(this._cachedLineHeight)return;let e=this._textareaElement.cloneNode(!1);e.rows=1,e.style.position="absolute",e.style.visibility="hidden",e.style.border="none",e.style.padding="0",e.style.height="",e.style.minHeight="",e.style.maxHeight="",e.style.overflow="hidden",this._textareaElement.parentNode.appendChild(e),this._cachedLineHeight=e.clientHeight,e.remove(),this._setMinHeight(),this._setMaxHeight()}_measureScrollHeight(){const e=this._textareaElement,t=e.style.marginBottom||"",n=this._platform.FIREFOX,r=n&&this._hasFocus,o=n?"cdk-textarea-autosize-measuring-firefox":"cdk-textarea-autosize-measuring";r&&(e.style.marginBottom=`${e.clientHeight}px`),e.classList.add(o);const a=e.scrollHeight-4;return e.classList.remove(o),r&&(e.style.marginBottom=t),a}_cacheTextareaPlaceholderHeight(){if(!this._isViewInited||null!=this._cachedPlaceholderHeight)return;if(!this.placeholder)return void(this._cachedPlaceholderHeight=0);const e=this._textareaElement.value;this._textareaElement.value=this._textareaElement.placeholder,this._cachedPlaceholderHeight=this._measureScrollHeight(),this._textareaElement.value=e}ngDoCheck(){this._platform.isBrowser&&this.resizeToFitContent()}resizeToFitContent(e=!1){if(!this._enabled)return;if(this._cacheTextareaLineHeight(),this._cacheTextareaPlaceholderHeight(),!this._cachedLineHeight)return;const t=this._elementRef.nativeElement,n=t.value;if(!e&&this._minRows===this._previousMinRows&&n===this._previousValue)return;const r=this._measureScrollHeight(),o=Math.max(r,this._cachedPlaceholderHeight||0);t.style.height=`${o}px`,this._ngZone.runOutsideAngular((()=>{"undefined"!=typeof requestAnimationFrame?requestAnimationFrame((()=>this._scrollToCaretPosition(t))):setTimeout((()=>this._scrollToCaretPosition(t)))})),this._previousValue=n,this._previousMinRows=this._minRows}reset(){void 0!==this._initialHeight&&(this._textareaElement.style.height=this._initialHeight)}_noopInputHandler(){}_getDocument(){return this._document||document}_getWindow(){return this._getDocument().defaultView||window}_scrollToCaretPosition(e){const{selectionStart:t,selectionEnd:n}=e;!this._destroyed.isStopped&&this._hasFocus&&e.setSelectionRange(t,n)}}Ar.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.0-rc.0",ngImport:t,type:Ar,deps:[{token:t.ElementRef},{token:pt.Platform},{token:t.NgZone},{token:j,optional:!0}],target:t.ɵɵFactoryTarget.Directive}),Ar.ɵdir=t.ɵɵngDeclareDirective({minVersion:"14.0.0",version:"15.2.0-rc.0",type:Ar,selector:"textarea[cdkTextareaAutosize]",inputs:{minRows:["cdkAutosizeMinRows","minRows"],maxRows:["cdkAutosizeMaxRows","maxRows"],enabled:["cdkTextareaAutosize","enabled"],placeholder:"placeholder"},host:{attributes:{rows:"1"},listeners:{input:"_noopInputHandler()"},classAttribute:"cdk-textarea-autosize"},exportAs:["cdkTextareaAutosize"],ngImport:t}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.0-rc.0",ngImport:t,type:Ar,decorators:[{type:d,args:[{selector:"textarea[cdkTextareaAutosize]",exportAs:"cdkTextareaAutosize",host:{class:"cdk-textarea-autosize",rows:"1","(input)":"_noopInputHandler()"}}]}],ctorParameters:function(){return[{type:t.ElementRef},{type:pt.Platform},{type:t.NgZone},{type:void 0,decorators:[{type:p},{type:m,args:[j]}]}]},propDecorators:{minRows:[{type:i,args:["cdkAutosizeMinRows"]}],maxRows:[{type:i,args:["cdkAutosizeMaxRows"]}],enabled:[{type:i,args:["cdkTextareaAutosize"]}],placeholder:[{type:i}]}}); + /** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.io/license + */ + class Mr{}Mr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.0-rc.0",ngImport:t,type:Mr,deps:[],target:t.ɵɵFactoryTarget.NgModule}),Mr.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.0-rc.0",ngImport:t,type:Mr,declarations:[qr,Ar],exports:[qr,Ar]}),Mr.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.0-rc.0",ngImport:t,type:Mr}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.0-rc.0",ngImport:t,type:Mr,decorators:[{type:c,args:[{declarations:[qr,Ar],exports:[qr,Ar]}]}]});class Er extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.mailBodyTypes=[{name:"tb.mail-body-type.plain-text",description:"tb.mail-body-type.plain-text-description",value:"false"},{name:"tb.mail-body-type.html",description:"tb.mail-body-type.html-text-description",value:"true"},{name:"tb.mail-body-type.use-body-type-template",description:"tb.mail-body-type.dynamic-text-description",value:"dynamic"}]}configForm(){return this.toEmailConfigForm}onConfigurationSet(e){this.toEmailConfigForm=this.fb.group({fromTemplate:[e?e.fromTemplate:null,[O.required]],toTemplate:[e?e.toTemplate:null,[O.required]],ccTemplate:[e?e.ccTemplate:null,[]],bccTemplate:[e?e.bccTemplate:null,[]],subjectTemplate:[e?e.subjectTemplate:null,[O.required]],mailBodyType:[e?e.mailBodyType:null],isHtmlTemplate:[e?e.isHtmlTemplate:null,[O.required]],bodyTemplate:[e?e.bodyTemplate:null,[O.required]]})}prepareInputConfig(e){return{fromTemplate:ie(e?.fromTemplate)?e.fromTemplate:null,toTemplate:ie(e?.toTemplate)?e.toTemplate:null,ccTemplate:ie(e?.ccTemplate)?e.ccTemplate:null,bccTemplate:ie(e?.bccTemplate)?e.bccTemplate:null,subjectTemplate:ie(e?.subjectTemplate)?e.subjectTemplate:null,mailBodyType:ie(e?.mailBodyType)?e.mailBodyType:null,isHtmlTemplate:ie(e?.isHtmlTemplate)?e.isHtmlTemplate:null,bodyTemplate:ie(e?.bodyTemplate)?e.bodyTemplate:null}}updateValidators(e){"dynamic"===this.toEmailConfigForm.get("mailBodyType").value?this.toEmailConfigForm.get("isHtmlTemplate").enable({emitEvent:!1}):this.toEmailConfigForm.get("isHtmlTemplate").disable({emitEvent:!1}),this.toEmailConfigForm.get("isHtmlTemplate").updateValueAndValidity({emitEvent:e})}validatorTriggers(){return["mailBodyType"]}getBodyTypeName(){return this.mailBodyTypes.find((e=>e.value===this.toEmailConfigForm.get("mailBodyType").value)).name}}e("ToEmailConfigComponent",Er),Er.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Er,deps:[{token:P.Store},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Er.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Er,selector:"tb-transformation-node-to-email-config",usesInheritance:!0,ngImport:t,template:'
\n
\n
tb.rulenode.email-sender
\n
\n \n tb.rulenode.from-template\n \n \n {{ \'tb.rulenode.email-from-template-hint\' | translate }}\n \n \n
\n
\n
\n
\n \n {{ \'tb.rulenode.from-template-required\' | translate }}\n \n
\n
\n
\n
\n
\n
tb.rulenode.recipients
\n \n \n
\n
\n \n tb.rulenode.to-template\n \n \n {{ \'tb.rulenode.to-template-required\' | translate }}\n \n \n \n tb.rulenode.cc-template\n \n \n \n tb.rulenode.bcc-template\n \n \n
\n
\n
\n
tb.rulenode.message-subject-and-content
\n \n \n
\n \n tb.rulenode.subject-template\n \n \n {{ \'tb.rulenode.subject-template-required\' | translate }}\n \n \n \n tb.rulenode.mail-body-type\n \n \n \n {{ getBodyTypeName() | translate }}\n \n \n \n \n {{ type.name | translate }}\n \n
\n \n {{ type.description | translate }}\n \n
\n
\n
\n \n tb.rulenode.body-type-template\n \n tb.mail-body-type.after-template-evaluation-hint\n \n \n tb.rulenode.body-template\n \n \n {{ \'tb.rulenode.body-template-required\' | translate }}\n \n \n
\n
\n
\n',styles:[":host .input-bottom-double-hint{display:inline-flex}:host .input-bottom-double-hint .see-example{flex-shrink:0;padding-right:16px}:host textarea.tb-enable-vertical-resize{resize:vertical}\n"],dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:He.HelpPopupComponent,selector:"[tb-help-popup], [tb-help-popup-content]",inputs:["tb-help-popup","tb-help-popup-content","trigger-text","trigger-style","tb-help-popup-placement","tb-help-popup-style","hintMode"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Ar,selector:"textarea[cdkTextareaAutosize]",inputs:["cdkAutosizeMinRows","cdkAutosizeMaxRows","cdkTextareaAutosize","placeholder"],exportAs:["cdkTextareaAutosize"]},{kind:"component",type:X.MatSelect,selector:"mat-select",inputs:["disabled","disableRipple","tabIndex","hideSingleSelectionIndicator"],exportAs:["matSelect"]},{kind:"directive",type:X.MatSelectTrigger,selector:"mat-select-trigger"},{kind:"component",type:ee.MatOption,selector:"mat-option",exportAs:["matOption"]},{kind:"directive",type:Ne.MatListItemTitle,selector:"[matListItemTitle]"},{kind:"directive",type:Ne.MatListItemMeta,selector:"[matListItemMeta]"},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"component",type:Nn,selector:"tb-example-hint",inputs:["hintText","popupHelpLink","textAlign"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Er,decorators:[{type:n,args:[{selector:"tb-transformation-node-to-email-config",template:'
\n
\n
tb.rulenode.email-sender
\n
\n \n tb.rulenode.from-template\n \n \n {{ \'tb.rulenode.email-from-template-hint\' | translate }}\n \n \n
\n
\n
\n
\n \n {{ \'tb.rulenode.from-template-required\' | translate }}\n \n
\n
\n
\n
\n
\n
tb.rulenode.recipients
\n \n \n
\n
\n \n tb.rulenode.to-template\n \n \n {{ \'tb.rulenode.to-template-required\' | translate }}\n \n \n \n tb.rulenode.cc-template\n \n \n \n tb.rulenode.bcc-template\n \n \n
\n
\n
\n
tb.rulenode.message-subject-and-content
\n \n \n
\n \n tb.rulenode.subject-template\n \n \n {{ \'tb.rulenode.subject-template-required\' | translate }}\n \n \n \n tb.rulenode.mail-body-type\n \n \n \n {{ getBodyTypeName() | translate }}\n \n \n \n \n {{ type.name | translate }}\n \n
\n \n {{ type.description | translate }}\n \n
\n
\n
\n \n tb.rulenode.body-type-template\n \n tb.mail-body-type.after-template-evaluation-hint\n \n \n tb.rulenode.body-template\n \n \n {{ \'tb.rulenode.body-template-required\' | translate }}\n \n \n
\n
\n
\n',styles:[":host .input-bottom-double-hint{display:inline-flex}:host .input-bottom-double-hint .see-example{flex-shrink:0;padding-right:16px}:host textarea.tb-enable-vertical-resize{resize:vertical}\n"]}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder}]}});class Gr extends f{constructor(e,t,n){super(e),this.store=e,this.fb=t,this.translate=n,this.copyFrom=[],this.translation=tn;for(const e of this.translation.keys())this.copyFrom.push({value:e,name:this.translate.instant(this.translation.get(e))})}onConfigurationSet(e){this.copyKeysConfigForm=this.fb.group({copyFrom:[e.copyFrom,[O.required]],keys:[e?e.keys:null,[O.required]]})}configForm(){return this.copyKeysConfigForm}prepareInputConfig(e){let t;return t=ie(e?.fromMetadata)?e.copyFrom?en.METADATA:en.DATA:ie(e?.copyFrom)?e.copyFrom:en.DATA,{keys:ie(e?.keys)?e.keys:null,copyFrom:t}}}e("CopyKeysConfigComponent",Gr),Gr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Gr,deps:[{token:P.Store},{token:R.FormBuilder},{token:Z.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Gr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Gr,selector:"tb-transformation-node-copy-keys-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n help\n \n \n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"component",type:Ze.StringItemsListComponent,selector:"tb-string-items-list",inputs:["required","disabled","label","placeholder","hint","requiredText","floatLabel","appearance","editable","subscriptSizing","predefinedValues"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:Y.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:On,selector:"tb-msg-metadata-chip",inputs:["labelText","translation"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Gr,decorators:[{type:n,args:[{selector:"tb-transformation-node-copy-keys-config",template:'
\n \n \n \n \n help\n \n \n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder},{type:Z.TranslateService}]}});class Dr extends f{constructor(e,t,n){super(e),this.store=e,this.fb=t,this.translate=n,this.renameIn=[],this.translation=rn;for(const e of this.translation.keys())this.renameIn.push({value:e,name:this.translate.instant(this.translation.get(e))})}configForm(){return this.renameKeysConfigForm}onConfigurationSet(e){this.renameKeysConfigForm=this.fb.group({renameIn:[e?e.renameIn:null,[O.required]],renameKeysMapping:[e?e.renameKeysMapping:null,[O.required]]})}prepareInputConfig(e){let t;return t=ie(e?.fromMetadata)?e.fromMetadata?en.METADATA:en.DATA:ie(e?.renameIn)?e?.renameIn:en.DATA,{renameKeysMapping:ie(e?.renameKeysMapping)?e.renameKeysMapping:null,renameIn:t}}}e("RenameKeysConfigComponent",Dr),Dr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Dr,deps:[{token:P.Store},{token:R.FormBuilder},{token:Z.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Dr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Dr,selector:"tb-transformation-node-rename-keys-config",usesInheritance:!0,ngImport:t,template:'
\n
tb.rulenode.rename-keys-in
\n
\n
\n \n \n {{ data.name }}\n \n \n
\n
\n \n \n
\n',styles:[":host .fetch-to-data-toggle{max-width:420px;width:100%}:host .fx-centered{display:flex;width:100%;justify-content:space-around}\n"],dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"directive",type:Xe.ToggleOption,selector:"tb-toggle-option",inputs:["value"]},{kind:"component",type:et.ToggleSelectComponent,selector:"tb-toggle-select",inputs:["disabled","selectMediaBreakpoint","appearance","disablePagination"]},{kind:"component",type:Sn,selector:"tb-kv-map-config",inputs:["disabled","uniqueKeyValuePairValidator","labelText","requiredText","keyText","keyRequiredText","valText","valRequiredText","hintText","popupHelpLink","required"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Dr,decorators:[{type:n,args:[{selector:"tb-transformation-node-rename-keys-config",template:'
\n
tb.rulenode.rename-keys-in
\n
\n
\n \n \n {{ data.name }}\n \n \n
\n
\n \n \n
\n',styles:[":host .fetch-to-data-toggle{max-width:420px;width:100%}:host .fx-centered{display:flex;width:100%;justify-content:space-around}\n"]}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder},{type:Z.TranslateService}]}});class wr extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.jsonPathConfigForm}onConfigurationSet(e){this.jsonPathConfigForm=this.fb.group({jsonPath:[e?e.jsonPath:null,[O.required]]})}}e("NodeJsonPathConfigComponent",wr),wr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:wr,deps:[{token:P.Store},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),wr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:wr,selector:"tb-transformation-node-json-path-config",usesInheritance:!0,ngImport:t,template:"
\n \n {{ 'tb.rulenode.json-path-expression' | translate }}\n \n {{ 'tb.rulenode.json-path-expression-hint' | translate }}\n {{ 'tb.rulenode.json-path-expression-required' | translate }}\n \n
\n",dependencies:[{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatHint,selector:"mat-hint",inputs:["align","id"]},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:wr,decorators:[{type:n,args:[{selector:"tb-transformation-node-json-path-config",template:"
\n \n {{ 'tb.rulenode.json-path-expression' | translate }}\n \n {{ 'tb.rulenode.json-path-expression-hint' | translate }}\n {{ 'tb.rulenode.json-path-expression-required' | translate }}\n \n
\n"}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder}]}});class Vr extends f{constructor(e,t,n){super(e),this.store=e,this.fb=t,this.translate=n,this.deleteFrom=[],this.translation=nn;for(const e of this.translation.keys())this.deleteFrom.push({value:e,name:this.translate.instant(this.translation.get(e))})}onConfigurationSet(e){this.deleteKeysConfigForm=this.fb.group({deleteFrom:[e.deleteFrom,[O.required]],keys:[e?e.keys:null,[O.required]]})}prepareInputConfig(e){let t;return t=ie(e?.fromMetadata)?e.fromMetadata?en.METADATA:en.DATA:ie(e?.deleteFrom)?e?.deleteFrom:en.DATA,{keys:ie(e?.keys)?e.keys:null,deleteFrom:t}}configForm(){return this.deleteKeysConfigForm}}e("DeleteKeysConfigComponent",Vr),Vr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Vr,deps:[{token:P.Store},{token:R.FormBuilder},{token:Z.TranslateService}],target:t.ɵɵFactoryTarget.Component}),Vr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Vr,selector:"tb-transformation-node-delete-keys-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n \n \n help\n \n \n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n'],dependencies:[{kind:"component",type:Ze.StringItemsListComponent,selector:"tb-string-items-list",inputs:["required","disabled","label","placeholder","hint","requiredText","floatLabel","appearance","editable","subscriptSizing","predefinedValues"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:Y.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"component",type:On,selector:"tb-msg-metadata-chip",inputs:["labelText","translation"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Vr,decorators:[{type:n,args:[{selector:"tb-transformation-node-delete-keys-config",template:'
\n \n \n \n \n help\n \n \n
\n',styles:[':host .margin-8{margin:8px}:host .tb-error{letter-spacing:.25px;color:var(--mdc-theme-error, #f44336)}:host .tb-required:after{content:"*";font-size:16px;color:#000000de}.same-width-component-row{display:flex;flex-wrap:nowrap;gap:16px}@media screen and (max-width: 599px){.same-width-component-row{gap:8px}}.same-width-component-row>*{flex:1}\n']}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder},{type:Z.TranslateService}]}});class Pr extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.deduplicationStrategie=Gt,this.deduplicationStrategies=Object.keys(this.deduplicationStrategie),this.deduplicationStrategiesTranslations=Dt}configForm(){return this.deduplicationConfigForm}onConfigurationSet(e){this.deduplicationConfigForm=this.fb.group({interval:[ie(e?.interval)?e.interval:null,[O.required,O.min(1)]],strategy:[ie(e?.strategy)?e.strategy:null,[O.required]],outMsgType:[ie(e?.outMsgType)?e.outMsgType:null,[O.required]],maxPendingMsgs:[ie(e?.maxPendingMsgs)?e.maxPendingMsgs:null,[O.required,O.min(1),O.max(1e3)]],maxRetries:[ie(e?.maxRetries)?e.maxRetries:null,[O.required,O.min(0),O.max(100)]]})}prepareInputConfig(e){return e||(e={}),e.outMsgType||(e.outMsgType="POST_TELEMETRY_REQUEST"),super.prepareInputConfig(e)}updateValidators(e){this.deduplicationConfigForm.get("strategy").value===this.deduplicationStrategie.ALL?this.deduplicationConfigForm.get("outMsgType").enable({emitEvent:!1}):this.deduplicationConfigForm.get("outMsgType").disable({emitEvent:!1}),this.deduplicationConfigForm.get("outMsgType").updateValueAndValidity({emitEvent:e})}validatorTriggers(){return["strategy"]}}e("DeduplicationConfigComponent",Pr),Pr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Pr,deps:[{token:P.Store},{token:R.FormBuilder}],target:t.ɵɵFactoryTarget.Component}),Pr.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Pr,selector:"tb-action-node-msg-deduplication-config",usesInheritance:!0,ngImport:t,template:'
\n \n {{\'tb.rulenode.interval\' | translate}}\n \n \n {{\'tb.rulenode.interval-required\' | translate}}\n \n \n {{\'tb.rulenode.interval-min-error\' | translate}}\n \n help\n \n
\n
\n
tb.rulenode.strategy
\n \n \n {{ deduplicationStrategiesTranslations.get(strategy) | translate }}\n \n \n \n \n \n \n \n \n
\n \n \n
\n
\n
\n \n \n tb.rulenode.advanced-settings\n \n
\n \n {{\'tb.rulenode.max-pending-msgs\' | translate}}\n \n \n {{\'tb.rulenode.max-pending-msgs-required\' | translate}}\n \n \n {{\'tb.rulenode.max-pending-msgs-max-error\' | translate}}\n \n \n {{\'tb.rulenode.max-pending-msgs-min-error\' | translate}}\n \n help\n \n \n {{\'tb.rulenode.max-retries\' | translate}}\n \n \n {{\'tb.rulenode.max-retries-required\' | translate}}\n \n \n {{\'tb.rulenode.max-retries-max-error\' | translate}}\n \n \n {{\'tb.rulenode.max-retries-min-error\' | translate}}\n \n help\n \n
\n
\n
\n
\n
\n',dependencies:[{kind:"directive",type:H.NgForOf,selector:"[ngFor][ngForOf]",inputs:["ngForOf","ngForTrackBy","ngForTemplate"]},{kind:"directive",type:H.NgIf,selector:"[ngIf]",inputs:["ngIf","ngIfThen","ngIfElse"]},{kind:"component",type:ue.MatIcon,selector:"mat-icon",inputs:["color","inline","svgIcon","fontSet","fontIcon"],exportAs:["matIcon"]},{kind:"directive",type:J.MatInput,selector:"input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",inputs:["disabled","id","placeholder","name","required","type","errorStateMatcher","aria-describedby","value","readonly"],exportAs:["matInput"]},{kind:"component",type:Y.MatFormField,selector:"mat-form-field",inputs:["hideRequiredMarker","color","floatLabel","appearance","subscriptSizing","hintLabel"],exportAs:["matFormField"]},{kind:"directive",type:Y.MatLabel,selector:"mat-label"},{kind:"directive",type:Y.MatError,selector:"mat-error, [matError]",inputs:["id"]},{kind:"directive",type:Y.MatSuffix,selector:"[matSuffix], [matIconSuffix], [matTextSuffix]",inputs:["matTextSuffix"]},{kind:"directive",type:ce.MatTooltip,selector:"[matTooltip]",exportAs:["matTooltip"]},{kind:"component",type:Je.MatExpansionPanel,selector:"mat-expansion-panel",inputs:["disabled","expanded","hideToggle","togglePosition"],outputs:["opened","closed","expandedChange","afterExpand","afterCollapse"],exportAs:["matExpansionPanel"]},{kind:"component",type:Je.MatExpansionPanelHeader,selector:"mat-expansion-panel-header",inputs:["tabIndex","expandedHeight","collapsedHeight"]},{kind:"directive",type:Je.MatExpansionPanelTitle,selector:"mat-panel-title"},{kind:"directive",type:R.DefaultValueAccessor,selector:"input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]"},{kind:"directive",type:R.NumberValueAccessor,selector:"input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]"},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]},{kind:"directive",type:Z.TranslateDirective,selector:"[translate],[ngx-translate]",inputs:["translate","translateParams"]},{kind:"directive",type:Xe.ToggleOption,selector:"tb-toggle-option",inputs:["value"]},{kind:"component",type:et.ToggleSelectComponent,selector:"tb-toggle-select",inputs:["disabled","selectMediaBreakpoint","appearance","disablePagination"]},{kind:"component",type:Rn,selector:"tb-output-message-type-autocomplete",inputs:["subscriptSizing","disabled","required"]},{kind:"component",type:Nn,selector:"tb-example-hint",inputs:["hintText","popupHelpLink","textAlign"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Pr,decorators:[{type:n,args:[{selector:"tb-action-node-msg-deduplication-config",template:'
\n \n {{\'tb.rulenode.interval\' | translate}}\n \n \n {{\'tb.rulenode.interval-required\' | translate}}\n \n \n {{\'tb.rulenode.interval-min-error\' | translate}}\n \n help\n \n
\n
\n
tb.rulenode.strategy
\n \n \n {{ deduplicationStrategiesTranslations.get(strategy) | translate }}\n \n \n \n \n \n \n \n \n
\n \n \n
\n
\n
\n \n \n tb.rulenode.advanced-settings\n \n
\n \n {{\'tb.rulenode.max-pending-msgs\' | translate}}\n \n \n {{\'tb.rulenode.max-pending-msgs-required\' | translate}}\n \n \n {{\'tb.rulenode.max-pending-msgs-max-error\' | translate}}\n \n \n {{\'tb.rulenode.max-pending-msgs-min-error\' | translate}}\n \n help\n \n \n {{\'tb.rulenode.max-retries\' | translate}}\n \n \n {{\'tb.rulenode.max-retries-required\' | translate}}\n \n \n {{\'tb.rulenode.max-retries-max-error\' | translate}}\n \n \n {{\'tb.rulenode.max-retries-min-error\' | translate}}\n \n help\n \n
\n
\n
\n
\n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.FormBuilder}]}});class Rr{}e("RulenodeCoreConfigTransformModule",Rr),Rr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Rr,deps:[],target:t.ɵɵFactoryTarget.NgModule}),Rr.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.10",ngImport:t,type:Rr,declarations:[Tr,Ir,Er,Gr,Dr,wr,Vr,Pr],imports:[$,M,Un],exports:[Tr,Ir,Er,Gr,Dr,wr,Vr,Pr]}),Rr.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Rr,imports:[$,M,Un]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Rr,decorators:[{type:c,args:[{declarations:[Tr,Ir,Er,Gr,Dr,wr,Vr,Pr],imports:[$,M,Un],exports:[Tr,Ir,Er,Gr,Dr,wr,Vr,Pr]}]}]});class Or extends f{constructor(e,t){super(e),this.store=e,this.fb=t,this.entityType=F}configForm(){return this.ruleChainInputConfigForm}onConfigurationSet(e){this.ruleChainInputConfigForm=this.fb.group({ruleChainId:[e?e.ruleChainId:null,[O.required]]})}}e("RuleChainInputComponent",Or),Or.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Or,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),Or.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:Or,selector:"tb-flow-node-rule-chain-input-config",usesInheritance:!0,ngImport:t,template:'
\n \n \n
\n',dependencies:[{kind:"component",type:lt.EntityAutocompleteComponent,selector:"tb-entity-autocomplete",inputs:["entityType","entitySubtype","excludeEntityIds","labelText","requiredText","useFullEntityId","appearance","required","disabled"],outputs:["entityChanged"]},{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:R.NgControlStatus,selector:"[formControlName],[ngModel],[formControl]"},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.RequiredValidator,selector:":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",inputs:["required"]},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"directive",type:R.FormControlName,selector:"[formControlName]",inputs:["formControlName","disabled","ngModel"],outputs:["ngModelChange"]}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Or,decorators:[{type:n,args:[{selector:"tb-flow-node-rule-chain-input-config",template:'
\n \n \n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class _r extends f{constructor(e,t){super(e),this.store=e,this.fb=t}configForm(){return this.ruleChainOutputConfigForm}onConfigurationSet(e){this.ruleChainOutputConfigForm=this.fb.group({})}}e("RuleChainOutputComponent",_r),_r.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:_r,deps:[{token:P.Store},{token:R.UntypedFormBuilder}],target:t.ɵɵFactoryTarget.Component}),_r.ɵcmp=t.ɵɵngDeclareComponent({minVersion:"14.0.0",version:"15.2.10",type:_r,selector:"tb-flow-node-rule-chain-output-config",usesInheritance:!0,ngImport:t,template:'
\n
\n
\n',dependencies:[{kind:"directive",type:W.DefaultLayoutDirective,selector:" [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]",inputs:["fxLayout","fxLayout.xs","fxLayout.sm","fxLayout.md","fxLayout.lg","fxLayout.xl","fxLayout.lt-sm","fxLayout.lt-md","fxLayout.lt-lg","fxLayout.lt-xl","fxLayout.gt-xs","fxLayout.gt-sm","fxLayout.gt-md","fxLayout.gt-lg"]},{kind:"directive",type:R.NgControlStatusGroup,selector:"[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]"},{kind:"directive",type:R.FormGroupDirective,selector:"[formGroup]",inputs:["formGroup"],outputs:["ngSubmit"],exportAs:["ngForm"]},{kind:"pipe",type:Z.TranslatePipe,name:"translate"}]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:_r,decorators:[{type:n,args:[{selector:"tb-flow-node-rule-chain-output-config",template:'
\n
\n
\n'}]}],ctorParameters:function(){return[{type:P.Store},{type:R.UntypedFormBuilder}]}});class Br{}e("RuleNodeCoreConfigFlowModule",Br),Br.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Br,deps:[],target:t.ɵɵFactoryTarget.NgModule}),Br.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.10",ngImport:t,type:Br,declarations:[Or,_r],imports:[$,M,Un],exports:[Or,_r]}),Br.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Br,imports:[$,M,Un]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Br,decorators:[{type:c,args:[{declarations:[Or,_r],imports:[$,M,Un],exports:[Or,_r]}]}]});class Kr{constructor(e){!function(e){e.setTranslation("en_US",{tb:{rulenode:{id:"Id","additional-info":"Additional Info","advanced-settings":"Advanced settings","create-entity-if-not-exists":"Create new entity if not exists","create-entity-if-not-exists-hint":"Create a new entity set above if it does not exist.","entity-name-pattern":"Name pattern","entity-name-pattern-required":"Name pattern is required","entity-name-pattern-hint":"Name pattern field support templatization. Use $[messageKey] to extract value from the message and ${metadataKey} to extract value from the metadata.","copy-message-type":"Copy message type","entity-type-pattern":"Type pattern","entity-type-pattern-required":"Type pattern is required","message-type-value":"Message type value","message-type-value-required":"Message type value is required","message-type-value-max-length":"Message type value should be less than 256","output-message-type":"Output message type","entity-cache-expiration":"Entities cache expiration time (sec)","entity-cache-expiration-hint":"Specifies maximum time interval allowed to store found entity records. 0 value means that records will never expire.","entity-cache-expiration-required":"Entities cache expiration time is required.","entity-cache-expiration-range":"Entities cache expiration time should be greater than or equal to 0.","customer-name-pattern":"Customer name pattern","customer-name-pattern-required":"Customer name pattern is required","create-customer-if-not-exists":"Create new customer if not exists","customer-cache-expiration":"Customers cache expiration time (sec)","customer-cache-expiration-hint":"Specifies maximum time interval allowed to store found customer records. 0 value means that records will never expire.","customer-cache-expiration-required":"Customers cache expiration time is required.","customer-cache-expiration-range":"Customers cache expiration time should be greater than or equal to 0.","interval-start":"Interval start","interval-end":"Interval end","time-unit":"Time unit","fetch-mode":"Fetch mode","order-by-timestamp":"Order by timestamp",limit:"Limit","limit-hint":"Min limit value is 2, max - 1000. If you want to fetch a single entry, select fetch mode 'First' or 'Last'.","limit-required":"Limit is required.","limit-range":"Limit should be in a range from 2 to 1000.","time-unit-milliseconds":"Milliseconds","time-unit-seconds":"Seconds","time-unit-minutes":"Minutes","time-unit-hours":"Hours","time-unit-days":"Days","time-value-range":"Allowing range from 1 to 2147483647.","start-interval-value-required":"Interval start is required.","end-interval-value-required":"Interval end is required.",filter:"Filter",switch:"Switch","math-templatization-tooltip":"This field support templatization. Use $[messageKey] to extract value from the message and ${metadataKey} to extract value from the metadata.","add-message-type":"Add message type","select-message-types-required":"At least one message type should be selected.","select-message-types":"Select message types","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","attributes-keys":"Attributes keys","attributes-keys-required":"Attributes keys are required","notify-device":"Force notification to the device","send-attributes-updated-notification":"Send attributes updated notification","send-attributes-updated-notification-hint":"Send notification about updated attributes as a separate message to the rule engine queue.","send-attributes-deleted-notification":"Send attributes deleted notification","send-attributes-deleted-notification-hint":"Send notification about deleted attributes as a separate message to the rule engine queue.","update-attributes-only-on-value-change":"Save attributes only if the value changes","update-attributes-only-on-value-change-hint":"Updates the attributes on every incoming message disregarding if their value has changed. Increases API usage and reduces performance.","update-attributes-only-on-value-change-hint-enabled":"Updates the attributes only if their value has changed. If the value is not changed, no update to the attribute timestamp nor attribute change notification will be sent.","fetch-credentials-to-metadata":"Fetch credentials to metadata","notify-device-on-update-hint":"If enabled, force notification to the device about shared attributes update. If disabled, the notification behavior is controlled by the 'notifyDevice' parameter from the incoming message metadata. To turn off the notification, the message metadata must contain the 'notifyDevice' parameter set to 'false'. Any other case will trigger the notification to the device.","notify-device-on-delete-hint":"If enabled, force notification to the device about shared attributes removal. If disabled, the notification behavior is controlled by the 'notifyDevice' parameter from the incoming message metadata. To turn on the notification, the message metadata must contain the 'notifyDevice' parameter set to 'true'. In any other case, the notification will not be triggered to the device.","latest-timeseries":"Latest time-series data keys","timeseries-keys":"Timeseries keys","timeseries-keys-required":"At least one timeseries key should be selected.","add-timeseries-key":"Add timeseries key","add-message-field":"Add message field","relation-search-parameters":"Relation search parameters","add-metadata-field":"Add metadata field","data-keys":"Message field names","copy-from":"Copy from","data-to-metadata":"Data to metadata","metadata-to-data":"Metadata to data","use-regular-expression-hint":"Use regular expression to copy keys by pattern.\n\nTips & tricks:\nPress 'Enter' to complete field name input.\nPress 'Backspace' to delete field name. Multiple field names supported.",interval:"Interval","interval-required":"Interval is required","interval-hint":"Deduplication interval in seconds.","interval-min-error":"Min allowed value is 1","max-pending-msgs":"Max pending messages","max-pending-msgs-hint":"Maximum number of messages that are stored in memory for each unique deduplication id.","max-pending-msgs-required":"Max pending messages is required","max-pending-msgs-max-error":"Max allowed value is 1000","max-pending-msgs-min-error":"Min allowed value is 1","max-retries":"Max retries","max-retries-required":"Max retries is required","max-retries-hint":"Maximum number of retries to push the deduplicated messages into the queue. 10 seconds delay is used between retries","max-retries-max-error":"Max allowed value is 100","max-retries-min-error":"Min allowed value is 0",strategy:"Strategy","strategy-required":"Strategy is required","strategy-all-hint":"Return all messages that arrived during deduplication period as a single JSON array message. Where each element represents object with msg and metadata inner properties.","strategy-first-hint":"Return first message that arrived during deduplication period.","strategy-last-hint":"Return last message that arrived during deduplication period.",first:"First",last:"Last",all:"All","output-msg-type-hint":"The message type of the deduplication result.","queue-name-hint":"The queue name where the deduplication result will be published.",keys:"Keys","keys-required":"Keys are required","rename-keys-in":"Rename keys in",data:"Data",message:"Message",metadata:"Metadata","current-key-name":"Current key name","key-name-required":"Key name is required","new-key-name":"New key name","new-key-name-required":"New key name is required","metadata-keys":"Metadata field names","json-path-expression":"JSON path expression","json-path-expression-required":"JSON path expression is required","json-path-expression-hint":"JSONPath specifies a path to an element or a set of elements in a JSON structure. '$' represents the root object or array.","relations-query":"Relations query","device-relations-query":"Device relations query","max-relation-level":"Max relation level","max-relation-level-error":"Value should be greater than 0 or unspecified.","relation-type":"Relation type","relation-type-pattern":"Relation type pattern","relation-type-pattern-required":"Relation type pattern is required","relation-types-list":"Relation types to propagate","relation-types-list-hint":"If Propagate relation types are not selected, alarms will be propagated without filtering by relation type.","unlimited-level":"Unlimited level","latest-telemetry":"Latest telemetry","add-telemetry-key":"Add telemetry key","delete-from":"Delete from","use-regular-expression-delete-hint":"Use regular expression to delete keys by pattern.\n\nTips & tricks:\nPress 'Enter' to complete field name input.\nPress 'Backspace' to delete field name.\nMultiple field names supported.","fetch-into":"Fetch into","attr-mapping":"Attributes mapping:","source-attribute":"Source attribute key","source-attribute-required":"Source attribute key is required.","source-telemetry":"Source telemetry key","source-telemetry-required":"Source telemetry key is required.","target-key":"Target key","target-key-required":"Target key is required.","attr-mapping-required":"At least one mapping entry should be specified.","fields-mapping":"Fields mapping","relations-query-config-direction-suffix":"originator","profile-name":"Profile name","fetch-circle-parameter-info-from-metadata-hint":'Metadata field \'{{perimeterKeyName}}\' should be defined in next format: {"latitude":48.196, "longitude":24.6532, "radius":100.0, "radiusUnit":"METER"}',"fetch-poligon-parameter-info-from-metadata-hint":"Metadata field '{{perimeterKeyName}}' should be defined in next format: [[48.19736,24.65235],[48.19800,24.65060],...,[48.19849,24.65420]]","short-templatization-tooltip":"Use $[messageKey] to extract value from the message and ${metadataKey} to extract value from the metadata.","fields-mapping-required":"At least one field mapping should be specified.","at-least-one-field-required":"At least one input field must have a value(s) provided.","originator-fields-sv-map-hint":"Target key fields support templatization. Use $[messageKey] to extract value from the message and ${metadataKey} to extract value from the metadata.","sv-map-hint":"Only target key fields support templatization. Use $[messageKey] to extract value from the message and ${metadataKey} to extract value from the metadata.","source-field":"Source field","source-field-required":"Source field is required.","originator-source":"Originator source","new-originator":"New originator","originator-customer":"Customer","originator-tenant":"Tenant","originator-related":"Related entity","originator-alarm-originator":"Alarm Originator","originator-entity":"Entity by name pattern","clone-message":"Clone message",transform:"Transform","default-ttl":"Default TTL in seconds","default-ttl-required":"Default TTL is required.","min-default-ttl-message":"Only 0 minimum TTL is allowed.","message-count":"Message count (0 - unlimited)","message-count-required":"Message count is required.","min-message-count-message":"Only 0 minimum message count is allowed.","period-seconds":"Period in seconds","period-seconds-required":"Period is required.","use-metadata-period-in-seconds-patterns":"Use period in seconds pattern","use-metadata-period-in-seconds-patterns-hint":"If selected, rule node use period in seconds interval pattern from message metadata or data assuming that intervals are in the seconds.","period-in-seconds-pattern":"Period in seconds pattern","period-in-seconds-pattern-required":"Period in seconds pattern is required","min-period-seconds-message":"Only 1 second minimum period is allowed.",originator:"Originator","message-body":"Message body","message-metadata":"Message metadata",generate:"Generate","test-generator-function":"Test generator function",generator:"Generator","test-filter-function":"Test filter function","test-switch-function":"Test switch function","test-transformer-function":"Test transformer function",transformer:"Transformer","alarm-create-condition":"Alarm create condition","test-condition-function":"Test condition function","alarm-clear-condition":"Alarm clear condition","alarm-details-builder":"Alarm details builder","test-details-function":"Test details function","alarm-type":"Alarm type","select-entity-types":"Select entity types","alarm-type-required":"Alarm type is required.","alarm-severity":"Alarm severity","alarm-severity-required":"Alarm severity is required","alarm-severity-pattern":"Alarm severity pattern","alarm-status-filter":"Alarm status filter","alarm-status-list-empty":"Alarm status list is empty","no-alarm-status-matching":"No alarm status matching were found.",propagate:"Propagate alarm to related entities","propagate-to-owner":"Propagate alarm to entity owner (Customer or Tenant)","propagate-to-tenant":"Propagate alarm to Tenant",condition:"Condition",details:"Details","to-string":"To string","test-to-string-function":"Test to string function","from-template":"From","from-template-required":"From is required","message-to-metadata":"Message to metadata","metadata-to-message":"Metadata to message","from-message":"From message","from-metadata":"From metadata","to-template":"To","to-template-required":"To Template is required","mail-address-list-template-hint":'Comma separated address list, use ${metadataKey} for value from metadata, $[messageKey] for value from message body',"cc-template":"Cc","bcc-template":"Bcc","subject-template":"Subject","subject-template-required":"Subject Template is required","body-template":"Body","body-template-required":"Body Template is required","dynamic-mail-body-type":"Dynamic mail body type","mail-body-type":"Mail body type","body-type-template":"Body type template","request-id-metadata-attribute":"Request Id Metadata attribute name","timeout-sec":"Timeout in seconds","timeout-required":"Timeout is required","min-timeout-message":"Only 0 minimum timeout value is allowed.","endpoint-url-pattern":"Endpoint URL pattern","endpoint-url-pattern-required":"Endpoint URL pattern is required","request-method":"Request method","use-simple-client-http-factory":"Use simple client HTTP factory","ignore-request-body":"Without request body","parse-to-plain-text":"Parse to plain text","parse-to-plain-text-hint":'If selected, request body message payload will be transformed from JSON string to plain text, e.g. msg = "Hello,\\t\\"world\\"" will be parsed to Hello, "world"',"read-timeout":"Read timeout in millis","read-timeout-hint":"The value of 0 means an infinite timeout","max-parallel-requests-count":"Max number of parallel requests","max-parallel-requests-count-hint":"The value of 0 specifies no limit in parallel processing",headers:"Headers","headers-hint":'Use ${metadataKey} for value from metadata, $[messageKey] for value from message body in header/value fields',header:"Header","header-required":"Header is required",value:"Value","value-required":"Value is required","topic-pattern":"Topic pattern","key-pattern":"Key pattern","key-pattern-hint":"Optional. If a valid partition number is specified, it will be used when sending the record. If no partition is specified, the key will be used instead. If neither is specified, a partition will be assigned in a round-robin fashion.","topic-pattern-required":"Topic pattern is required",topic:"Topic","topic-required":"Topic is required","bootstrap-servers":"Bootstrap servers","bootstrap-servers-required":"Bootstrap servers value is required","other-properties":"Other properties",key:"Key","key-required":"Key is required",retries:"Automatically retry times if fails","min-retries-message":"Only 0 minimum retries is allowed.","batch-size-bytes":"Produces batch size in bytes","min-batch-size-bytes-message":"Only 0 minimum batch size is allowed.","linger-ms":"Time to buffer locally (ms)","min-linger-ms-message":"Only 0 ms minimum value is allowed.","buffer-memory-bytes":"Client buffer max size in bytes","min-buffer-memory-message":"Only 0 minimum buffer size is allowed.",acks:"Number of acknowledgments","key-serializer":"Key serializer","key-serializer-required":"Key serializer is required","value-serializer":"Value serializer","value-serializer-required":"Value serializer is required","topic-arn-pattern":"Topic ARN pattern","topic-arn-pattern-required":"Topic ARN pattern is required","aws-access-key-id":"AWS Access Key ID","aws-access-key-id-required":"AWS Access Key ID is required","aws-secret-access-key":"AWS Secret Access Key","aws-secret-access-key-required":"AWS Secret Access Key is required","aws-region":"AWS Region","aws-region-required":"AWS Region is required","exchange-name-pattern":"Exchange name pattern","routing-key-pattern":"Routing key pattern","message-properties":"Message properties",host:"Host","host-required":"Host is required",port:"Port","port-required":"Port is required","port-range":"Port should be in a range from 1 to 65535.","virtual-host":"Virtual host",username:"Username",password:"Password","automatic-recovery":"Automatic recovery","connection-timeout-ms":"Connection timeout (ms)","min-connection-timeout-ms-message":"Only 0 ms minimum value is allowed.","handshake-timeout-ms":"Handshake timeout (ms)","min-handshake-timeout-ms-message":"Only 0 ms minimum value is allowed.","client-properties":"Client properties","queue-url-pattern":"Queue URL pattern","queue-url-pattern-required":"Queue URL pattern is required","delay-seconds":"Delay (seconds)","min-delay-seconds-message":"Only 0 seconds minimum value is allowed.","max-delay-seconds-message":"Only 900 seconds maximum value is allowed.",name:"Name","name-required":"Name is required","queue-type":"Queue type","sqs-queue-standard":"Standard","sqs-queue-fifo":"FIFO","gcp-project-id":"GCP project ID","gcp-project-id-required":"GCP project ID is required","gcp-service-account-key":"GCP service account key file","gcp-service-account-key-required":"GCP service account key file is required","pubsub-topic-name":"Topic name","pubsub-topic-name-required":"Topic name is required","message-attributes":"Message attributes","message-attributes-hint":'Use ${metadataKey} for value from metadata, $[messageKey] for value from message body in name/value fields',"connect-timeout":"Connection timeout (sec)","connect-timeout-required":"Connection timeout is required.","connect-timeout-range":"Connection timeout should be in a range from 1 to 200.","client-id":"Client ID","client-id-hint":'Optional. Leave empty for auto-generated Client ID. Be careful when specifying the Client ID. Majority of the MQTT brokers will not allow multiple connections with the same Client ID. To connect to such brokers, your mqtt Client ID must be unique. When platform is running in a micro-services mode, the copy of rule node is launched in each micro-service. This will automatically lead to multiple mqtt clients with the same ID and may cause failures of the rule node. To avoid such failures enable "Add Service ID as suffix to Client ID" option below.',"append-client-id-suffix":"Add Service ID as suffix to Client ID","client-id-suffix-hint":'Optional. Applied when "Client ID" specified explicitly. If selected then Service ID will be added to Client ID as a suffix. Helps to avoid failures when platform is running in a micro-services mode.',"device-id":"Device ID","device-id-required":"Device ID is required.","clean-session":"Clean session","enable-ssl":"Enable SSL",credentials:"Credentials","credentials-type":"Credentials type","credentials-type-required":"Credentials type is required.","credentials-anonymous":"Anonymous","credentials-basic":"Basic","credentials-pem":"PEM","credentials-pem-hint":"At least Server CA certificate file or a pair of Client certificate and Client private key files are required","credentials-sas":"Shared Access Signature","sas-key":"SAS Key","sas-key-required":"SAS Key is required.",hostname:"Hostname","hostname-required":"Hostname is required.","azure-ca-cert":"CA certificate file","username-required":"Username is required.","password-required":"Password is required.","ca-cert":"Server CA certificate file","private-key":"Client private key file",cert:"Client certificate file","no-file":"No file selected.","drop-file":"Drop a file or click to select a file to upload.","private-key-password":"Private key password","use-system-smtp-settings":"Use system SMTP settings","use-metadata-dynamic-interval":"Use dynamic interval","metadata-dynamic-interval-hint":"Interval start and end input fields support templatization. Note that the substituted template value should be set in milliseconds. Use $[messageKey] to extract value from the message and ${metadataKey} to extract value from the metadata.","use-metadata-interval-patterns-hint":"If selected, rule node use start and end interval patterns from message metadata or data assuming that intervals are in the milliseconds.","use-message-alarm-data":"Use message alarm data","overwrite-alarm-details":"Overwrite alarm details","use-alarm-severity-pattern":"Use alarm severity pattern","check-all-keys":"Check that all specified fields are present","check-all-keys-hint":"If selected, checks that all specified keys are present in the message data and metadata.","check-relation-to-specific-entity":"Check relation to specific entity","check-relation-to-specific-entity-tooltip":"If enabled, checks the presence of relation with a specific entity otherwise, checks the presence of relation with any entity. In both cases, relation lookup is based on configured direction and type.","check-relation-hint":"Checks existence of relation to specific entity or to any entity based on direction and relation type.","delete-relation-to-specific-entity":"Delete relation to specific entity","delete-relation-hint":"Deletes relation from the originator of the incoming message to the specified entity or list of entities based on direction and type.","remove-current-relations":"Remove current relations","remove-current-relations-hint":"Removes current relations from the originator of the incoming message based on direction and type.","change-originator-to-related-entity":"Change originator to related entity","change-originator-to-related-entity-hint":"Used to process submitted message as a message from another entity.","start-interval":"Interval start","end-interval":"Interval end","start-interval-required":"Interval start is required.","end-interval-required":"Interval end is required.","smtp-protocol":"Protocol","smtp-host":"SMTP host","smtp-host-required":"SMTP host is required.","smtp-port":"SMTP port","smtp-port-required":"You must supply a smtp port.","smtp-port-range":"SMTP port should be in a range from 1 to 65535.","timeout-msec":"Timeout ms","min-timeout-msec-message":"Only 0 ms minimum value is allowed.","enter-username":"Enter username","enter-password":"Enter password","enable-tls":"Enable TLS","tls-version":"TLS version","enable-proxy":"Enable proxy","use-system-proxy-properties":"Use system proxy properties","proxy-host":"Proxy host","proxy-host-required":"Proxy host is required.","proxy-port":"Proxy port","proxy-port-required":"Proxy port is required.","proxy-port-range":"Proxy port should be in a range from 1 to 65535.","proxy-user":"Proxy user","proxy-password":"Proxy password","proxy-scheme":"Proxy scheme","numbers-to-template":"Phone Numbers To Template","numbers-to-template-required":"Phone Numbers To Template is required","numbers-to-template-hint":'Comma separated Phone Numbers, use ${metadataKey} for value from metadata, $[messageKey] for value from message body',"sms-message-template":"SMS message Template","sms-message-template-required":"SMS message Template is required","use-system-sms-settings":"Use system SMS provider settings","min-period-0-seconds-message":"Only 0 second minimum period is allowed.","max-pending-messages":"Maximum pending messages","max-pending-messages-required":"Maximum pending messages is required.","max-pending-messages-range":"Maximum pending messages should be in a range from 1 to 100000.","originator-types-filter":"Originator types filter","interval-seconds":"Interval in seconds","interval-seconds-required":"Interval is required.","min-interval-seconds-message":"Only 1 second minimum interval is allowed.","output-timeseries-key-prefix":"Output timeseries key prefix","output-timeseries-key-prefix-required":"Output timeseries key prefix required.","separator-hint":'Press "Enter" to complete field input.',"select-details":"Select details","entity-details-id":"Id","entity-details-title":"Title","entity-details-country":"Country","entity-details-state":"State","entity-details-city":"City","entity-details-zip":"Zip","entity-details-address":"Address","entity-details-address2":"Address2","entity-details-additional_info":"Additional Info","entity-details-phone":"Phone","entity-details-email":"Email","email-sender":"Email sender","fields-to-check":"Fields to check","add-detail":"Add detail","check-all-keys-tooltip":"If enabled, checks the presence of all fields listed in the message and metadata field names within the incoming message and its metadata.","fields-to-check-hint":'Press "Enter" to complete field name input. Multiple field names supported.',"entity-details-list-empty":"At least one detail should be selected.","alarm-status":"Alarm status","alarm-required":"At least one alarm status should be selected.","no-entity-details-matching":"No entity details matching were found.","custom-table-name":"Custom table name","custom-table-name-required":"Table Name is required","custom-table-hint":"Enter the table name without prefix 'cs_tb_'.","message-field":"Message field","message-field-required":"Message field is required.","table-col":"Table column","table-col-required":"Table column is required.","latitude-field-name":"Latitude field name","longitude-field-name":"Longitude field name","latitude-field-name-required":"Latitude field name is required.","longitude-field-name-required":"Longitude field name is required.","fetch-perimeter-info-from-metadata":"Fetch perimeter information from metadata","fetch-perimeter-info-from-metadata-tooltip":"If perimeter type is set to 'Polygon' the value of metadata field '{{perimeterKeyName}}' will be set as perimeter definition without additional parsing of the value. Otherwise, if perimeter type is set to 'Circle' the value of '{{perimeterKeyName}}' metadata field will be parsed to extract 'latitude', 'longitude', 'radius', 'radiusUnit' fields that uses for circle perimeter definition.","perimeter-key-name":"Perimeter key name","perimeter-key-name-hint":"Metadata field name that includes perimeter information.","perimeter-key-name-required":"Perimeter key name is required.","perimeter-circle":"Circle","perimeter-polygon":"Polygon","perimeter-type":"Perimeter type","circle-center-latitude":"Center latitude","circle-center-latitude-required":"Center latitude is required.","circle-center-longitude":"Center longitude","circle-center-longitude-required":"Center longitude is required.","range-unit-meter":"Meter","range-unit-kilometer":"Kilometer","range-unit-foot":"Foot","range-unit-mile":"Mile","range-unit-nautical-mile":"Nautical mile","range-units":"Range units","range-units-required":"Range units is required.",range:"Range","range-required":"Range is required.","polygon-definition":"Polygon definition","polygon-definition-required":"Polygon definition is required.","polygon-definition-hint":"Use the following format for manual definition of polygon: [[lat1,lon1],[lat2,lon2], ... ,[latN,lonN]].","min-inside-duration":"Minimal inside duration","min-inside-duration-value-required":"Minimal inside duration is required","min-inside-duration-time-unit":"Minimal inside duration time unit","min-outside-duration":"Minimal outside duration","min-outside-duration-value-required":"Minimal outside duration is required","min-outside-duration-time-unit":"Minimal outside duration time unit","tell-failure-if-absent":"Tell Failure","tell-failure-if-absent-hint":'If at least one selected key doesn\'t exist the outbound message will report "Failure".',"get-latest-value-with-ts":"Fetch timestamp for the latest telemetry values","get-latest-value-with-ts-hint":'If selected, the latest telemetry values will also include timestamp, e.g: "temp": "{"ts":1574329385897, "value":42}"',"use-redis-queue":"Use redis queue for message persistence","ignore-null-strings":"Ignore null strings","ignore-null-strings-hint":"If selected rule node will ignore entity fields with empty value.","trim-redis-queue":"Trim redis queue","redis-queue-max-size":"Redis queue max size","add-metadata-key-values-as-kafka-headers":"Add Message metadata key-value pairs to Kafka record headers","add-metadata-key-values-as-kafka-headers-hint":"If selected, key-value pairs from message metadata will be added to the outgoing records headers as byte arrays with predefined charset encoding.","charset-encoding":"Charset encoding","charset-encoding-required":"Charset encoding is required.","charset-us-ascii":"US-ASCII","charset-iso-8859-1":"ISO-8859-1","charset-utf-8":"UTF-8","charset-utf-16be":"UTF-16BE","charset-utf-16le":"UTF-16LE","charset-utf-16":"UTF-16","select-queue-hint":"The queue name can be selected from a drop-down list or add a custom name.","persist-alarm-rules":"Persist state of alarm rules","fetch-alarm-rules":"Fetch state of alarm rules","input-value-key":"Input value key","input-value-key-required":"Input value key is required.","output-value-key":"Output value key","output-value-key-required":"Output value key is required.","number-of-digits-after-floating-point":"Number of digits after floating point","number-of-digits-after-floating-point-range":"Number of digits after floating point should be in a range from 0 to 15.","failure-if-delta-negative":"Tell Failure if delta is negative","failure-if-delta-negative-tooltip":"Rule node forces failure of message processing if delta value is negative.","use-caching":"Use caching","use-caching-tooltip":'Rule node will cache the value of "{{inputValueKey}}" that arrives from the incoming message to improve performance. Note that the cache will not be updated if you modify the "{{inputValueKey}}" value elsewhere.',"add-time-difference-between-readings":'Add the time difference between "{{inputValueKey}}" readings',"add-time-difference-between-readings-tooltip":'If enabled, the rule node will add the "{{periodValueKey}}" to the outbound message.',"period-value-key":"Period value key","period-value-key-required":"Period value key is required.","general-pattern-hint":"Use ${metadataKey} for value from metadata, $[messageKey] for value from message body.","alarm-severity-pattern-hint":'Use ${metadataKey} for value from metadata, $[messageKey] for value from message body. Alarm severity should be system (CRITICAL, MAJOR etc.)',"output-node-name-hint":"The rule node name corresponds to the relation type of the output message, and it is used to forward messages to other rule nodes in the caller rule chain.","skip-latest-persistence":"Skip latest persistence","use-server-ts":"Use server ts","use-server-ts-hint":"Enable this setting to use the timestamp of the message processing instead of the timestamp from the message. Useful for all sorts of sequential processing if you merge messages from multiple sources (devices, assets, etc).","kv-map-pattern-hint":"All input fields support templatization. Use $[messageKey] to extract value from the message and ${metadataKey} to extract value from the metadata.","shared-scope":"Shared scope","server-scope":"Server scope","client-scope":"Client scope","attribute-type":"Attribute","constant-type":"Constant","time-series-type":"Time-series","message-body-type":"Message","message-metadata-type":"Metadata","argument-tile":"Arguments","no-arguments-prompt":"No arguments configured","result-title":"Result","functions-field-input":"Functions","no-option-found":"No option found","argument-source-field-input":"Source","argument-source-field-input-required":"Argument source is required.","argument-key-field-input":"Key","argument-key-field-input-required":"Argument key is required.","constant-value-field-input":"Constant value","constant-value-field-input-required":"Constant value is required.","attribute-scope-field-input":"Attribute scope","attribute-scope-field-input-required":"Attribute scope os required.","default-value-field-input":"Default value","type-field-input":"Type","type-field-input-required":"Type is required.","key-field-input":"Key","add-entity-type":"Add entity type","add-device-profile":"Add device profile","key-field-input-required":"Key is required.","number-floating-point-field-input":"Number of digits after floating point","number-floating-point-field-input-hint":"Use 0 to convert result to integer","add-to-message-field-input":"Add to message","add-to-metadata-field-input":"Add to metadata","custom-expression-field-input":"Mathematical Expression","custom-expression-field-input-required":"Mathematical expression is required","custom-expression-field-input-hint":"Specify a mathematical expression to evaluate. Default expression demonstrates how to transform Fahrenheit to Celsius","retained-message":"Retained","attributes-mapping":"Attributes mapping","latest-telemetry-mapping":"Latest telemetry mapping","add-mapped-attribute-to":"Add mapped attributes to","add-mapped-latest-telemetry-to":"Add mapped latest telemetry to","add-mapped-fields-to":"Add mapped fields to","add-selected-details-to":"Add selected details to","clear-selected-types":"Clear selected types","clear-selected-details":"Clear selected details","clear-selected-fields":"Clear selected fields","clear-selected-keys":"Clear selected keys","geofence-configuration":"Geofence configuration","coordinate-field-names":"Coordinate field names","coordinate-field-hint":"Rule node tries to retrieve the specified fields from the message. If they are not present, it will look them up in the metadata.","fetch-credentials-to":"Fetch credentials to","add-originator-attributes-to":"Add originator attributes to","originator-attributes":"Originator attributes","fetch-latest-telemetry-with-timestamp":"Fetch latest telemetry with timestamp","fetch-latest-telemetry-with-timestamp-tooltip":'If selected, latest telemetry values will be added to the outbound metadata with timestamp, e.g: "{{latestTsKeyName}}": "{"ts":1574329385897, "value":42}"',"tell-failure":"Tell failure if any of the attributes are missing","tell-failure-tooltip":'If at least one selected key doesn\'t exist the outbound message will report "Failure".',"created-time":"Created time","chip-help":"Press 'Enter' to complete {{inputName}} input. \nPress 'Backspace' to delete {{inputName}}. \nMultiple values supported.",detail:"detail","field-name":"field name","device-profile":"device profile","entity-type":"entity type","message-type":"message type","timeseries-key":"timeseries key",type:"Type","first-name":"First name","last-name":"Last name",label:"Label","originator-fields-mapping":"Originator fields mapping","add-mapped-originator-fields-to":"Add mapped originator fields to",fields:"Fields","skip-empty-fields":"Skip empty fields","skip-empty-fields-tooltip":"Fields with empty values will not be added to the output message/output metadata.","fetch-interval":"Fetch interval","fetch-strategy":"Fetch strategy","fetch-timeseries-from-to":"Fetch timeseries from {{startInterval}} {{startIntervalTimeUnit}} ago to {{endInterval}} {{endIntervalTimeUnit}} ago.","fetch-timeseries-from-to-invalid":'Fetch timeseries invalid ("Interval start" should be less than "Interval end").',"use-metadata-dynamic-interval-tooltip":"If selected, the rule node will use dynamic interval start and end based on the message and metadata patterns.","all-mode-hint":'If selected fetch mode "All" rule node will retrieve telemetry from the fetch interval with configurable query parameters.',"first-mode-hint":'If selected fetch mode "First" rule node will retrieve the closest telemetry to the fetch interval\'s start.',"last-mode-hint":'If selected fetch mode "Last" rule node will retrieve the closest telemetry to the fetch interval\'s end.',ascending:"Ascending",descending:"Descending",min:"Min",max:"Max",average:"Average",sum:"Sum",count:"Count",none:"None","last-level-relation-tooltip":"If selected, the rule node will search related entities only on the level set in the max relation level.","last-level-device-relation-tooltip":"If selected, the rule node will search related devices only on the level set in the max relation level.","data-to-fetch":"Data to fetch","mapping-of-customers":"Mapping of customer's","map-fields-required":"All mapping fields are required.",attributes:"Attributes","related-device-attributes":"Related device attributes","add-selected-attributes-to":"Add selected attributes to","device-profiles":"Device profiles","mapping-of-tenant":"Mapping of tenant's","add-attribute-key":"Add attribute key","message-template":"Message template","message-template-required":"Message template is required","use-system-slack-settings":"Use system slack settings","slack-api-token":"Slack API token","slack-api-token-required":"Slack API token is required","keys-mapping":"keys mapping","add-key":"Add key",recipients:"Recipients","message-subject-and-content":"Message subject and content","template-rules-hint":"Both input fields support templatization. Use $[messageKey] to extract value from the message and ${metadataKey} to extract value from the metadata.","originator-customer-desc":"Use customer of incoming message originator as new originator.","originator-tenant-desc":"Use current tenant as new originator.","originator-related-entity-desc":"Use related entity as new originator. Lookup based on configured relation type and direction.","originator-alarm-originator-desc":"Use alarm originator as new originator. Only if incoming message originator is alarm entity.","originator-entity-by-name-pattern-desc":"Use entity fetched from DB as new originator. Lookup based on entity type and specified name pattern.","email-from-template-hint":"Use $[messageKey] to extract value from the message and ${metadataKey} to extract value from the metadata.","recipients-block-main-hint":"Comma-separated address list. All input fields support templatization. Use $[messageKey] to extract value from the message and ${metadataKey} to extract value from the metadata."},"key-val":{key:"Key",value:"Value","see-examples":"See examples.","remove-entry":"Remove entry","remove-mapping-entry":"Remove mapping entry","add-mapping-entry":"Add mapping","add-entry":"Add entry","copy-key-values-from":"Copy key-values from","delete-key-values":"Delete key-values","delete-key-values-from":"Delete key-values from","at-least-one-key-error":"At least one key should be selected.","unique-key-value-pair-error":"'{{keyText}}' must be different from the '{{valText}}'!"},"mail-body-type":{"plain-text":"Plain text",html:"HTML",dynamic:"Dynamic","use-body-type-template":"Use body type template","plain-text-description":"Simple, unformatted text with no special styling or formating.","html-text-description":"Allows you to use HTML tags for formatting, links and images in your mai body.","dynamic-text-description":"Allows to use Plain Text or HTML body type dynamically based on templatization feature.","after-template-evaluation-hint":"After template evaluation value should be true for HTML, and false for Plain text."}}},!0)}(e)}}e("RuleNodeCoreConfigModule",Kr),Kr.ɵfac=t.ɵɵngDeclareFactory({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Kr,deps:[{token:Z.TranslateService}],target:t.ɵɵFactoryTarget.NgModule}),Kr.ɵmod=t.ɵɵngDeclareNgModule({minVersion:"14.0.0",version:"15.2.10",ngImport:t,type:Kr,declarations:[dt],imports:[$,M],exports:[Hn,Lr,nr,gr,Rr,Br,dt]}),Kr.ɵinj=t.ɵɵngDeclareInjector({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Kr,imports:[$,M,Hn,Lr,nr,gr,Rr,Br]}),t.ɵɵngDeclareClassMetadata({minVersion:"12.0.0",version:"15.2.10",ngImport:t,type:Kr,decorators:[{type:c,args:[{declarations:[dt],imports:[$,M],exports:[Hn,Lr,nr,gr,Rr,Br,dt]}]}],ctorParameters:function(){return[{type:Z.TranslateService}]}})}}}));//# sourceMappingURL=rulenode-core-config.js.map From 3ee8a8c56d10d5a08111032c6d90067d6a538535 Mon Sep 17 00:00:00 2001 From: ViacheslavKlimov Date: Fri, 26 Jan 2024 12:17:37 +0200 Subject: [PATCH 135/179] Refactor rate limit service --- .../config/RateLimitProcessingFilter.java | 2 +- .../server/controller/AuthController.java | 2 +- .../controller/plugin/TbWebSocketHandler.java | 2 +- .../DefaultNotificationCenter.java | 2 +- .../DefaultNotificationRuleProcessor.java | 2 +- .../auth/mfa/DefaultTwoFactorAuthService.java | 2 +- .../DefaultEntitiesExportImportService.java | 2 +- .../service/limits/RateLimitServiceTest.java | 10 ++++---- .../notification/NotificationRuleApiTest.java | 2 +- common/cache/pom.xml | 4 +++ .../limits/DefaultRateLimitService.java | 16 ++++++------ .../cache}/limits/RateLimitService.java | 2 +- .../cache/limits/TenantProfileProvider.java | 25 +++++++++++++++++++ .../CassandraBufferedRateReadExecutor.java | 2 +- .../CassandraBufferedRateWriteExecutor.java | 2 +- .../tenant/DefaultTbTenantProfileCache.java | 3 ++- .../util/AbstractBufferedRateExecutor.java | 2 +- 17 files changed, 55 insertions(+), 27 deletions(-) rename {dao/src/main/java/org/thingsboard/server/dao/util => common/cache/src/main/java/org/thingsboard/server/cache}/limits/DefaultRateLimitService.java (89%) rename {dao/src/main/java/org/thingsboard/server/dao/util => common/cache/src/main/java/org/thingsboard/server/cache}/limits/RateLimitService.java (95%) create mode 100644 common/cache/src/main/java/org/thingsboard/server/cache/limits/TenantProfileProvider.java diff --git a/application/src/main/java/org/thingsboard/server/config/RateLimitProcessingFilter.java b/application/src/main/java/org/thingsboard/server/config/RateLimitProcessingFilter.java index 7791c7ee76..0b859e7b06 100644 --- a/application/src/main/java/org/thingsboard/server/config/RateLimitProcessingFilter.java +++ b/application/src/main/java/org/thingsboard/server/config/RateLimitProcessingFilter.java @@ -26,7 +26,7 @@ import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.exception.TenantProfileNotFoundException; import org.thingsboard.server.common.data.limit.LimitedApi; import org.thingsboard.server.common.msg.tools.TbRateLimitsException; -import org.thingsboard.server.dao.util.limits.RateLimitService; +import org.thingsboard.server.cache.limits.RateLimitService; import org.thingsboard.server.exception.ThingsboardErrorResponseHandler; import org.thingsboard.server.service.security.model.SecurityUser; diff --git a/application/src/main/java/org/thingsboard/server/controller/AuthController.java b/application/src/main/java/org/thingsboard/server/controller/AuthController.java index ba4c2b1fbd..92441bf1cb 100644 --- a/application/src/main/java/org/thingsboard/server/controller/AuthController.java +++ b/application/src/main/java/org/thingsboard/server/controller/AuthController.java @@ -48,7 +48,7 @@ import org.thingsboard.server.common.data.security.event.UserSessionInvalidation import org.thingsboard.server.common.data.security.model.JwtPair; import org.thingsboard.server.common.data.security.model.SecuritySettings; import org.thingsboard.server.common.data.security.model.UserPasswordPolicy; -import org.thingsboard.server.dao.util.limits.RateLimitService; +import org.thingsboard.server.cache.limits.RateLimitService; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.security.auth.rest.RestAuthenticationDetails; import org.thingsboard.server.service.security.model.ActivateUserRequest; diff --git a/application/src/main/java/org/thingsboard/server/controller/plugin/TbWebSocketHandler.java b/application/src/main/java/org/thingsboard/server/controller/plugin/TbWebSocketHandler.java index 1696d5c20b..64536ddb54 100644 --- a/application/src/main/java/org/thingsboard/server/controller/plugin/TbWebSocketHandler.java +++ b/application/src/main/java/org/thingsboard/server/controller/plugin/TbWebSocketHandler.java @@ -43,7 +43,7 @@ import org.thingsboard.server.common.data.limit.LimitedApi; import org.thingsboard.server.common.data.tenant.profile.DefaultTenantProfileConfiguration; import org.thingsboard.server.config.WebSocketConfiguration; import org.thingsboard.server.dao.tenant.TbTenantProfileCache; -import org.thingsboard.server.dao.util.limits.RateLimitService; +import org.thingsboard.server.cache.limits.RateLimitService; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.security.auth.jwt.JwtAuthenticationProvider; import org.thingsboard.server.service.security.model.SecurityUser; diff --git a/application/src/main/java/org/thingsboard/server/service/notification/DefaultNotificationCenter.java b/application/src/main/java/org/thingsboard/server/service/notification/DefaultNotificationCenter.java index be37d98bb5..11c40d964a 100644 --- a/application/src/main/java/org/thingsboard/server/service/notification/DefaultNotificationCenter.java +++ b/application/src/main/java/org/thingsboard/server/service/notification/DefaultNotificationCenter.java @@ -62,7 +62,7 @@ import org.thingsboard.server.dao.notification.NotificationService; import org.thingsboard.server.dao.notification.NotificationSettingsService; import org.thingsboard.server.dao.notification.NotificationTargetService; import org.thingsboard.server.dao.notification.NotificationTemplateService; -import org.thingsboard.server.dao.util.limits.RateLimitService; +import org.thingsboard.server.cache.limits.RateLimitService; import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.queue.common.TbProtoQueueMsg; import org.thingsboard.server.queue.discovery.TopicService; diff --git a/application/src/main/java/org/thingsboard/server/service/notification/rule/DefaultNotificationRuleProcessor.java b/application/src/main/java/org/thingsboard/server/service/notification/rule/DefaultNotificationRuleProcessor.java index a68708d8ae..a86315ce86 100644 --- a/application/src/main/java/org/thingsboard/server/service/notification/rule/DefaultNotificationRuleProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/notification/rule/DefaultNotificationRuleProcessor.java @@ -41,7 +41,7 @@ import org.thingsboard.server.common.msg.notification.NotificationRuleProcessor; import org.thingsboard.server.common.msg.plugin.ComponentLifecycleMsg; import org.thingsboard.server.common.msg.queue.ServiceType; import org.thingsboard.server.dao.notification.NotificationRequestService; -import org.thingsboard.server.dao.util.limits.RateLimitService; +import org.thingsboard.server.cache.limits.RateLimitService; import org.thingsboard.server.queue.discovery.PartitionService; import org.thingsboard.server.queue.notification.NotificationDeduplicationService; import org.thingsboard.server.service.executors.NotificationExecutorService; diff --git a/application/src/main/java/org/thingsboard/server/service/security/auth/mfa/DefaultTwoFactorAuthService.java b/application/src/main/java/org/thingsboard/server/service/security/auth/mfa/DefaultTwoFactorAuthService.java index b2ebcb0b5d..d4425372e1 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/auth/mfa/DefaultTwoFactorAuthService.java +++ b/application/src/main/java/org/thingsboard/server/service/security/auth/mfa/DefaultTwoFactorAuthService.java @@ -32,7 +32,7 @@ import org.thingsboard.server.common.data.security.model.mfa.provider.TwoFaProvi import org.thingsboard.server.common.data.security.model.mfa.provider.TwoFaProviderType; import org.thingsboard.server.dao.user.UserService; import org.thingsboard.server.common.data.limit.LimitedApi; -import org.thingsboard.server.dao.util.limits.RateLimitService; +import org.thingsboard.server.cache.limits.RateLimitService; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.security.auth.mfa.config.TwoFaConfigManager; import org.thingsboard.server.service.security.auth.mfa.provider.TwoFaProvider; diff --git a/application/src/main/java/org/thingsboard/server/service/sync/ie/DefaultEntitiesExportImportService.java b/application/src/main/java/org/thingsboard/server/service/sync/ie/DefaultEntitiesExportImportService.java index 08a59973de..4e3d034207 100644 --- a/application/src/main/java/org/thingsboard/server/service/sync/ie/DefaultEntitiesExportImportService.java +++ b/application/src/main/java/org/thingsboard/server/service/sync/ie/DefaultEntitiesExportImportService.java @@ -32,7 +32,7 @@ import org.thingsboard.server.common.data.sync.ie.EntityImportResult; import org.thingsboard.server.common.data.util.ThrowingRunnable; import org.thingsboard.server.dao.exception.DataValidationException; import org.thingsboard.server.dao.relation.RelationService; -import org.thingsboard.server.dao.util.limits.RateLimitService; +import org.thingsboard.server.cache.limits.RateLimitService; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.entitiy.TbNotificationEntityService; import org.thingsboard.server.service.sync.ie.exporting.EntityExportService; diff --git a/application/src/test/java/org/thingsboard/server/service/limits/RateLimitServiceTest.java b/application/src/test/java/org/thingsboard/server/service/limits/RateLimitServiceTest.java index 9917e837b9..afdb38a2ec 100644 --- a/application/src/test/java/org/thingsboard/server/service/limits/RateLimitServiceTest.java +++ b/application/src/test/java/org/thingsboard/server/service/limits/RateLimitServiceTest.java @@ -20,6 +20,8 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mockito; import org.mockito.junit.MockitoJUnitRunner; +import org.thingsboard.server.cache.limits.DefaultRateLimitService; +import org.thingsboard.server.cache.limits.RateLimitService; import org.thingsboard.server.common.data.TenantProfile; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.NotificationRuleId; @@ -28,9 +30,7 @@ import org.thingsboard.server.common.data.limit.LimitedApi; import org.thingsboard.server.common.data.tenant.profile.DefaultTenantProfileConfiguration; import org.thingsboard.server.common.data.tenant.profile.TenantProfileData; import org.thingsboard.server.common.msg.notification.NotificationRuleProcessor; -import org.thingsboard.server.dao.tenant.TbTenantProfileCache; -import org.thingsboard.server.dao.util.limits.DefaultRateLimitService; -import org.thingsboard.server.dao.util.limits.RateLimitService; +import org.thingsboard.server.dao.tenant.DefaultTbTenantProfileCache; import java.util.List; import java.util.UUID; @@ -46,12 +46,12 @@ import static org.mockito.Mockito.when; public class RateLimitServiceTest { private RateLimitService rateLimitService; - private TbTenantProfileCache tenantProfileCache; + private DefaultTbTenantProfileCache tenantProfileCache; private TenantId tenantId; @Before public void beforeEach() { - tenantProfileCache = Mockito.mock(TbTenantProfileCache.class); + tenantProfileCache = Mockito.mock(DefaultTbTenantProfileCache.class); rateLimitService = new DefaultRateLimitService(tenantProfileCache, mock(NotificationRuleProcessor.class), 60, 100); tenantId = new TenantId(UUID.randomUUID()); } diff --git a/application/src/test/java/org/thingsboard/server/service/notification/NotificationRuleApiTest.java b/application/src/test/java/org/thingsboard/server/service/notification/NotificationRuleApiTest.java index ed4a1c613a..1e95f9add3 100644 --- a/application/src/test/java/org/thingsboard/server/service/notification/NotificationRuleApiTest.java +++ b/application/src/test/java/org/thingsboard/server/service/notification/NotificationRuleApiTest.java @@ -93,7 +93,7 @@ import org.thingsboard.server.dao.notification.DefaultNotifications; import org.thingsboard.server.dao.notification.NotificationRequestService; import org.thingsboard.server.dao.rule.RuleChainService; import org.thingsboard.server.dao.service.DaoSqlTest; -import org.thingsboard.server.dao.util.limits.RateLimitService; +import org.thingsboard.server.cache.limits.RateLimitService; import org.thingsboard.server.queue.notification.DefaultNotificationDeduplicationService; import org.thingsboard.server.service.notification.rule.cache.DefaultNotificationRulesCache; import org.thingsboard.server.service.state.DeviceStateService; diff --git a/common/cache/pom.xml b/common/cache/pom.xml index 6b9544e761..184aa615ba 100644 --- a/common/cache/pom.xml +++ b/common/cache/pom.xml @@ -40,6 +40,10 @@ org.thingsboard.common data + + org.thingsboard.common + message + org.springframework.boot spring-boot-autoconfigure diff --git a/dao/src/main/java/org/thingsboard/server/dao/util/limits/DefaultRateLimitService.java b/common/cache/src/main/java/org/thingsboard/server/cache/limits/DefaultRateLimitService.java similarity index 89% rename from dao/src/main/java/org/thingsboard/server/dao/util/limits/DefaultRateLimitService.java rename to common/cache/src/main/java/org/thingsboard/server/cache/limits/DefaultRateLimitService.java index bcd560a6f9..a8f4545449 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/util/limits/DefaultRateLimitService.java +++ b/common/cache/src/main/java/org/thingsboard/server/cache/limits/DefaultRateLimitService.java @@ -13,14 +13,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.dao.util.limits; +package org.thingsboard.server.cache.limits; import com.github.benmanes.caffeine.cache.Cache; import com.github.benmanes.caffeine.cache.Caffeine; import lombok.Data; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.TenantProfile; @@ -28,10 +27,9 @@ import org.thingsboard.server.common.data.exception.TenantProfileNotFoundExcepti import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.limit.LimitedApi; -import org.thingsboard.server.common.msg.notification.NotificationRuleProcessor; import org.thingsboard.server.common.data.notification.rule.trigger.RateLimitsTrigger; +import org.thingsboard.server.common.msg.notification.NotificationRuleProcessor; import org.thingsboard.server.common.msg.tools.TbRateLimits; -import org.thingsboard.server.dao.tenant.TbTenantProfileCache; import java.util.concurrent.TimeUnit; @@ -39,14 +37,14 @@ import java.util.concurrent.TimeUnit; @Slf4j public class DefaultRateLimitService implements RateLimitService { - private final TbTenantProfileCache tenantProfileCache; + private final TenantProfileProvider tenantProfileProvider; private final NotificationRuleProcessor notificationRuleProcessor; - public DefaultRateLimitService(TbTenantProfileCache tenantProfileCache, - @Lazy NotificationRuleProcessor notificationRuleProcessor, + public DefaultRateLimitService(TenantProfileProvider tenantProfileProvider, + NotificationRuleProcessor notificationRuleProcessor, @Value("${cache.rateLimits.timeToLiveInMinutes:120}") int rateLimitsTtl, @Value("${cache.rateLimits.maxSize:200000}") int rateLimitsCacheMaxSize) { - this.tenantProfileCache = tenantProfileCache; + this.tenantProfileProvider = tenantProfileProvider; this.notificationRuleProcessor = notificationRuleProcessor; this.rateLimits = Caffeine.newBuilder() .expireAfterAccess(rateLimitsTtl, TimeUnit.MINUTES) @@ -66,7 +64,7 @@ public class DefaultRateLimitService implements RateLimitService { if (tenantId.isSysTenantId()) { return true; } - TenantProfile tenantProfile = tenantProfileCache.get(tenantId); + TenantProfile tenantProfile = tenantProfileProvider.get(tenantId); if (tenantProfile == null) { throw new TenantProfileNotFoundException(tenantId); } diff --git a/dao/src/main/java/org/thingsboard/server/dao/util/limits/RateLimitService.java b/common/cache/src/main/java/org/thingsboard/server/cache/limits/RateLimitService.java similarity index 95% rename from dao/src/main/java/org/thingsboard/server/dao/util/limits/RateLimitService.java rename to common/cache/src/main/java/org/thingsboard/server/cache/limits/RateLimitService.java index e24383bb62..84c22c514b 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/util/limits/RateLimitService.java +++ b/common/cache/src/main/java/org/thingsboard/server/cache/limits/RateLimitService.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.dao.util.limits; +package org.thingsboard.server.cache.limits; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.limit.LimitedApi; diff --git a/common/cache/src/main/java/org/thingsboard/server/cache/limits/TenantProfileProvider.java b/common/cache/src/main/java/org/thingsboard/server/cache/limits/TenantProfileProvider.java new file mode 100644 index 0000000000..15243d12c8 --- /dev/null +++ b/common/cache/src/main/java/org/thingsboard/server/cache/limits/TenantProfileProvider.java @@ -0,0 +1,25 @@ +/** + * Copyright © 2016-2024 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.server.cache.limits; + +import org.thingsboard.server.common.data.TenantProfile; +import org.thingsboard.server.common.data.id.TenantId; + +public interface TenantProfileProvider { + + TenantProfile get(TenantId tenantId); + +} diff --git a/dao/src/main/java/org/thingsboard/server/dao/nosql/CassandraBufferedRateReadExecutor.java b/dao/src/main/java/org/thingsboard/server/dao/nosql/CassandraBufferedRateReadExecutor.java index 23d4245575..e569745504 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/nosql/CassandraBufferedRateReadExecutor.java +++ b/dao/src/main/java/org/thingsboard/server/dao/nosql/CassandraBufferedRateReadExecutor.java @@ -27,7 +27,7 @@ import org.thingsboard.server.dao.entity.EntityService; import org.thingsboard.server.dao.util.AbstractBufferedRateExecutor; import org.thingsboard.server.dao.util.AsyncTaskContext; import org.thingsboard.server.dao.util.NoSqlAnyDao; -import org.thingsboard.server.dao.util.limits.RateLimitService; +import org.thingsboard.server.cache.limits.RateLimitService; import javax.annotation.PreDestroy; diff --git a/dao/src/main/java/org/thingsboard/server/dao/nosql/CassandraBufferedRateWriteExecutor.java b/dao/src/main/java/org/thingsboard/server/dao/nosql/CassandraBufferedRateWriteExecutor.java index 822768c572..59fdcac935 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/nosql/CassandraBufferedRateWriteExecutor.java +++ b/dao/src/main/java/org/thingsboard/server/dao/nosql/CassandraBufferedRateWriteExecutor.java @@ -27,7 +27,7 @@ import org.thingsboard.server.dao.entity.EntityService; import org.thingsboard.server.dao.util.AbstractBufferedRateExecutor; import org.thingsboard.server.dao.util.AsyncTaskContext; import org.thingsboard.server.dao.util.NoSqlAnyDao; -import org.thingsboard.server.dao.util.limits.RateLimitService; +import org.thingsboard.server.cache.limits.RateLimitService; import javax.annotation.PreDestroy; diff --git a/dao/src/main/java/org/thingsboard/server/dao/tenant/DefaultTbTenantProfileCache.java b/dao/src/main/java/org/thingsboard/server/dao/tenant/DefaultTbTenantProfileCache.java index 4610973370..a9d118befb 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/tenant/DefaultTbTenantProfileCache.java +++ b/dao/src/main/java/org/thingsboard/server/dao/tenant/DefaultTbTenantProfileCache.java @@ -17,6 +17,7 @@ package org.thingsboard.server.dao.tenant; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; +import org.thingsboard.server.cache.limits.TenantProfileProvider; import org.thingsboard.server.common.data.Tenant; import org.thingsboard.server.common.data.TenantProfile; import org.thingsboard.server.common.data.id.EntityId; @@ -31,7 +32,7 @@ import java.util.function.Consumer; @Service @Slf4j -public class DefaultTbTenantProfileCache implements TbTenantProfileCache { +public class DefaultTbTenantProfileCache implements TbTenantProfileCache, TenantProfileProvider { private final Lock tenantProfileFetchLock = new ReentrantLock(); private final TenantProfileService tenantProfileService; diff --git a/dao/src/main/java/org/thingsboard/server/dao/util/AbstractBufferedRateExecutor.java b/dao/src/main/java/org/thingsboard/server/dao/util/AbstractBufferedRateExecutor.java index ebe2d59dcf..8474af9584 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/util/AbstractBufferedRateExecutor.java +++ b/dao/src/main/java/org/thingsboard/server/dao/util/AbstractBufferedRateExecutor.java @@ -38,7 +38,7 @@ import org.thingsboard.server.common.stats.StatsType; import org.thingsboard.server.dao.entity.EntityService; import org.thingsboard.server.dao.nosql.CassandraStatementTask; import org.thingsboard.server.common.data.limit.LimitedApi; -import org.thingsboard.server.dao.util.limits.RateLimitService; +import org.thingsboard.server.cache.limits.RateLimitService; import javax.annotation.Nullable; import java.util.HashMap; From a729967a930f4ee9de8fde68a046bb4b08575aad Mon Sep 17 00:00:00 2001 From: ViacheslavKlimov Date: Fri, 26 Jan 2024 15:21:27 +0200 Subject: [PATCH 136/179] Fix DefaultRateLimitService init --- .../server/cache/limits/DefaultRateLimitService.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/common/cache/src/main/java/org/thingsboard/server/cache/limits/DefaultRateLimitService.java b/common/cache/src/main/java/org/thingsboard/server/cache/limits/DefaultRateLimitService.java index a8f4545449..f3530e99d2 100644 --- a/common/cache/src/main/java/org/thingsboard/server/cache/limits/DefaultRateLimitService.java +++ b/common/cache/src/main/java/org/thingsboard/server/cache/limits/DefaultRateLimitService.java @@ -20,6 +20,7 @@ import com.github.benmanes.caffeine.cache.Caffeine; import lombok.Data; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.TenantProfile; @@ -33,6 +34,7 @@ import org.thingsboard.server.common.msg.tools.TbRateLimits; import java.util.concurrent.TimeUnit; +@Lazy @Service @Slf4j public class DefaultRateLimitService implements RateLimitService { @@ -41,7 +43,7 @@ public class DefaultRateLimitService implements RateLimitService { private final NotificationRuleProcessor notificationRuleProcessor; public DefaultRateLimitService(TenantProfileProvider tenantProfileProvider, - NotificationRuleProcessor notificationRuleProcessor, + @Lazy NotificationRuleProcessor notificationRuleProcessor, @Value("${cache.rateLimits.timeToLiveInMinutes:120}") int rateLimitsTtl, @Value("${cache.rateLimits.maxSize:200000}") int rateLimitsCacheMaxSize) { this.tenantProfileProvider = tenantProfileProvider; From 3fcb913645762f0925fe02b0732fd68dcd656ee1 Mon Sep 17 00:00:00 2001 From: Igor Kulikov Date: Fri, 26 Jan 2024 17:54:24 +0200 Subject: [PATCH 137/179] UI: Update Widget action form style. --- ui-ngx/src/app/modules/common/modules-map.ts | 12 +- .../home/components/home-components.module.ts | 9 - .../manage-widget-actions.component.models.ts | 30 +- .../widget-action-dialog.component.html | 280 +++-------- .../action/widget-action-dialog.component.ts | 350 +------------ ...custom-action-pretty-editor.component.html | 3 +- ...custom-action-pretty-editor.component.scss | 2 +- .../custom-action-pretty-editor.component.ts | 4 +- ...ction-pretty-resources-tabs.component.html | 1 + ...ction-pretty-resources-tabs.component.scss | 0 ...-action-pretty-resources-tabs.component.ts | 2 +- .../action/custom-action.models.ts | 24 + .../{ => config}/action/custom-sample-css.raw | 0 .../action/custom-sample-html.raw | 0 .../{ => config}/action/custom-sample-js.raw | 0 .../mobile-action-editor.component.html | 56 ++- .../action/mobile-action-editor.component.ts | 35 +- .../action/mobile-action-editor.models.ts | 40 +- .../action/widget-action.component.html | 234 +++++++++ .../config/action/widget-action.component.ts | 463 ++++++++++++++++++ .../config/widget-config-components.module.ts | 17 +- .../common/css-size-input.component.html | 33 ++ .../common/css-size-input.component.ts | 124 +++++ .../common/css-unit-select.component.html | 2 +- .../common/css-unit-select.component.ts | 3 + .../common/widget-settings-common.module.ts | 3 + .../components/widget/widget.component.ts | 2 +- .../dashboard-autocomplete.component.html | 24 +- .../dashboard-autocomplete.component.ts | 40 +- .../shared/components/js-func.component.html | 12 +- .../shared/components/js-func.component.scss | 6 +- .../shared/components/js-func.component.ts | 20 +- .../shared/models/widget-settings.models.ts | 4 +- ui-ngx/src/app/shared/models/widget.models.ts | 24 +- .../assets/locale/locale.constant-ca_ES.json | 6 +- .../assets/locale/locale.constant-cs_CZ.json | 2 +- .../assets/locale/locale.constant-da_DK.json | 2 +- .../assets/locale/locale.constant-de_DE.json | 2 +- .../assets/locale/locale.constant-el_GR.json | 2 +- .../assets/locale/locale.constant-en_US.json | 19 +- .../assets/locale/locale.constant-es_ES.json | 6 +- .../assets/locale/locale.constant-fa_IR.json | 2 +- .../assets/locale/locale.constant-fr_FR.json | 2 +- .../assets/locale/locale.constant-it_IT.json | 2 +- .../assets/locale/locale.constant-ja_JP.json | 2 +- .../assets/locale/locale.constant-ka_GE.json | 2 +- .../assets/locale/locale.constant-ko_KR.json | 2 +- .../assets/locale/locale.constant-lv_LV.json | 2 +- .../assets/locale/locale.constant-nl_BE.json | 6 +- .../assets/locale/locale.constant-pt_BR.json | 2 +- .../assets/locale/locale.constant-ro_RO.json | 2 +- .../assets/locale/locale.constant-sl_SI.json | 2 +- .../assets/locale/locale.constant-tr_TR.json | 2 +- .../assets/locale/locale.constant-uk_UA.json | 2 +- .../assets/locale/locale.constant-zh_CN.json | 6 +- .../assets/locale/locale.constant-zh_TW.json | 6 +- ui-ngx/src/form.scss | 6 +- 57 files changed, 1217 insertions(+), 729 deletions(-) rename ui-ngx/src/app/modules/home/components/widget/{ => config}/action/custom-action-pretty-editor.component.html (94%) rename ui-ngx/src/app/modules/home/components/widget/{ => config}/action/custom-action-pretty-editor.component.scss (96%) rename ui-ngx/src/app/modules/home/components/widget/{ => config}/action/custom-action-pretty-editor.component.ts (96%) rename ui-ngx/src/app/modules/home/components/widget/{ => config}/action/custom-action-pretty-resources-tabs.component.html (98%) rename ui-ngx/src/app/modules/home/components/widget/{ => config}/action/custom-action-pretty-resources-tabs.component.scss (100%) rename ui-ngx/src/app/modules/home/components/widget/{ => config}/action/custom-action-pretty-resources-tabs.component.ts (99%) rename ui-ngx/src/app/modules/home/components/widget/{ => config}/action/custom-action.models.ts (71%) rename ui-ngx/src/app/modules/home/components/widget/{ => config}/action/custom-sample-css.raw (100%) rename ui-ngx/src/app/modules/home/components/widget/{ => config}/action/custom-sample-html.raw (100%) rename ui-ngx/src/app/modules/home/components/widget/{ => config}/action/custom-sample-js.raw (100%) rename ui-ngx/src/app/modules/home/components/widget/{ => config}/action/mobile-action-editor.component.html (74%) rename ui-ngx/src/app/modules/home/components/widget/{ => config}/action/mobile-action-editor.component.ts (91%) rename ui-ngx/src/app/modules/home/components/widget/{ => config}/action/mobile-action-editor.models.ts (92%) create mode 100644 ui-ngx/src/app/modules/home/components/widget/config/action/widget-action.component.html create mode 100644 ui-ngx/src/app/modules/home/components/widget/config/action/widget-action.component.ts create mode 100644 ui-ngx/src/app/modules/home/components/widget/lib/settings/common/css-size-input.component.html create mode 100644 ui-ngx/src/app/modules/home/components/widget/lib/settings/common/css-size-input.component.ts diff --git a/ui-ngx/src/app/modules/common/modules-map.ts b/ui-ngx/src/app/modules/common/modules-map.ts index c19b96e2a7..f8dab27af9 100644 --- a/ui-ngx/src/app/modules/common/modules-map.ts +++ b/ui-ngx/src/app/modules/common/modules-map.ts @@ -226,9 +226,9 @@ import * as DataKeyConfigComponent from '@home/components/widget/config/data-key import * as LegendConfigComponent from '@home/components/widget/lib/settings/common/legend-config.component'; import * as ManageWidgetActionsComponent from '@home/components/widget/action/manage-widget-actions.component'; import * as WidgetActionDialogComponent from '@home/components/widget/action/widget-action-dialog.component'; -import * as CustomActionPrettyResourcesTabsComponent from '@home/components/widget/action/custom-action-pretty-resources-tabs.component'; -import * as CustomActionPrettyEditorComponent from '@home/components/widget/action/custom-action-pretty-editor.component'; -import * as MobileActionEditorComponent from '@home/components/widget/action/mobile-action-editor.component'; +import * as CustomActionPrettyResourcesTabsComponent from '@home/components/widget/config/action/custom-action-pretty-resources-tabs.component'; +import * as CustomActionPrettyEditorComponent from '@home/components/widget/config/action/custom-action-pretty-editor.component'; +import * as MobileActionEditorComponent from '@home/components/widget/config/action/mobile-action-editor.component'; import * as CustomDialogService from '@home/components/widget/dialog/custom-dialog.service'; import * as CustomDialogContainerComponent from '@home/components/widget/dialog/custom-dialog-container.component'; import * as ImportDialogComponent from '@shared/import-export/import-dialog.component'; @@ -541,9 +541,9 @@ class ModulesMap implements IModulesMap { '@home/components/widget/lib/settings/common/legend-config.component': LegendConfigComponent, '@home/components/widget/action/manage-widget-actions.component': ManageWidgetActionsComponent, '@home/components/widget/action/widget-action-dialog.component': WidgetActionDialogComponent, - '@home/components/widget/action/custom-action-pretty-resources-tabs.component': CustomActionPrettyResourcesTabsComponent, - '@home/components/widget/action/custom-action-pretty-editor.component': CustomActionPrettyEditorComponent, - '@home/components/widget/action/mobile-action-editor.component': MobileActionEditorComponent, + '@home/components/widget/config/action/custom-action-pretty-resources-tabs.component': CustomActionPrettyResourcesTabsComponent, + '@home/components/widget/config/action/custom-action-pretty-editor.component': CustomActionPrettyEditorComponent, + '@home/components/widget/config/action/mobile-action-editor.component': MobileActionEditorComponent, '@home/components/widget/dialog/custom-dialog.service': CustomDialogService, '@home/components/widget/dialog/custom-dialog-container.component': CustomDialogContainerComponent, '@home/components/attribute/add-widget-to-dashboard-dialog.component': AddWidgetToDashboardDialogComponent, diff --git a/ui-ngx/src/app/modules/home/components/home-components.module.ts b/ui-ngx/src/app/modules/home/components/home-components.module.ts index 4694b5ead8..5390a915d3 100644 --- a/ui-ngx/src/app/modules/home/components/home-components.module.ts +++ b/ui-ngx/src/app/modules/home/components/home-components.module.ts @@ -46,9 +46,6 @@ import { EntityFilterComponent } from '@home/components/entity/entity-filter.com import { RelationFiltersComponent } from '@home/components/relation/relation-filters.component'; import { ManageWidgetActionsComponent } from '@home/components/widget/action/manage-widget-actions.component'; import { WidgetActionDialogComponent } from '@home/components/widget/action/widget-action-dialog.component'; -import { CustomActionPrettyResourcesTabsComponent } from '@home/components/widget/action/custom-action-pretty-resources-tabs.component'; -import { CustomActionPrettyEditorComponent } from '@home/components/widget/action/custom-action-pretty-editor.component'; -import { MobileActionEditorComponent } from '@home/components/widget/action/mobile-action-editor.component'; import { CustomDialogService } from '@home/components/widget/dialog/custom-dialog.service'; import { CustomDialogContainerComponent } from '@home/components/widget/dialog/custom-dialog-container.component'; import { AddWidgetToDashboardDialogComponent } from '@home/components/attribute/add-widget-to-dashboard-dialog.component'; @@ -218,9 +215,6 @@ import { DeleteTimeseriesPanelComponent } from '@home/components/attribute/delet ManageWidgetActionsComponent, WidgetActionDialogComponent, ManageWidgetActionsDialogComponent, - CustomActionPrettyResourcesTabsComponent, - CustomActionPrettyEditorComponent, - MobileActionEditorComponent, CustomDialogContainerComponent, SelectTargetLayoutDialogComponent, SelectTargetStateDialogComponent, @@ -359,9 +353,6 @@ import { DeleteTimeseriesPanelComponent } from '@home/components/attribute/delet ManageWidgetActionsComponent, WidgetActionDialogComponent, ManageWidgetActionsDialogComponent, - CustomActionPrettyResourcesTabsComponent, - CustomActionPrettyEditorComponent, - MobileActionEditorComponent, CustomDialogContainerComponent, SelectTargetLayoutDialogComponent, SelectTargetStateDialogComponent, diff --git a/ui-ngx/src/app/modules/home/components/widget/action/manage-widget-actions.component.models.ts b/ui-ngx/src/app/modules/home/components/widget/action/manage-widget-actions.component.models.ts index 941affd220..428fb6fa1b 100644 --- a/ui-ngx/src/app/modules/home/components/widget/action/manage-widget-actions.component.models.ts +++ b/ui-ngx/src/app/modules/home/components/widget/action/manage-widget-actions.component.models.ts @@ -15,7 +15,6 @@ /// import { - CustomActionDescriptor, WidgetActionDescriptor, WidgetActionSource, widgetActionTypeTranslationMap @@ -27,11 +26,7 @@ import { TranslateService } from '@ngx-translate/core'; import { PageLink } from '@shared/models/page/page-link'; import { catchError, map, publishReplay, refCount } from 'rxjs/operators'; import { UtilsService } from '@core/services/utils.service'; -import { deepClone, isDefined, isUndefined } from '@core/utils'; - -import customSampleJs from '!raw-loader!./custom-sample-js.raw'; -import customSampleCss from '!raw-loader!./custom-sample-css.raw'; -import customSampleHtml from '!raw-loader!./custom-sample-html.raw'; +import { deepClone } from '@core/utils'; export interface WidgetActionCallbacks { fetchDashboardStates: (query: string) => Array; @@ -48,32 +43,13 @@ export interface WidgetActionDescriptorInfo extends WidgetActionDescriptor { typeName?: string; } -export function toWidgetActionDescriptor(action: WidgetActionDescriptorInfo): WidgetActionDescriptor { +export const toWidgetActionDescriptor = (action: WidgetActionDescriptorInfo): WidgetActionDescriptor => { const copy = deepClone(action); delete copy.actionSourceId; delete copy.actionSourceName; delete copy.typeName; return copy; -} - -export function toCustomAction(action: WidgetActionDescriptorInfo): CustomActionDescriptor { - let result: CustomActionDescriptor; - if (!action || (isUndefined(action.customFunction) && isUndefined(action.customHtml) && isUndefined(action.customCss))) { - result = { - customHtml: customSampleHtml, - customCss: customSampleCss, - customFunction: customSampleJs - }; - } else { - result = { - customHtml: action.customHtml, - customCss: action.customCss, - customFunction: action.customFunction - }; - } - result.customResources = action && isDefined(action.customResources) ? deepClone(action.customResources) : []; - return result; -} +}; export class WidgetActionsDatasource implements DataSource { diff --git a/ui-ngx/src/app/modules/home/components/widget/action/widget-action-dialog.component.html b/ui-ngx/src/app/modules/home/components/widget/action/widget-action-dialog.component.html index 94e88350e1..f75b2e44e7 100644 --- a/ui-ngx/src/app/modules/home/components/widget/action/widget-action-dialog.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/action/widget-action-dialog.component.html @@ -27,219 +27,82 @@ -
+
- - widget-config.action-source - - - {{ actionSourceName(actionSourceItem.value) }} - - - - {{ 'widget-config.action-source-required' | translate }} - - - - widget-config.action-name - - - - {{ 'widget-config.action-name-required' | translate }} - - - - - - - - {{ 'widget-config.show-hide-action-using-function' | translate }} - - - - widget-config.action-type - - - {{ widgetActionTypeTranslations.get(widgetActionType[actionType]) | translate }} - - - - {{ 'widget-config.action-type-required' | translate }} - - -
- -
widget-action.target-dashboard
- -
- - - - - - - - - - - {{ 'widget-action.target-dashboard-state-required' | translate }} - - - - - - {{ 'widget-action.open-right-layout' | translate }} - - - - - {{ 'widget-action.open-new-browser-tab' | translate }} - - - - - {{ 'widget-action.set-entity-from-widget' | translate }} - - - alias.state-entity-parameter-name - - - - - - widget-action.state-display-type - - - {{ stateDisplayTypeName(displayType) }} +
+
+
{{'widget-config.action-source' | translate}}*
+ + + + {{ actionSourceName(actionSourceItem.value) }} + + warning + -
- - - widget-action.dialog-title - - - - {{ 'widget-action.dialog-hide-dashboard-toolbar' | translate }} - - - widget-action.dialog-width - - - {{ 'widget-action.dialog-size-range-error' | translate }} - - - {{ 'widget-action.dialog-size-range-error' | translate }} - - - - widget-action.dialog-height - - - {{ 'widget-action.dialog-size-range-error' | translate }} - - - {{ 'widget-action.dialog-size-range-error' | translate }} - - - - - - widget-action.popover-preferred-placement - - - {{ popoverPlacementName(placement) }} - - - - - {{ 'widget-action.popover-hide-on-click-outside' | translate }} - - - {{ 'widget-action.popover-hide-dashboard-toolbar' | translate }} - - - widget-action.popover-width - - - - widget-action.popover-height - - - - - +
+
+
{{'widget-config.action-name' | translate}}*
+ + + + warning + + +
+
+
{{'widget-config.icon' | translate}}
+ + +
+
+ + + + + {{ 'widget-config.show-hide-action-using-function' | translate }} + + + + + -
- - - - - - - - - - - - -
+ +
+ + +
@@ -251,8 +114,7 @@
diff --git a/ui-ngx/src/app/modules/home/components/widget/action/widget-action-dialog.component.ts b/ui-ngx/src/app/modules/home/components/widget/action/widget-action-dialog.component.ts index 15ece4f772..1eec44b714 100644 --- a/ui-ngx/src/app/modules/home/components/widget/action/widget-action-dialog.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/action/widget-action-dialog.component.ts @@ -14,46 +14,38 @@ /// limitations under the License. /// -import { Component, ElementRef, Inject, OnInit, SkipSelf, ViewChild } from '@angular/core'; +import { Component, Inject, OnDestroy, OnInit, SkipSelf } from '@angular/core'; import { ErrorStateMatcher } from '@angular/material/core'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { Store } from '@ngrx/store'; import { AppState } from '@core/core.state'; import { + FormGroupDirective, + NgForm, UntypedFormBuilder, UntypedFormControl, UntypedFormGroup, - FormGroupDirective, - NgForm, ValidatorFn, Validators } from '@angular/forms'; -import { Observable, of, Subject, Subscription } from 'rxjs'; +import { Subject } from 'rxjs'; import { Router } from '@angular/router'; import { DialogComponent } from '@app/shared/components/dialog.component'; import { - toCustomAction, WidgetActionCallbacks, WidgetActionDescriptorInfo, WidgetActionsData } from '@home/components/widget/action/manage-widget-actions.component.models'; import { UtilsService } from '@core/services/utils.service'; import { + actionDescriptorToAction, WidgetActionSource, WidgetActionType, - widgetActionTypeTranslationMap + widgetType } from '@shared/models/widget.models'; -import { map, mergeMap, startWith, takeUntil, tap } from 'rxjs/operators'; -import { DashboardService } from '@core/http/dashboard.service'; -import { Dashboard } from '@shared/models/dashboard.models'; -import { DashboardUtilsService } from '@core/services/dashboard-utils.service'; -import { CustomActionEditorCompleter } from '@home/components/widget/action/custom-action.models'; -import { isDefinedAndNotNull } from '@core/utils'; -import { MobileActionEditorComponent } from '@home/components/widget/action/mobile-action-editor.component'; -import { widgetType } from '@shared/models/widget.models'; +import { takeUntil } from 'rxjs/operators'; +import { CustomActionEditorCompleter } from '@home/components/widget/config/action/custom-action.models'; import { WidgetService } from '@core/http/widget.service'; -import { TranslateService } from '@ngx-translate/core'; -import { PopoverPlacement, PopoverPlacements } from '@shared/components/popover.models'; export interface WidgetActionDialogData { isAdd: boolean; @@ -63,18 +55,6 @@ export interface WidgetActionDialogData { widgetType: widgetType; } -const stateDisplayTypes = ['normal', 'separateDialog', 'popover'] as const; -type stateDisplayTypeTuple = typeof stateDisplayTypes; -export type stateDisplayType = stateDisplayTypeTuple[number]; - -const stateDisplayTypesTranslations = new Map( - [ - ['normal', 'widget-action.open-normal'], - ['separateDialog', 'widget-action.open-in-separate-dialog'], - ['popover', 'widget-action.open-in-popover'], - ] -); - @Component({ selector: 'tb-widget-action-dialog', templateUrl: './widget-action-dialog.component.html', @@ -82,49 +62,25 @@ const stateDisplayTypesTranslations = new Map( styleUrls: [] }) export class WidgetActionDialogComponent extends DialogComponent implements OnInit, ErrorStateMatcher { - - @ViewChild('dashboardStateInput') dashboardStateInput: ElementRef; - - @ViewChild('mobileActionEditor', {static: false}) mobileActionEditor: MobileActionEditorComponent; + WidgetActionDescriptorInfo> implements OnInit, OnDestroy, ErrorStateMatcher { private destroy$ = new Subject(); - private dashboard: Dashboard; - widgetActionFormGroup: UntypedFormGroup; - actionTypeFormGroup: UntypedFormGroup; - actionTypeFormGroupSubscriptions: Subscription[] = []; - stateDisplayTypeFormGroup: UntypedFormGroup; isAdd: boolean; action: WidgetActionDescriptorInfo; - widgetActionTypes = Object.keys(WidgetActionType); - widgetActionTypeTranslations = widgetActionTypeTranslationMap; - widgetActionType = WidgetActionType; - - filteredDashboardStates: Observable>; - targetDashboardStateSearchText = ''; - selectedDashboardStateIds: Observable>; - customActionEditorCompleter = CustomActionEditorCompleter; submitted = false; - widgetType = widgetType; functionScopeVariables: string[]; - allStateDisplayTypes = stateDisplayTypes; - allPopoverPlacements = PopoverPlacements; - constructor(protected store: Store, protected router: Router, private utils: UtilsService, - private dashboardService: DashboardService, - private dashboardUtils: DashboardUtilsService, private widgetService: WidgetService, - private translate: TranslateService, @Inject(MAT_DIALOG_DATA) public data: WidgetActionDialogData, @SkipSelf() private errorStateMatcher: ErrorStateMatcher, public dialogRef: MatDialogRef, @@ -136,7 +92,11 @@ export class WidgetActionDialogComponent extends DialogComponent { - this.updateActionTypeFormGroup(type); - }); this.widgetActionFormGroup.get('actionSourceId').valueChanges.pipe( takeUntil(this.destroy$) ).subscribe(() => { @@ -209,233 +163,6 @@ export class WidgetActionDialogComponent extends DialogComponent s.unsubscribe()); - this.actionTypeFormGroupSubscriptions.length = 0; - this.actionTypeFormGroup = this.fb.group({}); - if (type) { - switch (type) { - case WidgetActionType.openDashboard: - case WidgetActionType.openDashboardState: - case WidgetActionType.updateDashboardState: - this.actionTypeFormGroup.addControl( - 'targetDashboardStateId', - this.fb.control(action ? action.targetDashboardStateId : null, - type === WidgetActionType.openDashboardState ? [Validators.required] : []) - ); - this.actionTypeFormGroup.addControl( - 'setEntityId', - this.fb.control(this.data.widgetType === widgetType.static ? false : action ? action.setEntityId : true, []) - ); - this.actionTypeFormGroup.addControl( - 'stateEntityParamName', - this.fb.control(action ? action.stateEntityParamName : null, []) - ); - if (type === WidgetActionType.openDashboard) { - this.actionTypeFormGroup.addControl( - 'openNewBrowserTab', - this.fb.control(action ? action.openNewBrowserTab : false, []) - ); - this.actionTypeFormGroup.addControl( - 'targetDashboardId', - this.fb.control(action ? action.targetDashboardId : null, - [Validators.required]) - ); - this.setupSelectedDashboardStateIds(); - } else { - if (type === WidgetActionType.openDashboardState) { - const displayType = this.getStateDisplayType(action); - this.actionTypeFormGroup.addControl( - 'stateDisplayType', - this.fb.control(this.getStateDisplayType(action), [Validators.required]) - ); - this.updateStateDisplayTypeFormGroup(displayType, action); - this.actionTypeFormGroupSubscriptions.push( - this.actionTypeFormGroup.get('stateDisplayType').valueChanges.pipe( - takeUntil(this.destroy$) - ).subscribe((displayTypeValue: stateDisplayType) => { - this.updateStateDisplayTypeFormGroup(displayTypeValue); - }) - ); - } - this.actionTypeFormGroup.addControl( - 'openRightLayout', - this.fb.control(action ? action.openRightLayout : false, []) - ); - } - this.setupFilteredDashboardStates(); - break; - case WidgetActionType.custom: - this.actionTypeFormGroup.addControl( - 'customFunction', - this.fb.control(action ? action.customFunction : null, []) - ); - break; - case WidgetActionType.customPretty: - this.actionTypeFormGroup.addControl( - 'customAction', - this.fb.control(toCustomAction(action), [Validators.required]) - ); - break; - case WidgetActionType.mobileAction: - this.actionTypeFormGroup.addControl( - 'mobileAction', - this.fb.control(action ? action.mobileAction : null, [Validators.required]) - ); - break; - } - } - } - - private updateStateDisplayTypeFormGroup(displayType?: stateDisplayType, action?: WidgetActionDescriptorInfo) { - this.stateDisplayTypeFormGroup = this.fb.group({}); - if (displayType) { - switch (displayType) { - case 'normal': - break; - case 'separateDialog': - this.stateDisplayTypeFormGroup.addControl( - 'dialogTitle', - this.fb.control(action ? action.dialogTitle : '', []) - ); - this.stateDisplayTypeFormGroup.addControl( - 'dialogHideDashboardToolbar', - this.fb.control(action && isDefinedAndNotNull(action.dialogHideDashboardToolbar) - ? action.dialogHideDashboardToolbar : true, []) - ); - this.stateDisplayTypeFormGroup.addControl( - 'dialogWidth', - this.fb.control(action ? action.dialogWidth : null, [Validators.min(1), Validators.max(100)]) - ); - this.stateDisplayTypeFormGroup.addControl( - 'dialogHeight', - this.fb.control(action ? action.dialogHeight : null, [Validators.min(1), Validators.max(100)]) - ); - break; - case 'popover': - this.stateDisplayTypeFormGroup.addControl( - 'popoverPreferredPlacement', - this.fb.control(action && isDefinedAndNotNull(action.popoverPreferredPlacement) - ? action.popoverPreferredPlacement : 'top', []) - ); - this.stateDisplayTypeFormGroup.addControl( - 'popoverHideOnClickOutside', - this.fb.control(action && isDefinedAndNotNull(action.popoverHideOnClickOutside) - ? action.popoverHideOnClickOutside : true, []) - ); - this.stateDisplayTypeFormGroup.addControl( - 'popoverHideDashboardToolbar', - this.fb.control(action && isDefinedAndNotNull(action.popoverHideDashboardToolbar) - ? action.popoverHideDashboardToolbar : true, []) - ); - this.stateDisplayTypeFormGroup.addControl( - 'popoverWidth', - this.fb.control(action && isDefinedAndNotNull(action.popoverWidth) ? action.popoverWidth : '25vw', []) - ); - this.stateDisplayTypeFormGroup.addControl( - 'popoverHeight', - this.fb.control(action && isDefinedAndNotNull(action.popoverHeight) ? action.popoverHeight : '25vh', []) - ); - this.stateDisplayTypeFormGroup.addControl( - 'popoverStyle', - this.fb.control(action && isDefinedAndNotNull(action.popoverStyle) ? action.popoverStyle : {}, []) - ); - break; - } - } - } - - private getStateDisplayType(action?: WidgetActionDescriptorInfo): stateDisplayType { - let res: stateDisplayType = 'normal'; - if (action) { - if (action.openInSeparateDialog) { - res = 'separateDialog'; - } else if (action.openInPopover) { - res = 'popover'; - } - } - return res; - } - - private setupSelectedDashboardStateIds() { - this.selectedDashboardStateIds = - this.actionTypeFormGroup.get('targetDashboardId').valueChanges.pipe( - tap((dashboardId) => { - if (!dashboardId) { - this.actionTypeFormGroup.get('targetDashboardStateId') - .patchValue('', {emitEvent: true}); - } - - this.targetDashboardStateSearchText = ''; - }), - mergeMap((dashboardId) => { - if (dashboardId) { - if (this.dashboard?.id.id === dashboardId) { - return of(this.dashboard); - } else { - return this.dashboardService.getDashboard(dashboardId); - } - } else { - return of(null); - } - }), - map((dashboard: Dashboard) => { - if (dashboard) { - if (this.dashboard?.id.id !== dashboard.id.id) { - this.dashboard = this.dashboardUtils.validateAndUpdateDashboard(dashboard); - } - - return Object.keys(this.dashboard.configuration.states); - } else { - return []; - } - }) - ); - } - - private setupFilteredDashboardStates() { - this.targetDashboardStateSearchText = ''; - this.filteredDashboardStates = this.actionTypeFormGroup.get('targetDashboardStateId').valueChanges - .pipe( - startWith(''), - map(value => value ? value : ''), - mergeMap(name => this.fetchDashboardStates(name)), - takeUntil(this.destroy$) - ); - } - - private fetchDashboardStates(searchText?: string): Observable> { - this.targetDashboardStateSearchText = searchText; - if (this.widgetActionFormGroup.get('type').value === WidgetActionType.openDashboard) { - return this.selectedDashboardStateIds.pipe( - map(stateIds => { - const result = searchText ? stateIds.filter(this.createFilterForDashboardState(searchText)) : stateIds; - if (result && result.length) { - return result; - } else { - return [searchText]; - } - }) - ); - } else { - return of(this.data.callbacks.fetchDashboardStates(searchText)); - } - } - - private createFilterForDashboardState(query: string): (stateId: string) => boolean { - const lowercaseQuery = query.toLowerCase(); - return stateId => stateId.toLowerCase().indexOf(lowercaseQuery) === 0; - } - - public clearTargetDashboardState(value: string = '') { - this.dashboardStateInput.nativeElement.value = value; - this.actionTypeFormGroup.get('targetDashboardStateId').patchValue(value, {emitEvent: true}); - setTimeout(() => { - this.dashboardStateInput.nativeElement.blur(); - this.dashboardStateInput.nativeElement.focus(); - }, 0); - } - private validateActionName(): ValidatorFn { return (c: UntypedFormControl) => { const newName = c.value; @@ -474,53 +201,16 @@ export class WidgetActionDialogComponent extends DialogComponent -
+
diff --git a/ui-ngx/src/app/modules/home/components/widget/action/custom-action-pretty-editor.component.scss b/ui-ngx/src/app/modules/home/components/widget/config/action/custom-action-pretty-editor.component.scss similarity index 96% rename from ui-ngx/src/app/modules/home/components/widget/action/custom-action-pretty-editor.component.scss rename to ui-ngx/src/app/modules/home/components/widget/config/action/custom-action-pretty-editor.component.scss index 6af29b3cff..4087b33aa3 100644 --- a/ui-ngx/src/app/modules/home/components/widget/action/custom-action-pretty-editor.component.scss +++ b/ui-ngx/src/app/modules/home/components/widget/config/action/custom-action-pretty-editor.component.scss @@ -64,7 +64,7 @@ .gutter.gutter-horizontal { cursor: col-resize; - background-image: url("../../../../../../assets/split.js/grips/vertical.png"); + background-image: url("../../../../../../../assets/split.js/grips/vertical.png"); } .tb-split.tb-split-horizontal, diff --git a/ui-ngx/src/app/modules/home/components/widget/action/custom-action-pretty-editor.component.ts b/ui-ngx/src/app/modules/home/components/widget/config/action/custom-action-pretty-editor.component.ts similarity index 96% rename from ui-ngx/src/app/modules/home/components/widget/action/custom-action-pretty-editor.component.ts rename to ui-ngx/src/app/modules/home/components/widget/config/action/custom-action-pretty-editor.component.ts index 47178013ae..d18ec34183 100644 --- a/ui-ngx/src/app/modules/home/components/widget/action/custom-action-pretty-editor.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/config/action/custom-action-pretty-editor.component.ts @@ -15,7 +15,7 @@ /// // eslint-disable-next-line @typescript-eslint/triple-slash-reference -/// +/// import { AfterViewInit, @@ -35,7 +35,7 @@ import { Store } from '@ngrx/store'; import { AppState } from '@core/core.state'; import { combineLatest } from 'rxjs'; import { CustomActionDescriptor } from '@shared/models/widget.models'; -import { CustomPrettyActionEditorCompleter } from '@home/components/widget/action/custom-action.models'; +import { CustomPrettyActionEditorCompleter } from '@home/components/widget/config/action/custom-action.models'; @Component({ selector: 'tb-custom-action-pretty-editor', diff --git a/ui-ngx/src/app/modules/home/components/widget/action/custom-action-pretty-resources-tabs.component.html b/ui-ngx/src/app/modules/home/components/widget/config/action/custom-action-pretty-resources-tabs.component.html similarity index 98% rename from ui-ngx/src/app/modules/home/components/widget/action/custom-action-pretty-resources-tabs.component.html rename to ui-ngx/src/app/modules/home/components/widget/config/action/custom-action-pretty-resources-tabs.component.html index 5145fc13ce..f9610ecbee 100644 --- a/ui-ngx/src/app/modules/home/components/widget/action/custom-action-pretty-resources-tabs.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/config/action/custom-action-pretty-resources-tabs.component.html @@ -100,6 +100,7 @@ [disableUndefinedCheck]="true" [validationArgs]="[]" [editorCompleter]="customPrettyActionEditorCompleter" + functionTitle="{{ 'widget-action.custom-pretty-function' | translate }}" helpId="widget/action/custom_pretty_action_fn"> diff --git a/ui-ngx/src/app/modules/home/components/widget/action/custom-action-pretty-resources-tabs.component.scss b/ui-ngx/src/app/modules/home/components/widget/config/action/custom-action-pretty-resources-tabs.component.scss similarity index 100% rename from ui-ngx/src/app/modules/home/components/widget/action/custom-action-pretty-resources-tabs.component.scss rename to ui-ngx/src/app/modules/home/components/widget/config/action/custom-action-pretty-resources-tabs.component.scss diff --git a/ui-ngx/src/app/modules/home/components/widget/action/custom-action-pretty-resources-tabs.component.ts b/ui-ngx/src/app/modules/home/components/widget/config/action/custom-action-pretty-resources-tabs.component.ts similarity index 99% rename from ui-ngx/src/app/modules/home/components/widget/action/custom-action-pretty-resources-tabs.component.ts rename to ui-ngx/src/app/modules/home/components/widget/config/action/custom-action-pretty-resources-tabs.component.ts index 71bb0a4a2e..a5beaa7f7a 100644 --- a/ui-ngx/src/app/modules/home/components/widget/action/custom-action-pretty-resources-tabs.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/config/action/custom-action-pretty-resources-tabs.component.ts @@ -35,7 +35,7 @@ import { CustomActionDescriptor } from '@shared/models/widget.models'; import { Ace } from 'ace-builds'; import { CancelAnimationFrame, RafService } from '@core/services/raf.service'; import { ResizeObserver } from '@juggle/resize-observer'; -import { CustomPrettyActionEditorCompleter } from '@home/components/widget/action/custom-action.models'; +import { CustomPrettyActionEditorCompleter } from '@home/components/widget/config/action/custom-action.models'; import { Observable } from 'rxjs/internal/Observable'; import { forkJoin, from } from 'rxjs'; import { map, tap } from 'rxjs/operators'; diff --git a/ui-ngx/src/app/modules/home/components/widget/action/custom-action.models.ts b/ui-ngx/src/app/modules/home/components/widget/config/action/custom-action.models.ts similarity index 71% rename from ui-ngx/src/app/modules/home/components/widget/action/custom-action.models.ts rename to ui-ngx/src/app/modules/home/components/widget/config/action/custom-action.models.ts index d9083bfe12..f1c3b98c74 100644 --- a/ui-ngx/src/app/modules/home/components/widget/action/custom-action.models.ts +++ b/ui-ngx/src/app/modules/home/components/widget/config/action/custom-action.models.ts @@ -17,6 +17,11 @@ import { TbEditorCompleter, TbEditorCompletions } from '@shared/models/ace/completion.models'; import { widgetContextCompletions } from '@shared/models/ace/widget-completion.models'; import { entityIdHref, entityTypeHref, serviceCompletions } from '@shared/models/ace/service-completion.models'; +import { CustomActionDescriptor, WidgetAction } from '@shared/models/widget.models'; +import { deepClone, isDefined, isUndefined } from '@core/utils'; +import customSampleJs from '!raw-loader!./custom-sample-js.raw'; +import customSampleCss from '!raw-loader!./custom-sample-css.raw'; +import customSampleHtml from '!raw-loader!./custom-sample-html.raw'; const customActionCompletions: TbEditorCompletions = { ...{ @@ -73,5 +78,24 @@ const customPrettyActionCompletions: TbEditorCompletions = { ...customActionCompletions }; +export const toCustomAction = (action: WidgetAction): CustomActionDescriptor => { + let result: CustomActionDescriptor; + if (!action || (isUndefined(action.customFunction) && isUndefined(action.customHtml) && isUndefined(action.customCss))) { + result = { + customHtml: customSampleHtml, + customCss: customSampleCss, + customFunction: customSampleJs + }; + } else { + result = { + customHtml: action.customHtml, + customCss: action.customCss, + customFunction: action.customFunction + }; + } + result.customResources = action && isDefined(action.customResources) ? deepClone(action.customResources) : []; + return result; +}; + export const CustomActionEditorCompleter = new TbEditorCompleter(customActionCompletions); export const CustomPrettyActionEditorCompleter = new TbEditorCompleter(customPrettyActionCompletions); diff --git a/ui-ngx/src/app/modules/home/components/widget/action/custom-sample-css.raw b/ui-ngx/src/app/modules/home/components/widget/config/action/custom-sample-css.raw similarity index 100% rename from ui-ngx/src/app/modules/home/components/widget/action/custom-sample-css.raw rename to ui-ngx/src/app/modules/home/components/widget/config/action/custom-sample-css.raw diff --git a/ui-ngx/src/app/modules/home/components/widget/action/custom-sample-html.raw b/ui-ngx/src/app/modules/home/components/widget/config/action/custom-sample-html.raw similarity index 100% rename from ui-ngx/src/app/modules/home/components/widget/action/custom-sample-html.raw rename to ui-ngx/src/app/modules/home/components/widget/config/action/custom-sample-html.raw diff --git a/ui-ngx/src/app/modules/home/components/widget/action/custom-sample-js.raw b/ui-ngx/src/app/modules/home/components/widget/config/action/custom-sample-js.raw similarity index 100% rename from ui-ngx/src/app/modules/home/components/widget/action/custom-sample-js.raw rename to ui-ngx/src/app/modules/home/components/widget/config/action/custom-sample-js.raw diff --git a/ui-ngx/src/app/modules/home/components/widget/action/mobile-action-editor.component.html b/ui-ngx/src/app/modules/home/components/widget/config/action/mobile-action-editor.component.html similarity index 74% rename from ui-ngx/src/app/modules/home/components/widget/action/mobile-action-editor.component.html rename to ui-ngx/src/app/modules/home/components/widget/config/action/mobile-action-editor.component.html index 4338061a2a..458e619185 100644 --- a/ui-ngx/src/app/modules/home/components/widget/action/mobile-action-editor.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/config/action/mobile-action-editor.component.html @@ -15,19 +15,27 @@ limitations under the License. --> -
- - widget-action.mobile.action-type - - - {{ mobileActionTypeTranslations.get(mobileActionType[actionType]) | translate }} - - - - {{ 'widget-action.mobile.action-type-required' | translate }} - - -
+
+
+
{{ 'widget-action.mobile.action-type' | translate }}*
+ + + + {{ mobileActionTypeTranslations.get(mobileActionType[actionType]) | translate }} + + + + warning + + +
+ @@ -37,6 +45,7 @@ [functionArgs]="['$event', 'widgetContext', 'entityId', 'entityName', 'additionalParams', 'entityLabel']" [globalVariables]="functionScopeVariables" [editorCompleter]="customActionEditorCompleter" + hideBrackets helpId="widget/action/mobile_get_location_fn" > @@ -47,6 +56,7 @@ [functionArgs]="['$event', 'widgetContext', 'entityId', 'entityName', 'additionalParams', 'entityLabel']" [globalVariables]="functionScopeVariables" [editorCompleter]="customActionEditorCompleter" + hideBrackets helpId="widget/action/mobile_get_phone_number_fn" > @@ -60,6 +70,7 @@ [functionArgs]="['imageUrl', '$event', 'widgetContext', 'entityId', 'entityName', 'additionalParams', 'entityLabel']" [globalVariables]="functionScopeVariables" [editorCompleter]="customActionEditorCompleter" + hideBrackets helpId="widget/action/mobile_process_image_fn" > @@ -70,6 +81,7 @@ [functionArgs]="['code', 'format', '$event', 'widgetContext', 'entityId', 'entityName', 'additionalParams', 'entityLabel']" [globalVariables]="functionScopeVariables" [editorCompleter]="customActionEditorCompleter" + hideBrackets helpId="widget/action/mobile_process_qr_code_fn" > @@ -80,6 +92,7 @@ [functionArgs]="['latitude', 'longitude', '$event', 'widgetContext', 'entityId', 'entityName', 'additionalParams', 'entityLabel']" [globalVariables]="functionScopeVariables" [editorCompleter]="customActionEditorCompleter" + hideBrackets helpId="widget/action/mobile_process_location_fn" > @@ -93,24 +106,27 @@ [functionArgs]="['launched', '$event', 'widgetContext', 'entityId', 'entityName', 'additionalParams', 'entityLabel']" [globalVariables]="functionScopeVariables" [editorCompleter]="customActionEditorCompleter" + hideBrackets helpId="widget/action/mobile_process_launch_result_fn" > -
+
diff --git a/ui-ngx/src/app/modules/home/components/widget/action/mobile-action-editor.component.ts b/ui-ngx/src/app/modules/home/components/widget/config/action/mobile-action-editor.component.ts similarity index 91% rename from ui-ngx/src/app/modules/home/components/widget/action/mobile-action-editor.component.ts rename to ui-ngx/src/app/modules/home/components/widget/config/action/mobile-action-editor.component.ts index af028ac0ae..a95e34bec9 100644 --- a/ui-ngx/src/app/modules/home/components/widget/action/mobile-action-editor.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/config/action/mobile-action-editor.component.ts @@ -14,18 +14,22 @@ /// limitations under the License. /// -import { Component, forwardRef, Input, OnInit, QueryList, ViewChildren } from '@angular/core'; -import { ControlValueAccessor, UntypedFormBuilder, UntypedFormGroup, NG_VALUE_ACCESSOR, Validators } from '@angular/forms'; -import { Store } from '@ngrx/store'; -import { AppState } from '@app/core/core.state'; +import { Component, forwardRef, Input, OnInit } from '@angular/core'; +import { + ControlValueAccessor, + NG_VALUE_ACCESSOR, + UntypedFormBuilder, + UntypedFormGroup, + Validators +} from '@angular/forms'; import { coerceBooleanProperty } from '@angular/cdk/coercion'; import { + WidgetActionType, WidgetMobileActionDescriptor, WidgetMobileActionType, widgetMobileActionTypeTranslationMap } from '@shared/models/widget.models'; -import { CustomActionEditorCompleter } from '@home/components/widget/action/custom-action.models'; -import { JsFuncComponent } from '@shared/components/js-func.component'; +import { CustomActionEditorCompleter } from '@home/components/widget/config/action/custom-action.models'; import { getDefaultGetLocationFunction, getDefaultGetPhoneNumberFunction, @@ -35,7 +39,7 @@ import { getDefaultProcessLaunchResultFunction, getDefaultProcessLocationFunction, getDefaultProcessQrCodeFunction -} from '@home/components/widget/action/mobile-action-editor.models'; +} from '@home/components/widget/config/action/mobile-action-editor.models'; import { WidgetService } from '@core/http/widget.service'; @Component({ @@ -50,8 +54,6 @@ import { WidgetService } from '@core/http/widget.service'; }) export class MobileActionEditorComponent implements ControlValueAccessor, OnInit { - @ViewChildren(JsFuncComponent) jsFuncComponents: QueryList; - mobileActionTypes = Object.keys(WidgetMobileActionType); mobileActionTypeTranslations = widgetMobileActionTypeTranslationMap; mobileActionType = WidgetMobileActionType; @@ -75,10 +77,9 @@ export class MobileActionEditorComponent implements ControlValueAccessor, OnInit @Input() disabled: boolean; - private propagateChange = (v: any) => { }; + private propagateChange = (_v: any) => { }; - constructor(private store: Store, - private fb: UntypedFormBuilder, + constructor(private fb: UntypedFormBuilder, private widgetService: WidgetService) { this.functionScopeVariables = this.widgetService.getWidgetScopeVariables(); } @@ -87,7 +88,7 @@ export class MobileActionEditorComponent implements ControlValueAccessor, OnInit this.propagateChange = fn; } - registerOnTouched(fn: any): void { + registerOnTouched(_fn: any): void { } ngOnInit() { @@ -158,7 +159,7 @@ export class MobileActionEditorComponent implements ControlValueAccessor, OnInit } this.mobileActionTypeFormGroup = this.fb.group({}); if (type) { - let processLaunchResultFunction; + let processLaunchResultFunction: string; switch (type) { case WidgetMobileActionType.takePictureFromGallery: case WidgetMobileActionType.takePhoto: @@ -253,9 +254,5 @@ export class MobileActionEditorComponent implements ControlValueAccessor, OnInit }); } - public validateOnSubmit() { - for (const jsFuncComponent of this.jsFuncComponents.toArray()) { - jsFuncComponent.validateOnSubmit(); - } - } + protected readonly WidgetActionType = WidgetActionType; } diff --git a/ui-ngx/src/app/modules/home/components/widget/action/mobile-action-editor.models.ts b/ui-ngx/src/app/modules/home/components/widget/config/action/mobile-action-editor.models.ts similarity index 92% rename from ui-ngx/src/app/modules/home/components/widget/action/mobile-action-editor.models.ts rename to ui-ngx/src/app/modules/home/components/widget/config/action/mobile-action-editor.models.ts index 2a7270a14d..5abf69c523 100644 --- a/ui-ngx/src/app/modules/home/components/widget/action/mobile-action-editor.models.ts +++ b/ui-ngx/src/app/modules/home/components/widget/config/action/mobile-action-editor.models.ts @@ -24,6 +24,7 @@ const processImageFunctionTemplate = '\n' + 'function showImageDialog(title, imageUrl) {\n' + ' setTimeout(function() {\n' + + // eslint-disable-next-line max-len ' widgetContext.customDialog.customDialog(imageDialogTemplate, ImageDialogController, {imageUrl: imageUrl, title: title}).subscribe();\n' + ' }, 100);\n' + '}\n' + @@ -82,6 +83,7 @@ const processImageFunctionTemplate = '}\n'; const processLaunchResultFunctionTemplate = + // eslint-disable-next-line max-len '// Optional function body to process result of attempt to launch external mobile application (for ex. map application or phone call application). \n' + '// - launched - boolean value indicating if the external application was successfully launched.\n\n' + 'showLaunchStatusDialog(\'--TITLE--\', launched);\n' + @@ -166,6 +168,7 @@ const getLocationFunctionTemplate = '\n' + 'function getLocationFromEntityAttributes() {\n' + ' if (entityId) {\n' + + // eslint-disable-next-line max-len ' return widgetContext.attributeService.getEntityAttributes(entityId, \'SERVER_SCOPE\', [\'latitude\', \'longitude\']).pipe(widgetContext.rxjs.map(function(attributeData) {\n' + ' var res = [0,0];\n' + ' if (attributeData && attributeData.length === 2) {\n' + @@ -188,6 +191,7 @@ const getPhoneNumberFunctionTemplate = '\n' + 'function getPhoneNumberFromEntityAttributes() {\n' + ' if (entityId) {\n' + + // eslint-disable-next-line max-len ' return widgetContext.attributeService.getEntityAttributes(entityId, \'SERVER_SCOPE\', [\'phone\']).pipe(widgetContext.rxjs.map(function(attributeData) {\n' + ' var res = 0;\n' + ' if (attributeData && attributeData.length === 1) {\n' + @@ -200,8 +204,8 @@ const getPhoneNumberFunctionTemplate = ' }\n' + '}\n'; -export function getDefaultProcessImageFunction(type: WidgetMobileActionType): string { - let title; +export const getDefaultProcessImageFunction = (type: WidgetMobileActionType): string => { + let title: string; switch (type) { case WidgetMobileActionType.takePictureFromGallery: title = 'Gallery picture'; @@ -214,10 +218,10 @@ export function getDefaultProcessImageFunction(type: WidgetMobileActionType): st break; } return processImageFunctionTemplate.replace('--TITLE--', title); -} +}; -export function getDefaultProcessLaunchResultFunction(type: WidgetMobileActionType): string { - let title; +export const getDefaultProcessLaunchResultFunction = (type: WidgetMobileActionType): string => { + let title: string; switch (type) { case WidgetMobileActionType.mapLocation: title = 'Map location'; @@ -230,25 +234,17 @@ export function getDefaultProcessLaunchResultFunction(type: WidgetMobileActionTy break; } return processLaunchResultFunctionTemplate.replace('--TITLE--', title); -} +}; -export function getDefaultProcessQrCodeFunction() { - return processQrCodeFunction; -} +export const getDefaultProcessQrCodeFunction = () => processQrCodeFunction; -export function getDefaultProcessLocationFunction() { - return processLocationFunction; -} +export const getDefaultProcessLocationFunction = () => processLocationFunction; -export function getDefaultGetLocationFunction() { - return getLocationFunctionTemplate; -} +export const getDefaultGetLocationFunction = () => getLocationFunctionTemplate; -export function getDefaultGetPhoneNumberFunction() { - return getPhoneNumberFunctionTemplate; -} +export const getDefaultGetPhoneNumberFunction = () => getPhoneNumberFunctionTemplate; -export function getDefaultHandleEmptyResultFunction(type: WidgetMobileActionType): string { +export const getDefaultHandleEmptyResultFunction = (type: WidgetMobileActionType): string => { let message = 'Mobile action was cancelled!'; switch (type) { case WidgetMobileActionType.takePictureFromGallery: @@ -277,9 +273,9 @@ export function getDefaultHandleEmptyResultFunction(type: WidgetMobileActionType break; } return handleEmptyResultFunctionTemplate.replace('--MESSAGE--', message); -} +}; -export function getDefaultHandleErrorFunction(type: WidgetMobileActionType): string { +export const getDefaultHandleErrorFunction = (type: WidgetMobileActionType): string => { let title = 'Mobile action failed'; switch (type) { case WidgetMobileActionType.takePictureFromGallery: @@ -308,4 +304,4 @@ export function getDefaultHandleErrorFunction(type: WidgetMobileActionType): str break; } return handleErrorFunctionTemplate.replace('--TITLE--', title); -} +}; diff --git a/ui-ngx/src/app/modules/home/components/widget/config/action/widget-action.component.html b/ui-ngx/src/app/modules/home/components/widget/config/action/widget-action.component.html new file mode 100644 index 0000000000..35ca3f3144 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/config/action/widget-action.component.html @@ -0,0 +1,234 @@ + +
+
+
widget-config.action
+ + + + {{ widgetActionTypeTranslations.get(widgetActionType[actionType]) | translate }} + + + +
+ + +
+
{{ 'widget-action.target-dashboard' | translate }}*
+ +
+
+ +
+
{{ 'widget-action.target-dashboard-state' | translate }} + {{widgetActionFormGroup.get('type').value === widgetActionType.openDashboardState ? '*' : ''}}
+ + + + + warning + + + + + + + +
+
+ +
+ + {{ 'widget-action.open-right-layout' | translate }} + +
+
+ +
+ + {{ 'widget-action.open-new-browser-tab' | translate }} + +
+
+ +
+ + {{ 'widget-action.set-entity-from-widget' | translate }} + +
+
+
{{ 'alias.state-entity-parameter-name' | translate }}
+ + + +
+
+ +
+
{{ 'widget-action.state-display-type' | translate }}
+ + + + {{ stateDisplayTypeName(displayType) }} + + + +
+ + +
+
{{ 'widget-action.dialog-title' | translate }}
+ + + +
+
+ + {{ 'widget-action.dialog-hide-dashboard-toolbar' | translate }} + +
+
+
{{ 'widget-action.dialog-width' | translate }}
+ + + + warning + + +
+
+
{{ 'widget-action.dialog-height' | translate }}
+ + + + warning + + +
+
+ +
+
{{ 'widget-action.popover-preferred-placement' | translate }}
+ + + + {{ popoverPlacementName(placement) }} + + + +
+
+ + {{ 'widget-action.popover-hide-on-click-outside' | translate }} + +
+
+ + {{ 'widget-action.popover-hide-dashboard-toolbar' | translate }} + +
+
+
{{ 'widget-action.popover-width' | translate }}
+ + +
+
+
{{ 'widget-action.popover-height' | translate }}
+ + +
+ +
+ + +
+
+ + + + + + + + + + + +
+
diff --git a/ui-ngx/src/app/modules/home/components/widget/config/action/widget-action.component.ts b/ui-ngx/src/app/modules/home/components/widget/config/action/widget-action.component.ts new file mode 100644 index 0000000000..ed7690fe28 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/config/action/widget-action.component.ts @@ -0,0 +1,463 @@ +/// +/// Copyright © 2016-2024 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 { + ControlValueAccessor, + NG_VALIDATORS, + NG_VALUE_ACCESSOR, + UntypedFormBuilder, + UntypedFormControl, + UntypedFormGroup, + Validator, + Validators +} from '@angular/forms'; +import { Component, ElementRef, forwardRef, Input, OnInit, ViewChild } from '@angular/core'; +import { + WidgetAction, + WidgetActionType, + widgetActionTypeTranslationMap, + widgetType +} from '@shared/models/widget.models'; +import { WidgetService } from '@core/http/widget.service'; +import { WidgetActionCallbacks } from '@home/components/widget/action/manage-widget-actions.component.models'; +import { map, mergeMap, share, startWith, takeUntil, tap } from 'rxjs/operators'; +import { Observable, of, Subject, Subscription } from 'rxjs'; +import { Dashboard } from '@shared/models/dashboard.models'; +import { DashboardService } from '@core/http/dashboard.service'; +import { DashboardUtilsService } from '@core/services/dashboard-utils.service'; +import { isDefinedAndNotNull } from '@core/utils'; +import { TranslateService } from '@ngx-translate/core'; +import { PopoverPlacement, PopoverPlacements } from '@shared/components/popover.models'; +import { + CustomActionEditorCompleter, + toCustomAction +} from '@home/components/widget/config/action/custom-action.models'; + +const stateDisplayTypes = ['normal', 'separateDialog', 'popover'] as const; +type stateDisplayTypeTuple = typeof stateDisplayTypes; +export type stateDisplayType = stateDisplayTypeTuple[number]; + +const stateDisplayTypesTranslations = new Map( + [ + ['normal', 'widget-action.open-normal'], + ['separateDialog', 'widget-action.open-in-separate-dialog'], + ['popover', 'widget-action.open-in-popover'], + ] +); + +@Component({ + selector: 'tb-widget-action', + templateUrl: './widget-action.component.html', + styleUrls: [], + providers: [ + { + provide: NG_VALUE_ACCESSOR, + useExisting: forwardRef(() => WidgetActionComponent), + multi: true + }, + { + provide: NG_VALIDATORS, + useExisting: forwardRef(() => WidgetActionComponent), + multi: true, + } + ] +}) +export class WidgetActionComponent implements ControlValueAccessor, OnInit, Validator { + + @ViewChild('dashboardStateInput', {static: false}) dashboardStateInput: ElementRef; + + @Input() + disabled: boolean; + + @Input() + widgetType: widgetType; + + @Input() + callbacks: WidgetActionCallbacks; + + widgetActionTypes = Object.keys(WidgetActionType); + widgetActionTypeTranslations = widgetActionTypeTranslationMap; + widgetActionType = WidgetActionType; + + allStateDisplayTypes = stateDisplayTypes; + allPopoverPlacements = PopoverPlacements; + + WidgetType = widgetType; + + filteredDashboardStates: Observable>; + targetDashboardStateSearchText = ''; + selectedDashboardStateIds: Observable>; + + customActionEditorCompleter = CustomActionEditorCompleter; + + functionScopeVariables = this.widgetService.getWidgetScopeVariables(); + + widgetActionFormGroup: UntypedFormGroup; + actionTypeFormGroup: UntypedFormGroup; + stateDisplayTypeFormGroup: UntypedFormGroup; + + private propagateChange = (_val: any) => {}; + private actionTypeFormGroupSubscriptions: Subscription[] = []; + private stateDisplayTypeFormGroupSubscriptions: Subscription[] = []; + private destroy$ = new Subject(); + private dashboard: Dashboard; + + constructor(private fb: UntypedFormBuilder, + private widgetService: WidgetService, + private dashboardService: DashboardService, + private dashboardUtils: DashboardUtilsService, + private translate: TranslateService) { + } + + registerOnChange(fn: any): void { + this.propagateChange = fn; + } + + registerOnTouched(_fn: any): void { + } + + setDisabledState(isDisabled: boolean): void { + this.disabled = isDisabled; + if (this.disabled) { + this.widgetActionFormGroup.disable({emitEvent: false}); + if (this.actionTypeFormGroup) { + this.actionTypeFormGroup.disable({emitEvent: false}); + } + if (this.stateDisplayTypeFormGroup) { + this.stateDisplayTypeFormGroup.disable({emitEvent: false}); + } + } else { + this.widgetActionFormGroup.enable({emitEvent: false}); + } + } + + ngOnInit() { + this.widgetActionFormGroup = this.fb.group({}); + this.widgetActionFormGroup.addControl('type', + this.fb.control(null, [Validators.required])); + this.widgetActionFormGroup.get('type').valueChanges.pipe( + takeUntil(this.destroy$) + ).subscribe((type: WidgetActionType) => { + this.updateActionTypeFormGroup(type); + }); + this.widgetActionFormGroup.valueChanges.pipe( + takeUntil(this.destroy$) + ).subscribe(() => { + this.widgetActionUpdated(); + }); + } + + writeValue(widgetAction?: WidgetAction): void { + this.widgetActionFormGroup.patchValue({ + type: widgetAction?.type + }, {emitEvent: false}); + this.updateActionTypeFormGroup(widgetAction?.type, widgetAction); + } + + validate(_c: UntypedFormControl) { + return (this.widgetActionFormGroup.valid && + this.actionTypeFormGroup.valid && (!this.stateDisplayTypeFormGroup || this.stateDisplayTypeFormGroup.valid)) ? null : { + widgetAction: { + valid: false, + } + }; + } + + clearTargetDashboardState(value: string = '') { + this.dashboardStateInput.nativeElement.value = value; + this.actionTypeFormGroup.get('targetDashboardStateId').patchValue(value, {emitEvent: true}); + setTimeout(() => { + this.dashboardStateInput.nativeElement.blur(); + this.dashboardStateInput.nativeElement.focus(); + }, 0); + } + + onDashboardStateInputFocus(): void { + this.actionTypeFormGroup.get('targetDashboardStateId').updateValueAndValidity({onlySelf: true, emitEvent: true}); + } + + stateDisplayTypeName(displayType: stateDisplayType): string { + if (displayType) { + return this.translate.instant(stateDisplayTypesTranslations.get(displayType)) + ''; + } else { + return ''; + } + } + + popoverPlacementName(placement: PopoverPlacement): string { + if (placement) { + return this.translate.instant(`widget-action.popover-placement-${placement}`) + ''; + } else { + return ''; + } + } + + private updateActionTypeFormGroup(type?: WidgetActionType, action?: WidgetAction) { + this.actionTypeFormGroupSubscriptions.forEach(s => s.unsubscribe()); + this.actionTypeFormGroupSubscriptions.length = 0; + this.actionTypeFormGroup = this.fb.group({}); + if (type) { + switch (type) { + case WidgetActionType.openDashboard: + case WidgetActionType.openDashboardState: + case WidgetActionType.updateDashboardState: + this.actionTypeFormGroup.addControl( + 'targetDashboardStateId', + this.fb.control(action ? action.targetDashboardStateId : null, + type === WidgetActionType.openDashboardState ? [Validators.required] : []) + ); + this.actionTypeFormGroup.addControl( + 'setEntityId', + this.fb.control(this.widgetType === widgetType.static ? false : action ? action.setEntityId : true, []) + ); + this.actionTypeFormGroup.addControl( + 'stateEntityParamName', + this.fb.control(action ? action.stateEntityParamName : null, []) + ); + if (type === WidgetActionType.openDashboard) { + this.actionTypeFormGroup.addControl( + 'openNewBrowserTab', + this.fb.control(action ? action.openNewBrowserTab : false, []) + ); + this.actionTypeFormGroup.addControl( + 'targetDashboardId', + this.fb.control(action ? action.targetDashboardId : null, + [Validators.required]) + ); + this.setupSelectedDashboardStateIds(); + } else { + if (type === WidgetActionType.openDashboardState) { + const displayType = this.getStateDisplayType(action); + this.actionTypeFormGroup.addControl( + 'stateDisplayType', + this.fb.control(this.getStateDisplayType(action), [Validators.required]) + ); + this.updateStateDisplayTypeFormGroup(displayType, action); + this.actionTypeFormGroupSubscriptions.push( + this.actionTypeFormGroup.get('stateDisplayType').valueChanges.pipe( + takeUntil(this.destroy$) + ).subscribe((displayTypeValue: stateDisplayType) => { + this.updateStateDisplayTypeFormGroup(displayTypeValue); + }) + ); + } + this.actionTypeFormGroup.addControl( + 'openRightLayout', + this.fb.control(action ? action.openRightLayout : false, []) + ); + } + this.setupFilteredDashboardStates(); + break; + case WidgetActionType.custom: + this.actionTypeFormGroup.addControl( + 'customFunction', + this.fb.control(action ? action.customFunction : null, []) + ); + break; + case WidgetActionType.customPretty: + this.actionTypeFormGroup.addControl( + 'customAction', + this.fb.control(toCustomAction(action), [Validators.required]) + ); + break; + case WidgetActionType.mobileAction: + this.actionTypeFormGroup.addControl( + 'mobileAction', + this.fb.control(action ? action.mobileAction : null, [Validators.required]) + ); + break; + } + } + this.actionTypeFormGroupSubscriptions.push( + this.actionTypeFormGroup.valueChanges.pipe( + takeUntil(this.destroy$) + ).subscribe(() => { + this.widgetActionUpdated(); + }) + ); + } + + private updateStateDisplayTypeFormGroup(displayType?: stateDisplayType, action?: WidgetAction) { + this.stateDisplayTypeFormGroupSubscriptions.forEach(s => s.unsubscribe()); + this.stateDisplayTypeFormGroupSubscriptions.length = 0; + this.stateDisplayTypeFormGroup = this.fb.group({}); + if (displayType) { + switch (displayType) { + case 'normal': + break; + case 'separateDialog': + this.stateDisplayTypeFormGroup.addControl( + 'dialogTitle', + this.fb.control(action ? action.dialogTitle : '', []) + ); + this.stateDisplayTypeFormGroup.addControl( + 'dialogHideDashboardToolbar', + this.fb.control(action && isDefinedAndNotNull(action.dialogHideDashboardToolbar) + ? action.dialogHideDashboardToolbar : true, []) + ); + this.stateDisplayTypeFormGroup.addControl( + 'dialogWidth', + this.fb.control(action ? action.dialogWidth : null, [Validators.min(1), Validators.max(100)]) + ); + this.stateDisplayTypeFormGroup.addControl( + 'dialogHeight', + this.fb.control(action ? action.dialogHeight : null, [Validators.min(1), Validators.max(100)]) + ); + break; + case 'popover': + this.stateDisplayTypeFormGroup.addControl( + 'popoverPreferredPlacement', + this.fb.control(action && isDefinedAndNotNull(action.popoverPreferredPlacement) + ? action.popoverPreferredPlacement : 'top', []) + ); + this.stateDisplayTypeFormGroup.addControl( + 'popoverHideOnClickOutside', + this.fb.control(action && isDefinedAndNotNull(action.popoverHideOnClickOutside) + ? action.popoverHideOnClickOutside : true, []) + ); + this.stateDisplayTypeFormGroup.addControl( + 'popoverHideDashboardToolbar', + this.fb.control(action && isDefinedAndNotNull(action.popoverHideDashboardToolbar) + ? action.popoverHideDashboardToolbar : true, []) + ); + this.stateDisplayTypeFormGroup.addControl( + 'popoverWidth', + this.fb.control(action && isDefinedAndNotNull(action.popoverWidth) ? action.popoverWidth : '25vw', []) + ); + this.stateDisplayTypeFormGroup.addControl( + 'popoverHeight', + this.fb.control(action && isDefinedAndNotNull(action.popoverHeight) ? action.popoverHeight : '25vh', []) + ); + this.stateDisplayTypeFormGroup.addControl( + 'popoverStyle', + this.fb.control(action && isDefinedAndNotNull(action.popoverStyle) ? action.popoverStyle : {}, []) + ); + break; + } + } + this.stateDisplayTypeFormGroupSubscriptions.push( + this.stateDisplayTypeFormGroup.valueChanges.pipe( + takeUntil(this.destroy$) + ).subscribe(() => { + this.widgetActionUpdated(); + }) + ); + } + + private setupSelectedDashboardStateIds() { + this.selectedDashboardStateIds = + this.actionTypeFormGroup.get('targetDashboardId').valueChanges.pipe( + tap((dashboardId) => { + if (!dashboardId) { + this.actionTypeFormGroup.get('targetDashboardStateId') + .patchValue('', {emitEvent: true}); + } + + this.targetDashboardStateSearchText = ''; + }), + mergeMap((dashboardId) => { + if (dashboardId) { + if (this.dashboard?.id.id === dashboardId) { + return of(this.dashboard); + } else { + return this.dashboardService.getDashboard(dashboardId); + } + } else { + return of(null); + } + }), + map((dashboard: Dashboard) => { + if (dashboard) { + if (this.dashboard?.id.id !== dashboard.id.id) { + this.dashboard = this.dashboardUtils.validateAndUpdateDashboard(dashboard); + } + + return Object.keys(this.dashboard.configuration.states); + } else { + return []; + } + }), + share() + ); + } + + private setupFilteredDashboardStates() { + this.targetDashboardStateSearchText = ''; + this.filteredDashboardStates = this.actionTypeFormGroup.get('targetDashboardStateId').valueChanges + .pipe( + startWith(''), + map(value => value ? value : ''), + mergeMap(name => this.fetchDashboardStates(name)), + takeUntil(this.destroy$) + ); + } + + private fetchDashboardStates(searchText?: string): Observable> { + this.targetDashboardStateSearchText = searchText; + if (this.widgetActionFormGroup.get('type').value === WidgetActionType.openDashboard) { + return this.selectedDashboardStateIds.pipe( + map(stateIds => { + const result = searchText ? stateIds.filter(this.createFilterForDashboardState(searchText)) : stateIds; + if (result && result.length) { + return result; + } else { + return [searchText]; + } + }) + ); + } else { + return of(this.callbacks.fetchDashboardStates(searchText)); + } + } + + private createFilterForDashboardState(query: string): (stateId: string) => boolean { + const lowercaseQuery = query.toLowerCase(); + return stateId => stateId.toLowerCase().indexOf(lowercaseQuery) === 0; + } + + private getStateDisplayType(action?: WidgetAction): stateDisplayType { + let res: stateDisplayType = 'normal'; + if (action) { + if (action.openInSeparateDialog) { + res = 'separateDialog'; + } else if (action.openInPopover) { + res = 'popover'; + } + } + return res; + } + + private widgetActionUpdated() { + const type: WidgetActionType = this.widgetActionFormGroup.get('type').value; + let result: WidgetAction; + if (type === WidgetActionType.customPretty) { + result = {...this.widgetActionFormGroup.value, ...this.actionTypeFormGroup.get('customAction').value}; + } else { + result = {...this.widgetActionFormGroup.value, ...this.actionTypeFormGroup.value}; + } + if (this.actionTypeFormGroup.get('stateDisplayType') && + this.actionTypeFormGroup.get('stateDisplayType').value !== 'normal') { + result = {...result, ...this.stateDisplayTypeFormGroup.value}; + result.openInSeparateDialog = this.actionTypeFormGroup.get('stateDisplayType').value === 'separateDialog'; + result.openInPopover = this.actionTypeFormGroup.get('stateDisplayType').value === 'popover'; + } else { + result.openInSeparateDialog = false; + result.openInPopover = false; + } + delete (result as any).stateDisplayType; + this.propagateChange(result); + } +} diff --git a/ui-ngx/src/app/modules/home/components/widget/config/widget-config-components.module.ts b/ui-ngx/src/app/modules/home/components/widget/config/widget-config-components.module.ts index 4470fc1327..7b80b4b088 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/widget-config-components.module.ts +++ b/ui-ngx/src/app/modules/home/components/widget/config/widget-config-components.module.ts @@ -33,6 +33,11 @@ import { WidgetSettingsCommonModule } from '@home/components/widget/lib/settings import { TimewindowStyleComponent } from '@home/components/widget/config/timewindow-style.component'; import { TimewindowStylePanelComponent } from '@home/components/widget/config/timewindow-style-panel.component'; import { TargetDeviceComponent } from '@home/components/widget/config/target-device.component'; +import { WidgetActionComponent } from '@home/components/widget/config/action/widget-action.component'; +import { CustomActionPrettyResourcesTabsComponent } + from '@home/components/widget/config/action/custom-action-pretty-resources-tabs.component'; +import { CustomActionPrettyEditorComponent } from '@home/components/widget/config/action/custom-action-pretty-editor.component'; +import { MobileActionEditorComponent } from '@home/components/widget/config/action/mobile-action-editor.component'; @NgModule({ declarations: @@ -50,7 +55,11 @@ import { TargetDeviceComponent } from '@home/components/widget/config/target-dev TimewindowStyleComponent, TimewindowStylePanelComponent, TimewindowConfigPanelComponent, - WidgetSettingsComponent + WidgetSettingsComponent, + WidgetActionComponent, + CustomActionPrettyResourcesTabsComponent, + CustomActionPrettyEditorComponent, + MobileActionEditorComponent ], imports: [ CommonModule, @@ -73,7 +82,11 @@ import { TargetDeviceComponent } from '@home/components/widget/config/target-dev TimewindowStylePanelComponent, TimewindowConfigPanelComponent, WidgetSettingsComponent, - WidgetSettingsCommonModule + WidgetSettingsCommonModule, + WidgetActionComponent, + CustomActionPrettyResourcesTabsComponent, + CustomActionPrettyEditorComponent, + MobileActionEditorComponent ] }) export class WidgetConfigComponentsModule { } diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/css-size-input.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/css-size-input.component.html new file mode 100644 index 0000000000..31836d433d --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/css-size-input.component.html @@ -0,0 +1,33 @@ + +
+ + + + warning + + + +
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/css-size-input.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/css-size-input.component.ts new file mode 100644 index 0000000000..dcd579e071 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/css-size-input.component.ts @@ -0,0 +1,124 @@ +/// +/// Copyright © 2016-2024 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 { Component, forwardRef, Input, OnInit } from '@angular/core'; +import { + ControlValueAccessor, + NG_VALIDATORS, + NG_VALUE_ACCESSOR, + UntypedFormBuilder, + UntypedFormControl, + UntypedFormGroup, + Validator, + Validators +} from '@angular/forms'; +import { cssUnit, resolveCssSize } from '@shared/models/widget-settings.models'; +import { coerceBoolean } from '@shared/decorators/coercion'; +import { isDefinedAndNotNull } from '@core/utils'; + +@Component({ + selector: 'tb-css-size-input', + templateUrl: './css-size-input.component.html', + styleUrls: [], + providers: [ + { + provide: NG_VALUE_ACCESSOR, + useExisting: forwardRef(() => CssSizeInputComponent), + multi: true + }, + { + provide: NG_VALIDATORS, + useExisting: forwardRef(() => CssSizeInputComponent), + multi: true, + } + ] +}) +export class CssSizeInputComponent implements OnInit, ControlValueAccessor, Validator { + + @Input() + disabled: boolean; + + @Input() + @coerceBoolean() + required = false; + + @Input() + requiredText: string; + + @Input() + @coerceBoolean() + allowEmptyUnit = false; + + cssSizeFormGroup: UntypedFormGroup; + + modelValue: string; + + private propagateChange = null; + + constructor(private fb: UntypedFormBuilder) {} + + ngOnInit(): void { + this.cssSizeFormGroup = this.fb.group({ + size: [null, this.required ? [Validators.required, Validators.min(0)] : [Validators.min(0)]], + unit: [null, []] + }); + this.cssSizeFormGroup.valueChanges.subscribe((value: {size: number; unit: cssUnit}) => { + this.updateModel(value); + }); + } + + registerOnChange(fn: any): void { + this.propagateChange = fn; + } + + registerOnTouched(fn: any): void { + } + + setDisabledState(isDisabled: boolean): void { + this.disabled = isDisabled; + if (this.disabled) { + this.cssSizeFormGroup.disable({emitEvent: false}); + } else { + this.cssSizeFormGroup.enable({emitEvent: false}); + } + } + + writeValue(value: string): void { + this.modelValue = value; + const size = resolveCssSize(value); + this.cssSizeFormGroup.patchValue({ + size: size[0], + unit: size[1] + }, {emitEvent: false}); + } + + validate(_c: UntypedFormControl) { + return this.cssSizeFormGroup.valid ? null : { + cssSize: { + valid: false, + } + }; + } + + private updateModel(value: {size: number; unit: cssUnit}): void { + const result: string = isDefinedAndNotNull(value?.size) && isDefinedAndNotNull(value?.unit) + ? value.size + value.unit : ''; + if (this.modelValue !== result) { + this.modelValue = result; + this.propagateChange(this.modelValue); + } + } +} diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/css-unit-select.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/css-unit-select.component.html index 8455c9b2cf..095310606f 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/css-unit-select.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/css-unit-select.component.html @@ -15,7 +15,7 @@ limitations under the License. --> - + diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/css-unit-select.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/css-unit-select.component.ts index 8c78d26a39..588871b7b9 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/css-unit-select.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/css-unit-select.component.ts @@ -40,6 +40,9 @@ export class CssUnitSelectComponent implements OnInit, ControlValueAccessor { @coerceBoolean() allowEmpty = false; + @Input() + width = '100%'; + cssUnitsList = cssUnits; cssUnitFormControl: UntypedFormControl; diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/widget-settings-common.module.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/widget-settings-common.module.ts index ba08a39bb7..8275f53e54 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/widget-settings-common.module.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/widget-settings-common.module.ts @@ -66,6 +66,7 @@ import { import { RpcUpdateStateSettingsPanelComponent } from '@home/components/widget/lib/settings/common/rpc/rpc-update-state-settings-panel.component'; +import { CssSizeInputComponent } from '@home/components/widget/lib/settings/common/css-size-input.component'; @NgModule({ declarations: [ @@ -76,6 +77,7 @@ import { ColorSettingsComponent, ColorSettingsPanelComponent, CssUnitSelectComponent, + CssSizeInputComponent, DateFormatSelectComponent, DateFormatSettingsPanelComponent, BackgroundSettingsComponent, @@ -106,6 +108,7 @@ import { ColorSettingsComponent, ColorSettingsPanelComponent, CssUnitSelectComponent, + CssSizeInputComponent, DateFormatSelectComponent, DateFormatSettingsPanelComponent, BackgroundSettingsComponent, diff --git a/ui-ngx/src/app/modules/home/components/widget/widget.component.ts b/ui-ngx/src/app/modules/home/components/widget/widget.component.ts index a7fbc64db7..1c029b6524 100644 --- a/ui-ngx/src/app/modules/home/components/widget/widget.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/widget.component.ts @@ -1345,7 +1345,7 @@ export class WidgetComponent extends PageComponent implements OnInit, AfterViewI this.widgetContext.parentDashboard : this.widgetContext.dashboard, popoverComponent: componentRef.instance }, - {width: popoverWidth, height: popoverHeight}, + {width: popoverWidth || '25vw', height: popoverHeight || '25vh'}, popoverStyle, {} ); diff --git a/ui-ngx/src/app/shared/components/dashboard-autocomplete.component.html b/ui-ngx/src/app/shared/components/dashboard-autocomplete.component.html index e9f177e851..5d41da6b4a 100644 --- a/ui-ngx/src/app/shared/components/dashboard-autocomplete.component.html +++ b/ui-ngx/src/app/shared/components/dashboard-autocomplete.component.html @@ -15,9 +15,14 @@ limitations under the License. --> - - {{ label }} + + {{ label }} close + + warning + - + - + > diff --git a/ui-ngx/src/app/shared/components/dashboard-autocomplete.component.ts b/ui-ngx/src/app/shared/components/dashboard-autocomplete.component.ts index 308087bd31..2cdaf2d13c 100644 --- a/ui-ngx/src/app/shared/components/dashboard-autocomplete.component.ts +++ b/ui-ngx/src/app/shared/components/dashboard-autocomplete.component.ts @@ -15,7 +15,13 @@ /// import { AfterViewInit, Component, ElementRef, forwardRef, Input, OnInit, ViewChild } from '@angular/core'; -import { ControlValueAccessor, NG_VALUE_ACCESSOR, UntypedFormBuilder, UntypedFormGroup } from '@angular/forms'; +import { + ControlValueAccessor, + NG_VALUE_ACCESSOR, + UntypedFormBuilder, + UntypedFormGroup, + Validators +} from '@angular/forms'; import { Observable, of } from 'rxjs'; import { PageLink } from '@shared/models/page/page-link'; import { Direction } from '@shared/models/page/sort-order'; @@ -28,11 +34,11 @@ import { AppState } from '@app/core/core.state'; import { getCurrentAuthUser } from '@app/core/auth/auth.selectors'; import { Authority } from '@shared/models/authority.enum'; import { TranslateService } from '@ngx-translate/core'; -import { coerceBooleanProperty } from '@angular/cdk/coercion'; import { FloatLabelType, MatFormFieldAppearance, SubscriptSizing } from '@angular/material/form-field'; import { getEntityDetailsPageURL } from '@core/utils'; import { EntityType } from '@shared/models/entity-type.models'; import { AuthUser } from '@shared/models/user.model'; +import { coerceBoolean } from '@shared/decorators/coercion'; @Component({ selector: 'tb-dashboard-autocomplete', @@ -82,14 +88,16 @@ export class DashboardAutocompleteComponent implements ControlValueAccessor, OnI @Input() subscriptSizing: SubscriptSizing = 'fixed'; - private requiredValue: boolean; - get required(): boolean { - return this.requiredValue; - } @Input() - set required(value: boolean) { - this.requiredValue = coerceBooleanProperty(value); - } + @coerceBoolean() + inlineField: boolean; + + @Input() + requiredText: string; + + @Input() + @coerceBoolean() + required: boolean; @Input() disabled: boolean; @@ -106,7 +114,7 @@ export class DashboardAutocompleteComponent implements ControlValueAccessor, OnI private authUser: AuthUser; - private propagateChange = (v: any) => { }; + private propagateChange = (_v: any) => { }; constructor(private store: Store, public translate: TranslateService, @@ -118,7 +126,7 @@ export class DashboardAutocompleteComponent implements ControlValueAccessor, OnI } this.selectDashboardFormGroup = this.fb.group({ - dashboard: [null] + dashboard: [null, this.required ? [Validators.required] : []] }); } @@ -126,7 +134,7 @@ export class DashboardAutocompleteComponent implements ControlValueAccessor, OnI this.propagateChange = fn; } - registerOnTouched(fn: any): void { + registerOnTouched(_fn: any): void { } ngOnInit() { @@ -134,7 +142,7 @@ export class DashboardAutocompleteComponent implements ControlValueAccessor, OnI .pipe( debounceTime(150), tap(value => { - let modelValue; + let modelValue: string | DashboardInfo; if (typeof value === 'string' || !value) { modelValue = null; } else { @@ -218,15 +226,13 @@ export class DashboardAutocompleteComponent implements ControlValueAccessor, OnI fetchDashboards(searchText?: string): Observable> { this.searchText = searchText; - const pageLink = new PageLink(10, 0, searchText, { + const pageLink = new PageLink(25, 0, searchText, { property: 'title', direction: Direction.ASC }); return this.getDashboards(pageLink).pipe( catchError(() => of(emptyPageData())), - map(pageData => { - return pageData.data; - }) + map(pageData => pageData.data) ); } diff --git a/ui-ngx/src/app/shared/components/js-func.component.html b/ui-ngx/src/app/shared/components/js-func.component.html index e072759213..66bced8adf 100644 --- a/ui-ngx/src/app/shared/components/js-func.component.html +++ b/ui-ngx/src/app/shared/components/js-func.component.html @@ -15,14 +15,14 @@ limitations under the License. --> -
- - +
-
widgets.rpc-state.turn-off
- widgets.value-action.turn-off
+ + formControlName="offUpdateState">
diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/rpc/single-switch-basic-config.component.ts b/ui-ngx/src/app/modules/home/components/widget/config/basic/rpc/single-switch-basic-config.component.ts index ed95847654..82c2766a23 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/basic/rpc/single-switch-basic-config.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/rpc/single-switch-basic-config.component.ts @@ -37,7 +37,7 @@ import { ValueType } from '@shared/models/constants'; templateUrl: './single-switch-basic-config.component.html', styleUrls: ['../basic-config.scss'] }) -export class SingSwitchBasicConfigComponent extends BasicWidgetConfigComponent { +export class SingleSwitchBasicConfigComponent extends BasicWidgetConfigComponent { get targetDevice(): TargetDevice { return this.singleSwitchWidgetConfigForm.get('targetDevice').value; diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/action/action-widget.models.ts b/ui-ngx/src/app/modules/home/components/widget/lib/action/action-widget.models.ts new file mode 100644 index 0000000000..8557c9cbd3 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/lib/action/action-widget.models.ts @@ -0,0 +1,659 @@ +/// +/// Copyright © 2016-2024 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 { + AttributeData, + AttributeScope, + LatestTelemetry, + TelemetrySubscriber, + TelemetryType, + telemetryTypeTranslationsShort +} from '@shared/models/telemetry/telemetry.models'; +import { WidgetContext } from '@home/models/widget-component.models'; +import { BehaviorSubject, forkJoin, Observable, Observer, of, throwError } from 'rxjs'; +import { catchError, delay, map, share, take } from 'rxjs/operators'; +import { UtilsService } from '@core/services/utils.service'; +import { AfterViewInit, ChangeDetectorRef, Directive, Input, OnDestroy, OnInit, TemplateRef } from '@angular/core'; +import { + DataToValueSettings, + DataToValueType, + GetAttributeValueSettings, + GetTelemetryValueSettings, + GetValueAction, + GetValueSettings, + RpcSettings, + SetAttributeValueSettings, + SetValueAction, + SetValueSettings, + TelemetryValueSettings, + ValueActionSettings, + ValueToDataSettings, + ValueToDataType +} from '@shared/models/action-widget-settings.models'; +import { ValueType } from '@shared/models/constants'; +import { EntityType, entityTypeTranslations } from '@shared/models/entity-type.models'; +import { EntityId } from '@shared/models/id/entity-id'; + +@Directive() +// eslint-disable-next-line @angular-eslint/directive-class-suffix +export abstract class BasicActionWidgetComponent implements OnInit, OnDestroy, AfterViewInit { + + @Input() + ctx: WidgetContext; + + @Input() + widgetTitlePanel: TemplateRef; + + private loadingSubject = new BehaviorSubject(false); + private valueGetters: ValueGetter[] = []; + private valueActions: ValueAction[] = []; + + loading$ = this.loadingSubject.asObservable().pipe(share()); + + error = ''; + + protected constructor(protected cd: ChangeDetectorRef) { + } + + ngOnInit(): void { + this.ctx.$scope.actionWidget = this; + } + + ngAfterViewInit(): void { + const getValueObservables: Array> = []; + this.valueGetters.forEach(valueGetter => { + getValueObservables.push(valueGetter.getValue()); + }); + this.loadingSubject.next(true); + forkJoin(getValueObservables).subscribe( + { + next: () => { + this.loadingSubject.next(false); + }, + error: () => { + this.loadingSubject.next(false); + } + } + ); + } + + ngOnDestroy() { + this.valueActions.forEach(v => v.destroy()); + } + + public onInit() { + } + + public clearError() { + this.error = ''; + this.cd.markForCheck(); + } + + protected createValueGetter(getValueSettings: GetValueSettings, + valueType: ValueType, + valueObserver?: Partial>): ValueGetter { + const observer: Partial> = { + next: (value: V) => { + if (valueObserver?.next) { + valueObserver.next(value); + } + }, + error: (err: any) => { + this.onError(err); + if (valueObserver?.error) { + valueObserver.error(err); + } + } + }; + const valueGetter = ValueGetter.fromSettings(this.ctx, getValueSettings, valueType, observer); + this.valueGetters.push(valueGetter); + this.valueActions.push(valueGetter); + return valueGetter; + } + + protected createValueSetter(setValueSettings: SetValueSettings): ValueSetter { + const valueSetter = ValueSetter.fromSettings(this.ctx, setValueSettings); + this.valueActions.push(valueSetter); + return valueSetter; + } + + private onError(error: string) { + this.error = error; + this.cd.markForCheck(); + } + + protected updateValue(valueSetter: ValueSetter, + value: V, + setValueObserver?: Partial>): void { + this.clearError(); + this.loadingSubject.next(true); + valueSetter.setValue(value).subscribe({ + next: () => { + if (setValueObserver?.next) { + setValueObserver.next(); + } + this.loadingSubject.next(false); + }, + error: (err) => { + this.loadingSubject.next(false); + if (setValueObserver?.error) { + setValueObserver.error(err); + } + const message = parseError(this.ctx, err); + this.onError(message); + } + }); + } +} + +type DataToValueFunction = (data: any) => V; + +export class DataToValueConverter { + + private readonly dataToValueFunction: DataToValueFunction; + private readonly compareToValue: any; + + constructor(private settings: DataToValueSettings, + private valueType: ValueType) { + this.compareToValue = settings.compareToValue; + switch (settings.type) { + case DataToValueType.FUNCTION: + try { + this.dataToValueFunction = new Function('data', settings.dataToValueFunction) as DataToValueFunction; + } catch (e) { + this.dataToValueFunction = (data) => data; + } + break; + case DataToValueType.NONE: + break; + } + } + + dataToValue(data: any): V { + let result: V; + switch (this.settings.type) { + case DataToValueType.FUNCTION: + result = data; + try { + result = this.dataToValueFunction(!!data ? JSON.parse(data) : data); + } catch (e) {} + break; + case DataToValueType.NONE: + result = data; + break; + } + if (this.valueType === ValueType.BOOLEAN) { + result = (result === this.compareToValue) as any; + } + return result; + } +} + +export abstract class ValueAction { + + protected constructor(protected ctx: WidgetContext, + protected settings: ValueActionSettings) {} + + protected handleError(err: any): Error { + const reason = parseError(this.ctx, err); + let errorMessage = this.ctx.translate.instant('widgets.value-action.error.failed-to-perform-action', + {actionLabel: this.settings.actionLabel}); + if (reason) { + errorMessage += '
' + reason; + } + return new Error(errorMessage); + } + + destroy(): void {} +} + +export abstract class ValueGetter extends ValueAction { + + static fromSettings(ctx: WidgetContext, + settings: GetValueSettings, + valueType: ValueType, + valueObserver: Partial>): ValueGetter { + switch (settings.action) { + case GetValueAction.DO_NOTHING: + return new DefaultValueGetter(ctx, settings, valueType, valueObserver); + case GetValueAction.EXECUTE_RPC: + return new ExecuteRpcValueGetter(ctx, settings, valueType, valueObserver); + case GetValueAction.GET_ATTRIBUTE: + return new AttributeValueGetter(ctx, settings, valueType, valueObserver); + case GetValueAction.GET_TIME_SERIES: + return new TimeSeriesValueGetter(ctx, settings, valueType, valueObserver); + } + } + + private readonly isSimulated: boolean; + private readonly dataConverter: DataToValueConverter; + + protected constructor(protected ctx: WidgetContext, + protected settings: GetValueSettings, + protected valueType: ValueType, + protected valueObserver: Partial>) { + super(ctx, settings); + this.isSimulated = this.ctx.$injector.get(UtilsService).widgetEditMode; + if (this.settings.action !== GetValueAction.DO_NOTHING) { + this.dataConverter = new DataToValueConverter(settings.dataToValue, valueType); + } + } + + getValue(): Observable { + const valueObservable: Observable = (this.isSimulated ? of(null).pipe(delay(500)) : this.doGetValue()).pipe( + map((data) => { + if (this.dataConverter) { + return this.dataConverter.dataToValue(data); + } else { + return data; + } + }), + catchError(err => { + throw this.handleError(err); + }) + ); + valueObservable.subscribe({ + next: (value) => { + this.valueObserver.next(value); + }, + error: (err) => { + this.valueObserver.error(err); + } + }); + return valueObservable.pipe( + take(1) + ); + } + + destroy() { + super.destroy(); + } + + protected abstract doGetValue(): Observable; +} + +type ValueToDataFunction = (value: V) => any; + +export class ValueToDataConverter { + + private readonly constantValue: any; + private readonly valueToDataFunction: ValueToDataFunction; + + constructor(protected settings: ValueToDataSettings) { + switch (settings.type) { + case ValueToDataType.CONSTANT: + this.constantValue = this.settings.constantValue; + break; + case ValueToDataType.FUNCTION: + try { + this.valueToDataFunction = new Function('value', settings.valueToDataFunction) as ValueToDataFunction; + } catch (e) { + this.valueToDataFunction = (data) => data; + } + break; + case ValueToDataType.NONE: + break; + } + } + + valueToData(value: V): any { + switch (this.settings.type) { + case ValueToDataType.CONSTANT: + return this.constantValue; + case ValueToDataType.FUNCTION: + let result = value; + try { + result = this.valueToDataFunction(value); + } catch (e) {} + return result; + case ValueToDataType.NONE: + return null; + } + } +} + +export abstract class ValueSetter extends ValueAction { + + static fromSettings(ctx: WidgetContext, + settings: SetValueSettings): ValueSetter { + switch (settings.action) { + case SetValueAction.EXECUTE_RPC: + return new ExecuteRpcValueSetter(ctx, settings); + case SetValueAction.SET_ATTRIBUTE: + return new AttributeValueSetter(ctx, settings); + case SetValueAction.ADD_TIME_SERIES: + return new TimeSeriesValueSetter(ctx, settings); + } + } + + private readonly isSimulated: boolean; + private readonly valueToDataConverter: ValueToDataConverter; + + protected constructor(protected ctx: WidgetContext, + protected settings: SetValueSettings) { + super(ctx, settings); + this.isSimulated = this.ctx.$injector.get(UtilsService).widgetEditMode; + this.valueToDataConverter = new ValueToDataConverter(settings.valueToData); + } + + setValue(value: V): Observable { + if (this.isSimulated) { + return of(null).pipe(delay(500)); + } else { + return this.doSetValue(this.valueToDataConverter.valueToData(value)).pipe( + catchError(err => { + throw this.handleError(err); + }) + ); + } + } + + protected abstract doSetValue(data: any): Observable; +} + +export class DefaultValueGetter extends ValueGetter { + + private readonly defaultValue: V; + + constructor(protected ctx: WidgetContext, + protected settings: GetValueSettings, + protected valueType: ValueType, + protected valueObserver: Partial>) { + super(ctx, settings, valueType, valueObserver); + this.defaultValue = settings.defaultValue; + } + + protected doGetValue(): Observable { + return of(this.defaultValue); + } +} + +export class ExecuteRpcValueGetter extends ValueGetter { + + private readonly executeRpcSettings: RpcSettings; + + constructor(protected ctx: WidgetContext, + protected settings: GetValueSettings, + protected valueType: ValueType, + protected valueObserver: Partial>) { + super(ctx, settings, valueType, valueObserver); + this.executeRpcSettings = settings.executeRpc; + } + + protected doGetValue(): Observable { + return this.ctx.controlApi.sendTwoWayCommand(this.executeRpcSettings.method, null, + this.executeRpcSettings.requestTimeout, + this.executeRpcSettings.requestPersistent, + this.executeRpcSettings.persistentPollingInterval).pipe( + catchError((err) => { + throw handleRpcError(this.ctx, err); + }) + ); + } +} + +export abstract class TelemetryValueGetter extends ValueGetter { + + protected targetEntityId: EntityId; + private telemetrySubscriber: TelemetrySubscriber; + + protected constructor(protected ctx: WidgetContext, + protected settings: GetValueSettings, + protected valueType: ValueType, + protected valueObserver: Partial>) { + super(ctx, settings, valueType, valueObserver); + const entityInfo = this.ctx.defaultSubscription.getFirstEntityInfo(); + this.targetEntityId = entityInfo?.entityId; + } + + protected doGetValue(): Observable { + if (!this.targetEntityId && !this.ctx.defaultSubscription.rpcEnabled) { + return throwError(() => new Error(this.ctx.translate.instant('widgets.value-action.error.target-entity-is-not-set'))); + } + if (this.targetEntityId) { + const err = validateAttributeScope(this.ctx, this.targetEntityId, this.scope()); + if (err) { + return throwError(() => err); + } + if (this.getTelemetryValueSettings().subscribeForUpdates) { + return this.subscribeForTelemetryValue(); + } else { + return this.doGetTelemetryValue(); + } + } else { + return of(null); + } + } + + private subscribeForTelemetryValue(): Observable { + this.telemetrySubscriber = + TelemetrySubscriber.createEntityAttributesSubscription(this.ctx.telemetryWsService, this.targetEntityId, + this.scope(), this.ctx.ngZone, [this.getTelemetryValueSettings().key]); + this.telemetrySubscriber.subscribe(); + return this.telemetrySubscriber.attributeData$().pipe( + map((data) => { + let value: V = null; + const entry = data.find(attr => attr.key === this.getTelemetryValueSettings().key); + if (entry) { + value = entry.value; + try { + value = JSON.parse(entry.value); + } catch (_e) {} + } + return value; + }) + ); + } + + protected scope(): TelemetryType { + return LatestTelemetry.LATEST_TELEMETRY; + } + + protected abstract getTelemetryValueSettings(): S; + + protected abstract doGetTelemetryValue(): Observable; + + destroy() { + if (this.telemetrySubscriber) { + this.telemetrySubscriber.unsubscribe(); + this.telemetrySubscriber = null; + } + super.destroy(); + } +} + +export class AttributeValueGetter extends TelemetryValueGetter { + + constructor(protected ctx: WidgetContext, + protected settings: GetValueSettings, + protected valueType: ValueType, + protected valueObserver: Partial>) { + super(ctx, settings, valueType, valueObserver); + } + + protected getTelemetryValueSettings(): GetAttributeValueSettings { + return this.settings.getAttribute; + } + + protected scope(): TelemetryType { + return this.getTelemetryValueSettings().scope; + } + + protected doGetTelemetryValue(): Observable { + const getAttributeValueSettings = this.getTelemetryValueSettings(); + return this.ctx.attributeService.getEntityAttributes(this.targetEntityId, + getAttributeValueSettings.scope, [getAttributeValueSettings.key], {ignoreLoading: true, ignoreErrors: true}).pipe( + map((data) => data.find(attr => attr.key === getAttributeValueSettings.key)?.value) + ); + } + +} + +export class TimeSeriesValueGetter extends TelemetryValueGetter { + + constructor(protected ctx: WidgetContext, + protected settings: GetValueSettings, + protected valueType: ValueType, + protected valueObserver: Partial>) { + super(ctx, settings, valueType, valueObserver); + } + + protected getTelemetryValueSettings(): GetTelemetryValueSettings { + return this.settings.getTimeSeries; + } + + protected doGetTelemetryValue(): Observable { + const getTelemetryValueSettings = this.getTelemetryValueSettings(); + return this.ctx.attributeService.getEntityTimeseriesLatest(this.targetEntityId, + [getTelemetryValueSettings.key], true, {ignoreLoading: true, ignoreErrors: true}) + .pipe( + map((data) => { + let value: any = null; + if (data[getTelemetryValueSettings.key]) { + const dataSet = data[getTelemetryValueSettings.key]; + if (dataSet.length) { + value = dataSet[0].value; + } + } + return value; + }) + ); + } + +} + +export class ExecuteRpcValueSetter extends ValueSetter { + + private readonly executeRpcSettings: RpcSettings; + + constructor(protected ctx: WidgetContext, + protected settings: SetValueSettings) { + super(ctx, settings); + this.executeRpcSettings = settings.executeRpc; + } + + protected doSetValue(data: any): Observable { + return this.ctx.controlApi.sendOneWayCommand(this.executeRpcSettings.method, data, + this.executeRpcSettings.requestTimeout, + this.executeRpcSettings.requestPersistent, + this.executeRpcSettings.persistentPollingInterval).pipe( + catchError((err) => { + throw handleRpcError(this.ctx, err); + }) + ); + } +} + +export abstract class TelemetryValueSetter extends ValueSetter { + + protected targetEntityId: EntityId; + + protected constructor(protected ctx: WidgetContext, + protected settings: SetValueSettings) { + super(ctx, settings); + const entityInfo = this.ctx.defaultSubscription.getFirstEntityInfo(); + this.targetEntityId = entityInfo?.entityId; + } + + protected doSetValue(data: any): Observable { + if (!this.targetEntityId && !this.ctx.defaultSubscription.rpcEnabled) { + return throwError(() => new Error(this.ctx.translate.instant('widgets.value-action.error.target-entity-is-not-set'))); + } + if (this.targetEntityId) { + const err = validateAttributeScope(this.ctx, this.targetEntityId, this.scope()); + if (err) { + return throwError(() => err); + } + return this.doSetTelemetryValue(data); + } else { + return of(null); + } + } + + protected scope(): TelemetryType { + return LatestTelemetry.LATEST_TELEMETRY; + } + + protected abstract doSetTelemetryValue(data: any): Observable; + +} + +export class AttributeValueSetter extends TelemetryValueSetter { + + private readonly setAttributeValueSettings: SetAttributeValueSettings; + + constructor(protected ctx: WidgetContext, + protected settings: SetValueSettings) { + super(ctx, settings); + this.setAttributeValueSettings = settings.setAttribute; + } + + protected doSetTelemetryValue(data: any): Observable { + const attributes: Array = [{key: this.setAttributeValueSettings.key, value: data}]; + return this.ctx.attributeService.saveEntityAttributes(this.targetEntityId, + this.setAttributeValueSettings.scope, attributes, {ignoreLoading: true, ignoreErrors: true}); + } + + protected scope(): TelemetryType { + return this.setAttributeValueSettings.scope; + } + +} + +export class TimeSeriesValueSetter extends TelemetryValueSetter { + + private readonly putTimeSeriesValueSettings: TelemetryValueSettings; + + constructor(protected ctx: WidgetContext, + protected settings: SetValueSettings) { + super(ctx, settings); + this.putTimeSeriesValueSettings = settings.putTimeSeries; + } + + protected doSetTelemetryValue(data: any): Observable { + const timeSeries: Array = [{key: this.putTimeSeriesValueSettings.key, value: data}]; + return this.ctx.attributeService.saveEntityTimeseries(this.targetEntityId, + LatestTelemetry.LATEST_TELEMETRY, timeSeries, {ignoreLoading: true, ignoreErrors: true}); + } + +} + +const parseError = (ctx: WidgetContext, err: any): string => + ctx.$injector.get(UtilsService).parseException(err).message || 'Unknown Error'; + +const handleRpcError = (ctx: WidgetContext, err: any): Error => { + let reason: string; + if (ctx.defaultSubscription.rpcErrorText) { + reason = ctx.defaultSubscription.rpcErrorText; + } else { + reason = parseError(ctx, err); + } + return new Error(reason); +}; + +const validateAttributeScope = (ctx: WidgetContext, targetEntityId: EntityId, scope?: TelemetryType): Error | null => { + if (targetEntityId.entityType !== EntityType.DEVICE && scope && + ![AttributeScope.SERVER_SCOPE, LatestTelemetry.LATEST_TELEMETRY].includes(scope)) { + const scopeStr = ctx.translate.instant(telemetryTypeTranslationsShort.get(scope)); + const entityType = + ctx.translate.instant(entityTypeTranslations.get(targetEntityId.entityType).type); + const errorMessage = + ctx.translate.instant('widgets.value-action.error.invalid-attribute-scope', {scope: scopeStr, entityType}); + return new Error(errorMessage); + } else { + return null; + } +}; diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/rpc/rpc-widget.models.ts b/ui-ngx/src/app/modules/home/components/widget/lib/rpc/rpc-widget.models.ts deleted file mode 100644 index f47e654fdb..0000000000 --- a/ui-ngx/src/app/modules/home/components/widget/lib/rpc/rpc-widget.models.ts +++ /dev/null @@ -1,626 +0,0 @@ -/// -/// Copyright © 2016-2024 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 { - AttributeData, - AttributeScope, - LatestTelemetry, - telemetryTypeTranslationsShort -} from '@shared/models/telemetry/telemetry.models'; -import { WidgetContext } from '@home/models/widget-component.models'; -import { BehaviorSubject, Observable, of, throwError } from 'rxjs'; -import { catchError, delay, map, share } from 'rxjs/operators'; -import { UtilsService } from '@core/services/utils.service'; -import { AfterViewInit, ChangeDetectorRef, Directive, Input, OnInit, TemplateRef } from '@angular/core'; -import { backgroundStyle, ComponentStyle, overlayStyle } from '@shared/models/widget-settings.models'; -import { ImagePipe } from '@shared/pipe/image.pipe'; -import { DomSanitizer } from '@angular/platform-browser'; -import { - RpcActionSettings, - RpcGetAttributeSettings, - RpcSetAttributeSettings, - RpcSettings, - RpcStateToParamsSettings, - RpcStateToParamsType, - RpcStateWidgetSettings, - RpcTelemetrySettings, - RpcUpdateStateAction -} from '@shared/models/rpc-widget-settings.models'; -import { - RpcDataToStateSettings, - RpcDataToStateType, - RpcInitialStateAction, - RpcInitialStateSettings, - RpcStateBehaviourSettings, - RpcUpdateStateSettings -} from '@app/shared/models/rpc-widget-settings.models'; -import { ValueType } from '@shared/models/constants'; -import { EntityType, entityTypeTranslations } from '@shared/models/entity-type.models'; - -@Directive() -// eslint-disable-next-line @angular-eslint/directive-class-suffix -export abstract class BasicRpcStateWidgetComponent> implements OnInit, AfterViewInit { - - @Input() - ctx: WidgetContext; - - @Input() - widgetTitlePanel: TemplateRef; - - settings: S; - - behaviorApi: RpcStateBehaviorApi; - loading$: Observable; - - backgroundStyle$: Observable; - overlayStyle: ComponentStyle = {}; - - value: V; - - error = ''; - - protected constructor(protected imagePipe: ImagePipe, - protected sanitizer: DomSanitizer, - protected cd: ChangeDetectorRef) { - } - - ngOnInit(): void { - this.ctx.$scope.rpcWidget = this; - this.settings = {...this.defaultSettings(), ...this.ctx.settings}; - this.backgroundStyle$ = backgroundStyle(this.settings.background, this.imagePipe, this.sanitizer); - this.overlayStyle = overlayStyle(this.settings.background.overlay); - - const behaviourSettings: RpcStateBehaviourSettings = { - initialState: this.initialState(), - updateStateByValue: val => this.getUpdateStateSettingsForValue(val) - }; - - const callbacks: RpcStateCallbacks = { - onStateValue: val => this.setValue(val), - onError: err => this.onError(err), - validateStateValue: val => this.validateValue(val) - }; - - this.behaviorApi = new RpcStateBehaviorApi(this.defaultValue(), this.ctx, - behaviourSettings, callbacks, this.stateValueType()); - this.loading$ = this.behaviorApi.loading$.pipe(share()); - } - - ngAfterViewInit(): void { - this.behaviorApi.initState(); - } - - public onInit() { - const borderRadius = this.ctx.$widgetElement.css('borderRadius'); - this.overlayStyle = {...this.overlayStyle, ...{borderRadius}}; - this.cd.detectChanges(); - } - - public clearError() { - this.error = ''; - } - - public updateValue() { - this.behaviorApi.updateState(this.value); - } - - private onError(error: string) { - this.error = error; - this.ctx.detectChanges(); - } - - protected abstract defaultSettings(): S; - - protected abstract initialState(): RpcInitialStateSettings; - - protected abstract getUpdateStateSettingsForValue(value: V): RpcUpdateStateSettings; - - protected stateValueType(): ValueType { - return ValueType.BOOLEAN; - } - - protected defaultValue(): V { - return null; - } - - protected setValue(value: V) { - this.value = value; - } - - protected validateValue(value: any): V { - return value; - } - -} - -export abstract class RpcHasLoading { - - public get loading$() { - return this.loadingSubject.asObservable(); - } - - protected loadingSubject = new BehaviorSubject(false); -} - -export interface RpcStateCallbacks { - onStateValue: (value: V) => void; - validateStateValue: (value: any) => V; - onError: (error: string) => void; -} - -export class RpcStateBehaviorApi extends RpcHasLoading { - - private readonly initialStateGetter: RpcInitialStateGetter; - private readonly stateUpdatersMap: Map>; - - constructor(private state: V, - private ctx: WidgetContext, - private settings: RpcStateBehaviourSettings, - private callbacks: RpcStateCallbacks, - stateValueType: ValueType) { - super(); - this.initialStateGetter = RpcInitialStateGetter.fromSettings(ctx, settings.initialState, stateValueType, callbacks); - this.stateUpdatersMap = new Map>(); - } - - initState() { - if (this.ctx.defaultSubscription.targetEntityId || this.ctx.defaultSubscription.rpcEnabled) { - this.loadingSubject.next(true); - this.initialStateGetter.initState().subscribe( - { - next: (value) => { - this.state = value; - this.loadingSubject.next(false); - this.callbacks.onStateValue(value); - this.ctx.detectChanges(); - }, - error: (err: any) => { - this.loadingSubject.next(false); - const message = parseError(this.ctx, err); - this.callbacks.onError(message); - } - } - ); - } else { - this.callbacks.onError(this.ctx.translate.instant('widgets.rpc-state.error.target-entity-is-not-set')); - } - } - - updateState(value: V) { - this.callbacks.onError(null); - let updater: RpcStateUpdater; - const updateStateSettings = this.settings.updateStateByValue(value); - if (updateStateSettings) { - updater = this.stateUpdatersMap.get(updateStateSettings); - if (!updater) { - updater = RpcStateUpdater.fromSettings(this.ctx, updateStateSettings); - this.stateUpdatersMap.set(updateStateSettings, updater); - } - } - if (updater) { - this.loadingSubject.next(true); - updater.updateState(value).subscribe( - { - next: () => { - this.state = value; - this.loadingSubject.next(false); - this.ctx.detectChanges(); - }, - error: (err: any) => { - this.loadingSubject.next(false); - const message = parseError(this.ctx, err); - this.callbacks.onStateValue(this.state); - this.callbacks.onError(message); - this.ctx.detectChanges(); - } - }); - } - } - -} - -type RpcDataToStateFunction = (data: any) => V; - -export class RpcDataToStateConverter { - - private readonly dataToStateFunction: RpcDataToStateFunction; - private readonly compareToValue: any; - - constructor(private settings: RpcDataToStateSettings, - private stateValueType: ValueType, - private callbacks: RpcStateCallbacks) { - this.compareToValue = settings.compareToValue; - switch (settings.type) { - case RpcDataToStateType.FUNCTION: - try { - this.dataToStateFunction = new Function('data', settings.dataToStateFunction) as RpcDataToStateFunction; - } catch (e) { - this.dataToStateFunction = (data) => data; - } - break; - case RpcDataToStateType.NONE: - break; - } - } - - dataToStateValue(data: any): V { - let result: V; - switch (this.settings.type) { - case RpcDataToStateType.FUNCTION: - result = data; - try { - result = this.dataToStateFunction(!!data ? JSON.parse(data) : data); - } catch (e) {} - break; - case RpcDataToStateType.NONE: - result = data; - break; - } - if (this.stateValueType === ValueType.BOOLEAN) { - result = (result === this.compareToValue) as any; - } - result = this.callbacks.validateStateValue(result); - return result; - } -} - -export abstract class RpcAction { - - protected constructor(protected ctx: WidgetContext, - protected settings: RpcActionSettings) {} - - handleError(err: any): Error { - const reason = parseError(this.ctx, err); - let errorMessage = this.ctx.translate.instant('widgets.rpc-state.error.failed-to-perform-action', - {actionLabel: this.settings.actionLabel}); - if (reason) { - errorMessage += '
' + reason; - } - return new Error(errorMessage); - } -} - -export abstract class RpcInitialStateGetter extends RpcAction { - - static fromSettings(ctx: WidgetContext, - settings: RpcInitialStateSettings, - stateValueType: ValueType, - callbacks: RpcStateCallbacks): RpcInitialStateGetter { - switch (settings.action) { - case RpcInitialStateAction.DO_NOTHING: - return new RpcDefaultStateGetter(ctx, settings, stateValueType, callbacks); - case RpcInitialStateAction.EXECUTE_RPC: - return new ExecuteRpcStateGetter(ctx, settings, stateValueType, callbacks); - case RpcInitialStateAction.GET_ATTRIBUTE: - return new RpcAttributeStateGetter(ctx, settings, stateValueType, callbacks); - case RpcInitialStateAction.GET_TIME_SERIES: - return new RpcTimeSeriesStateGetter(ctx, settings, stateValueType, callbacks); - } - } - - private readonly isSimulated: boolean; - private readonly dataConverter: RpcDataToStateConverter; - - protected constructor(protected ctx: WidgetContext, - protected settings: RpcInitialStateSettings, - protected stateValueType: ValueType, - protected callbacks: RpcStateCallbacks) { - super(ctx, settings); - this.isSimulated = this.ctx.$injector.get(UtilsService).widgetEditMode; - if (this.settings.action !== RpcInitialStateAction.DO_NOTHING) { - this.dataConverter = new RpcDataToStateConverter(settings.dataToState, stateValueType, this.callbacks); - } - } - - initState(): Observable { - const stateObservable: Observable = this.isSimulated ? of(null).pipe(delay(500)) : this.doGetState(); - return stateObservable.pipe( - map((data) => { - if (this.dataConverter) { - return this.dataConverter.dataToStateValue(data); - } else { - return data; - } - }), - catchError(err => { - throw this.handleError(err); - }) - ); - } - - protected abstract doGetState(): Observable; -} - -type RpcStateToParamsFunction = (state: V) => any; - -export class RpcStateToParamsConverter { - - private readonly constantValue: any; - private readonly stateToParamsFunction: RpcStateToParamsFunction; - - constructor(protected settings: RpcStateToParamsSettings) { - switch (settings.type) { - case RpcStateToParamsType.CONSTANT: - this.constantValue = this.settings.constantValue; - break; - case RpcStateToParamsType.FUNCTION: - try { - this.stateToParamsFunction = new Function('value', settings.stateToParamsFunction) as RpcStateToParamsFunction; - } catch (e) { - this.stateToParamsFunction = (data) => data; - } - break; - case RpcStateToParamsType.NONE: - break; - } - } - - stateToParams(state: V): any { - switch (this.settings.type) { - case RpcStateToParamsType.CONSTANT: - return this.constantValue; - case RpcStateToParamsType.FUNCTION: - let result = state; - try { - result = this.stateToParamsFunction(state); - } catch (e) {} - return result; - case RpcStateToParamsType.NONE: - return null; - } - } -} - -export abstract class RpcStateUpdater extends RpcAction { - - static fromSettings(ctx: WidgetContext, - settings: RpcUpdateStateSettings): RpcStateUpdater { - switch (settings.action) { - case RpcUpdateStateAction.EXECUTE_RPC: - return new ExecuteRpcStateUpdater(ctx, settings); - case RpcUpdateStateAction.SET_ATTRIBUTE: - return new RpcAttributeStateUpdater(ctx, settings); - case RpcUpdateStateAction.ADD_TIME_SERIES: - return new RpcTimeSeriesStateUpdater(ctx, settings); - } - } - - private readonly isSimulated: boolean; - private readonly paramsConverter: RpcStateToParamsConverter; - - protected constructor(protected ctx: WidgetContext, - protected settings: RpcUpdateStateSettings) { - super(ctx, settings); - this.isSimulated = this.ctx.$injector.get(UtilsService).widgetEditMode; - this.paramsConverter = new RpcStateToParamsConverter(settings.stateToParams); - } - - updateState(state: V): Observable { - if (this.isSimulated) { - return of(null).pipe(delay(500)); - } else { - return this.doUpdateState(this.paramsConverter.stateToParams(state)).pipe( - catchError(err => { - throw this.handleError(err); - }) - ); - } - } - - protected abstract doUpdateState(params: any): Observable; -} - -export class RpcDefaultStateGetter extends RpcInitialStateGetter { - - private readonly defaultValue: V; - - constructor(protected ctx: WidgetContext, - protected settings: RpcInitialStateSettings, - protected stateValueType: ValueType, - protected callbacks: RpcStateCallbacks) { - super(ctx, settings, stateValueType, callbacks); - this.defaultValue = settings.defaultValue; - } - - protected doGetState(): Observable { - return of(this.defaultValue); - } -} - -export class ExecuteRpcStateGetter extends RpcInitialStateGetter { - - private readonly executeRpcSettings: RpcSettings; - - constructor(protected ctx: WidgetContext, - protected settings: RpcInitialStateSettings, - protected stateValueType: ValueType, - protected callbacks: RpcStateCallbacks) { - super(ctx, settings, stateValueType, callbacks); - this.executeRpcSettings = settings.executeRpc; - } - - protected doGetState(): Observable { - return this.ctx.controlApi.sendTwoWayCommand(this.executeRpcSettings.method, null, - this.executeRpcSettings.requestTimeout, - this.executeRpcSettings.requestPersistent, - this.executeRpcSettings.persistentPollingInterval).pipe( - catchError((err) => { - throw handleRpcError(this.ctx, err); - }) - ); - } -} - -export class RpcAttributeStateGetter extends RpcInitialStateGetter { - - private readonly getAttributeSettings: RpcGetAttributeSettings; - - constructor(protected ctx: WidgetContext, - protected settings: RpcInitialStateSettings, - protected stateValueType: ValueType, - protected callbacks: RpcStateCallbacks) { - super(ctx, settings, stateValueType, callbacks); - this.getAttributeSettings = settings.getAttribute; - } - - protected doGetState(): Observable { - if (this.ctx.defaultSubscription.targetEntityId) { - const err = validateAttributeScope(this.ctx, this.getAttributeSettings.scope); - if (err) { - return throwError(() => err); - } - return this.ctx.attributeService.getEntityAttributes(this.ctx.defaultSubscription.targetEntityId, - this.getAttributeSettings.scope, [this.getAttributeSettings.key], {ignoreLoading: true, ignoreErrors: true}) - .pipe( - map((data) => data.find(attr => attr.key === this.getAttributeSettings.key)?.value) - ); - } else { - return of(null); - } - } - -} - -export class RpcTimeSeriesStateGetter extends RpcInitialStateGetter { - - private readonly getTimeSeriesSettings: RpcTelemetrySettings; - - constructor(protected ctx: WidgetContext, - protected settings: RpcInitialStateSettings, - protected stateValueType: ValueType, - protected callbacks: RpcStateCallbacks) { - super(ctx, settings, stateValueType, callbacks); - this.getTimeSeriesSettings = settings.getTimeSeries; - } - - protected doGetState(): Observable { - if (this.ctx.defaultSubscription.targetEntityId) { - return this.ctx.attributeService.getEntityTimeseriesLatest(this.ctx.defaultSubscription.targetEntityId, - [this.getTimeSeriesSettings.key], true, {ignoreLoading: true, ignoreErrors: true}) - .pipe( - map((data) => { - let value: any = null; - if (data[this.getTimeSeriesSettings.key]) { - const dataSet = data[this.getTimeSeriesSettings.key]; - if (dataSet.length) { - value = dataSet[0].value; - } - } - return value; - }) - ); - } else { - return of(null); - } - } - -} - -export class ExecuteRpcStateUpdater extends RpcStateUpdater { - - private readonly executeRpcSettings: RpcSettings; - - constructor(protected ctx: WidgetContext, - protected settings: RpcUpdateStateSettings) { - super(ctx, settings); - this.executeRpcSettings = settings.executeRpc; - } - - protected doUpdateState(params: any): Observable { - return this.ctx.controlApi.sendOneWayCommand(this.executeRpcSettings.method, params, - this.executeRpcSettings.requestTimeout, - this.executeRpcSettings.requestPersistent, - this.executeRpcSettings.persistentPollingInterval).pipe( - catchError((err) => { - throw handleRpcError(this.ctx, err); - }) - ); - } -} - -export class RpcAttributeStateUpdater extends RpcStateUpdater { - - private readonly setAttributeSettings: RpcSetAttributeSettings; - - constructor(protected ctx: WidgetContext, - protected settings: RpcUpdateStateSettings) { - super(ctx, settings); - this.setAttributeSettings = settings.setAttribute; - } - - protected doUpdateState(params: any): Observable { - if (this.ctx.defaultSubscription.targetEntityId) { - const err = validateAttributeScope(this.ctx, this.setAttributeSettings.scope); - if (err) { - return throwError(() => err); - } - const attributes: Array = [{key: this.setAttributeSettings.key, value: params}]; - return this.ctx.attributeService.saveEntityAttributes(this.ctx.defaultSubscription.targetEntityId, - this.setAttributeSettings.scope, attributes, {ignoreLoading: true, ignoreErrors: true}); - } else { - return of(null); - } - } - -} - -export class RpcTimeSeriesStateUpdater extends RpcStateUpdater { - - private readonly putTimeSeriesSettings: RpcTelemetrySettings; - - constructor(protected ctx: WidgetContext, - protected settings: RpcUpdateStateSettings) { - super(ctx, settings); - this.putTimeSeriesSettings = settings.putTimeSeries; - } - - protected doUpdateState(params: any): Observable { - if (this.ctx.defaultSubscription.targetEntityId) { - const timeSeries: Array = [{key: this.putTimeSeriesSettings.key, value: params}]; - return this.ctx.attributeService.saveEntityTimeseries(this.ctx.defaultSubscription.targetEntityId, - LatestTelemetry.LATEST_TELEMETRY, timeSeries, {ignoreLoading: true, ignoreErrors: true}); - } else { - return of(null); - } - } - -} - -const parseError = (ctx: WidgetContext, err: any): string => - ctx.$injector.get(UtilsService).parseException(err).message || 'Unknown Error'; - -const handleRpcError = (ctx: WidgetContext, err: any): Error => { - let reason: string; - if (ctx.defaultSubscription.rpcErrorText) { - reason = ctx.defaultSubscription.rpcErrorText; - } else { - reason = parseError(ctx, err); - } - return new Error(reason); -}; - -const validateAttributeScope = (ctx: WidgetContext, scope?: AttributeScope): Error | null => { - if (ctx.defaultSubscription.targetEntityId.entityType !== EntityType.DEVICE && scope && scope !== AttributeScope.SERVER_SCOPE) { - const scopeStr = ctx.translate.instant(telemetryTypeTranslationsShort.get(scope)); - const entityType = - ctx.translate.instant(entityTypeTranslations.get(ctx.defaultSubscription.targetEntityId.entityType).type); - const errorMessage = - ctx.translate.instant('widgets.rpc-state.error.invalid-attribute-scope', {scope: scopeStr, entityType}); - return new Error(errorMessage); - } else { - return null; - } -}; diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/rpc/single-switch-widget.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/rpc/single-switch-widget.component.html index ee27f83458..04ec9f22ab 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/rpc/single-switch-widget.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/rpc/single-switch-widget.component.html @@ -27,7 +27,7 @@
{{ offLabel }}
- +
{{ onLabel }}
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/rpc/single-switch-widget.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/rpc/single-switch-widget.component.ts index 7794e51ebc..61d4fb9322 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/rpc/single-switch-widget.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/rpc/single-switch-widget.component.ts @@ -25,20 +25,25 @@ import { ViewChild, ViewEncapsulation } from '@angular/core'; -import { BasicRpcStateWidgetComponent } from '@home/components/widget/lib/rpc/rpc-widget.models'; +import { BasicActionWidgetComponent, ValueSetter } from '@home/components/widget/lib/action/action-widget.models'; import { singleSwitchDefaultSettings, SingleSwitchLayout, SingleSwitchWidgetSettings } from '@home/components/widget/lib/rpc/single-switch-widget.models'; -import { ComponentStyle, iconStyle, textStyle } from '@shared/models/widget-settings.models'; +import { + backgroundStyle, + ComponentStyle, + iconStyle, + overlayStyle, + textStyle +} from '@shared/models/widget-settings.models'; import { Observable } from 'rxjs'; import { ResizeObserver } from '@juggle/resize-observer'; import { ImagePipe } from '@shared/pipe/image.pipe'; import { DomSanitizer } from '@angular/platform-browser'; import cssjs from '@core/css/css'; import { hashCode } from '@core/utils'; -import { RpcInitialStateSettings, RpcUpdateStateSettings } from '@shared/models/rpc-widget-settings.models'; import { ValueType } from '@shared/models/constants'; const horizontalLayoutPadding = 48; @@ -51,7 +56,7 @@ const verticalLayoutPadding = 36; encapsulation: ViewEncapsulation.None }) export class SingleSwitchWidgetComponent extends - BasicRpcStateWidgetComponent implements OnInit, AfterViewInit, OnDestroy { + BasicActionWidgetComponent implements OnInit, AfterViewInit, OnDestroy { @ViewChild('singleSwitchPanel', {static: false}) singleSwitchPanel: ElementRef; @@ -65,6 +70,13 @@ export class SingleSwitchWidgetComponent extends @ViewChild('singleSwitchToggleRow', {static: false}) singleSwitchToggleRow: ElementRef; + settings: SingleSwitchWidgetSettings; + + backgroundStyle$: Observable; + overlayStyle: ComponentStyle = {}; + + value = false; + layout: SingleSwitchLayout; showIcon = false; @@ -87,16 +99,24 @@ export class SingleSwitchWidgetComponent extends private panelResize$: ResizeObserver; + private onValueSetter: ValueSetter; + private offValueSetter: ValueSetter; + constructor(protected imagePipe: ImagePipe, protected sanitizer: DomSanitizer, private renderer: Renderer2, protected cd: ChangeDetectorRef, private elementRef: ElementRef) { - super(imagePipe, sanitizer, cd); + super(cd); } ngOnInit(): void { super.ngOnInit(); + this.settings = {...singleSwitchDefaultSettings, ...this.ctx.settings}; + + this.backgroundStyle$ = backgroundStyle(this.settings.background, this.imagePipe, this.sanitizer); + this.overlayStyle = overlayStyle(this.settings.background.overlay); + this.layout = this.settings.layout; this.autoScale = this.settings.autoScale; @@ -134,6 +154,20 @@ export class SingleSwitchWidgetComponent extends cssParser.cssPreviewNamespace = namespace; cssParser.createStyleElement(namespace, switchVariablesCss); this.renderer.addClass(this.elementRef.nativeElement, namespace); + + const getInitialStateSettings = + {...this.settings.initialState, actionLabel: this.ctx.translate.instant('widgets.value-action.initial-state')}; + this.createValueGetter(getInitialStateSettings, ValueType.BOOLEAN, { + next: (value) => this.onValue(value) + }); + + const onUpdateStateSettings = {...this.settings.onUpdateState, + actionLabel: this.ctx.translate.instant('widgets.value-action.turn-on')}; + this.onValueSetter = this.createValueSetter(onUpdateStateSettings); + + const offUpdateStateSettings = {...this.settings.offUpdateState, + actionLabel: this.ctx.translate.instant('widgets.value-action.turn-off')}; + this.offValueSetter = this.createValueSetter(offUpdateStateSettings); } ngAfterViewInit(): void { @@ -156,31 +190,30 @@ export class SingleSwitchWidgetComponent extends if (this.panelResize$) { this.panelResize$.disconnect(); } + super.ngOnDestroy(); } - protected stateValueType(): ValueType { - return ValueType.BOOLEAN; - } - - protected defaultValue(): boolean { - return false; - } - - protected defaultSettings(): SingleSwitchWidgetSettings { - return {...singleSwitchDefaultSettings}; - } - - protected initialState(): RpcInitialStateSettings { - return {...this.settings.initialState, actionLabel: this.ctx.translate.instant('widgets.rpc-state.initial-state')}; + public onInit() { + super.onInit(); + const borderRadius = this.ctx.$widgetElement.css('borderRadius'); + this.overlayStyle = {...this.overlayStyle, ...{borderRadius}}; + this.cd.detectChanges(); } - protected getUpdateStateSettingsForValue(value: boolean): RpcUpdateStateSettings { - const targetSettings = value ? this.settings.onUpdateState : this.settings.offUpdateState; - return {...targetSettings, actionLabel: this.ctx.translate.instant(value ? 'widgets.rpc-state.turn-on' : 'widgets.rpc-state.turn-off')}; + public onToggleChange(event: MouseEvent) { + event.preventDefault(); + const targetValue = this.value; + const targetSetter = targetValue ? this.onValueSetter : this.offValueSetter; + this.updateValue(targetSetter, targetValue, { + next: () => this.onValue(targetValue), + error: () => this.onValue(!targetValue) + }); } - protected validateValue(value: any): boolean { - return !!value; + private onValue(value: boolean): void { + console.log(`onValue: ${value}`); + this.value = !!value; + this.cd.markForCheck(); } private onResize() { diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/rpc/single-switch-widget.models.ts b/ui-ngx/src/app/modules/home/components/widget/lib/rpc/single-switch-widget.models.ts index 57c2af3b5e..23510e174a 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/rpc/single-switch-widget.models.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/rpc/single-switch-widget.models.ts @@ -14,16 +14,16 @@ /// limitations under the License. /// -import { BackgroundType, cssUnit, Font } from '@shared/models/widget-settings.models'; +import { BackgroundSettings, BackgroundType, cssUnit, Font } from '@shared/models/widget-settings.models'; import { AttributeScope } from '@shared/models/telemetry/telemetry.models'; import { - RpcDataToStateType, - RpcInitialStateAction, - RpcStateToParamsType, - RpcStateWidgetSettings, - RpcUpdateStateAction, - RpcUpdateStateSettings -} from '@shared/models/rpc-widget-settings.models'; + DataToValueType, + GetValueAction, + GetValueSettings, + SetValueAction, + SetValueSettings, + ValueToDataType +} from '@shared/models/action-widget-settings.models'; export enum SingleSwitchLayout { right = 'right', @@ -49,9 +49,10 @@ export const singleSwitchLayoutImages = new Map( ] ); -export interface SingleSwitchWidgetSettings extends RpcStateWidgetSettings { - onUpdateState: RpcUpdateStateSettings; - offUpdateState: RpcUpdateStateSettings; +export interface SingleSwitchWidgetSettings { + initialState: GetValueSettings; + onUpdateState: SetValueSettings; + offUpdateState: SetValueSettings; layout: SingleSwitchLayout; autoScale: boolean; showLabel: boolean; @@ -77,11 +78,12 @@ export interface SingleSwitchWidgetSettings extends RpcStateWidgetSettings -
-
widgets.rpc-state.initial-state
-
+
+
{{ panelTitle | translate }}
+
-
{{ 'widgets.rpc-state.action' | translate }}
+
{{ 'widgets.value-action.action' | translate }}
- - {{ rpcInitialStateTranslationsMap.get(action) | translate }} + + {{ getValueActionTranslationsMap.get(action) | translate }}
- - + +
-
widgets.rpc-state.value
- widgets.value-action.value
+
- +
-
{{ 'widgets.rpc-state.method' | translate }}*
+
{{ 'widgets.value-action.method' | translate }}*
warning
- +
-
{{ 'widgets.rpc-state.attribute-scope' | translate }}
+
{{ 'widgets.value-action.attribute-scope' | translate }}
@@ -71,58 +71,68 @@
-
{{ 'widgets.rpc-state.attribute-key' | translate }}*
+
{{ 'widgets.value-action.attribute-key' | translate }}*
+ [attributeScope]="getValueSettingsFormGroup.get('getAttribute').get('scope').value">
+
+ + {{ 'widgets.value-action.subscribe-for-updates' | translate }} + +
- +
-
{{ 'widgets.rpc-state.time-series-key' | translate }}*
+
{{ 'widgets.value-action.time-series-key' | translate }}*
+
+ + {{ 'widgets.value-action.subscribe-for-updates' | translate }} + +
-
+
-
widgets.rpc-state.action-result-converter
+
widgets.value-action.action-result-converter
- {{ 'widgets.rpc-state.converter-none' | translate }} - {{ 'widgets.rpc-state.converter-function' | translate }} + {{ 'widgets.value-action.converter-none' | translate }} + {{ 'widgets.value-action.converter-function' | translate }}
- -
-
widgets.rpc-state.on-when-result-is
+
+
widgets.value-action.on-when-result-is
-
@@ -142,16 +152,16 @@
-
{{ 'widgets.rpc-state.request-timeout-ms' | translate }}
+
{{ 'widgets.value-action.request-timeout-ms' | translate }}
warning @@ -159,28 +169,28 @@
+ [expanded]="getValueSettingsFormGroup.get('executeRpc').get('requestPersistent').value" + [disabled]="!getValueSettingsFormGroup.get('executeRpc').get('requestPersistent').value"> - {{ 'widgets.rpc-state.request-persistent' | translate }} + {{ 'widgets.value-action.request-persistent' | translate }}
-
{{ 'widgets.rpc-state.persistent-polling-interval' | translate }}
+
{{ 'widgets.value-action.persistent-polling-interval' | translate }}
warning @@ -193,7 +203,7 @@
-
+
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/get-value-action-settings-panel.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/get-value-action-settings-panel.component.ts new file mode 100644 index 0000000000..8f40d59bd1 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/get-value-action-settings-panel.component.ts @@ -0,0 +1,182 @@ +/// +/// Copyright © 2016-2024 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 { Component, EventEmitter, Input, OnInit, Output, ViewEncapsulation } from '@angular/core'; +import { PageComponent } from '@shared/components/page.component'; +import { TbPopoverComponent } from '@shared/components/popover.component'; +import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms'; +import { Store } from '@ngrx/store'; +import { AppState } from '@core/core.state'; +import { merge } from 'rxjs'; +import { + DataToValueType, + GetValueAction, + getValueActions, + getValueActionTranslations, + GetValueSettings +} from '@shared/models/action-widget-settings.models'; +import { ValueType } from '@shared/models/constants'; +import { TargetDevice } from '@shared/models/widget.models'; +import { AttributeScope, DataKeyType, telemetryTypeTranslationsShort } from '@shared/models/telemetry/telemetry.models'; +import { IAliasController } from '@core/api/widget-api.models'; +import { WidgetService } from '@core/http/widget.service'; + +@Component({ + selector: 'tb-get-value-action-settings-panel', + templateUrl: './get-value-action-settings-panel.component.html', + providers: [], + styleUrls: ['./value-action-settings-panel.component.scss'], + encapsulation: ViewEncapsulation.None +}) +export class GetValueActionSettingsPanelComponent extends PageComponent implements OnInit { + + @Input() + getValueSettings: GetValueSettings; + + @Input() + panelTitle: string; + + @Input() + valueType: ValueType; + + @Input() + aliasController: IAliasController; + + @Input() + targetDevice: TargetDevice; + + @Input() + popover: TbPopoverComponent; + + @Output() + getValueSettingsApplied = new EventEmitter>(); + + getValueAction = GetValueAction; + + getValueActions = getValueActions; + + getValueActionTranslationsMap = getValueActionTranslations; + + telemetryTypeTranslationsMap = telemetryTypeTranslationsShort; + + attributeScopes = Object.keys(AttributeScope) as AttributeScope[]; + + dataKeyType = DataKeyType; + + dataToValueType = DataToValueType; + + functionScopeVariables = this.widgetService.getWidgetScopeVariables(); + + ValueType = ValueType; + + getValueSettingsFormGroup: UntypedFormGroup; + + constructor(private fb: UntypedFormBuilder, + private widgetService: WidgetService, + protected store: Store) { + super(store); + } + + ngOnInit(): void { + this.getValueSettingsFormGroup = this.fb.group( + { + action: [this.getValueSettings?.action, []], + defaultValue: [this.getValueSettings?.defaultValue, [Validators.required]], + executeRpc: this.fb.group({ + method: [this.getValueSettings?.executeRpc?.method, [Validators.required]], + requestTimeout: [this.getValueSettings?.executeRpc?.requestTimeout, [Validators.required, Validators.min(5000)]], + requestPersistent: [this.getValueSettings?.executeRpc?.requestPersistent, []], + persistentPollingInterval: + [this.getValueSettings?.executeRpc?.persistentPollingInterval, [Validators.required, Validators.min(1000)]] + }), + getAttribute: this.fb.group({ + scope: [this.getValueSettings?.getAttribute?.scope, []], + key: [this.getValueSettings?.getAttribute?.key, [Validators.required]], + subscribeForUpdates: [this.getValueSettings?.getAttribute?.subscribeForUpdates, []] + }), + getTimeSeries: this.fb.group({ + key: [this.getValueSettings?.getTimeSeries?.key, [Validators.required]], + subscribeForUpdates: [this.getValueSettings?.getTimeSeries?.subscribeForUpdates, []] + }), + dataToValue: this.fb.group({ + type: [this.getValueSettings?.dataToValue?.type, [Validators.required]], + dataToValueFunction: [this.getValueSettings?.dataToValue?.dataToValueFunction, [Validators.required]], + }), + } + ); + if (this.valueType === ValueType.BOOLEAN) { + (this.getValueSettingsFormGroup.get('dataToValue') as UntypedFormGroup).addControl( + 'compareToValue', this.fb.control(this.getValueSettings?.dataToValue?.compareToValue, [Validators.required]) + ); + } + + merge(this.getValueSettingsFormGroup.get('action').valueChanges, + this.getValueSettingsFormGroup.get('dataToValue').get('type').valueChanges, + this.getValueSettingsFormGroup.get('executeRpc').get('requestPersistent').valueChanges).subscribe(() => { + this.updateValidators(); + }); + this.updateValidators(); + } + + cancel() { + this.popover?.hide(); + } + + applyGetValueSettings() { + const getValueSettings: GetValueSettings = this.getValueSettingsFormGroup.getRawValue(); + this.getValueSettingsApplied.emit(getValueSettings); + } + + private updateValidators() { + const action: GetValueAction = this.getValueSettingsFormGroup.get('action').value; + const dataToValueType: DataToValueType = this.getValueSettingsFormGroup.get('dataToValue').get('type').value; + + this.getValueSettingsFormGroup.get('defaultValue').disable({emitEvent: false}); + this.getValueSettingsFormGroup.get('executeRpc').disable({emitEvent: false}); + this.getValueSettingsFormGroup.get('getAttribute').disable({emitEvent: false}); + this.getValueSettingsFormGroup.get('getTimeSeries').disable({emitEvent: false}); + switch (action) { + case GetValueAction.DO_NOTHING: + this.getValueSettingsFormGroup.get('defaultValue').enable({emitEvent: false}); + break; + case GetValueAction.EXECUTE_RPC: + this.getValueSettingsFormGroup.get('executeRpc').enable({emitEvent: false}); + const requestPersistent: boolean = this.getValueSettingsFormGroup.get('executeRpc').get('requestPersistent').value; + if (requestPersistent) { + this.getValueSettingsFormGroup.get('executeRpc').get('persistentPollingInterval').enable({emitEvent: false}); + } else { + this.getValueSettingsFormGroup.get('executeRpc').get('persistentPollingInterval').disable({emitEvent: false}); + } + break; + case GetValueAction.GET_ATTRIBUTE: + this.getValueSettingsFormGroup.get('getAttribute').enable({emitEvent: false}); + break; + case GetValueAction.GET_TIME_SERIES: + this.getValueSettingsFormGroup.get('getTimeSeries').enable({emitEvent: false}); + break; + } + if (action === GetValueAction.DO_NOTHING) { + this.getValueSettingsFormGroup.get('dataToValue').disable({emitEvent: false}); + } else { + this.getValueSettingsFormGroup.get('dataToValue').enable({emitEvent: false}); + if (dataToValueType === DataToValueType.FUNCTION) { + this.getValueSettingsFormGroup.get('dataToValue').get('dataToValueFunction').enable({emitEvent: false}); + } else { + this.getValueSettingsFormGroup.get('dataToValue').get('dataToValueFunction').disable({emitEvent: false}); + } + } + } +} diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/rpc/rpc-initial-state-settings.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/get-value-action-settings.component.ts similarity index 61% rename from ui-ngx/src/app/modules/home/components/widget/lib/settings/common/rpc/rpc-initial-state-settings.component.ts rename to ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/get-value-action-settings.component.ts index 61c053d43c..3c3b00531a 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/rpc/rpc-initial-state-settings.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/get-value-action-settings.component.ts @@ -28,35 +28,38 @@ import { import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; import { MatButton } from '@angular/material/button'; import { TbPopoverService } from '@shared/components/popover.service'; -import { RpcInitialStateAction, RpcInitialStateSettings } from '@shared/models/rpc-widget-settings.models'; +import { GetValueAction, GetValueSettings } from '@shared/models/action-widget-settings.models'; import { TranslateService } from '@ngx-translate/core'; import { ValueType } from '@shared/models/constants'; import { - RpcInitialStateSettingsPanelComponent -} from '@home/components/widget/lib/settings/common/rpc/rpc-initial-state-settings-panel.component'; + GetValueActionSettingsPanelComponent +} from '@home/components/widget/lib/settings/common/action/get-value-action-settings-panel.component'; import { IAliasController } from '@core/api/widget-api.models'; import { TargetDevice } from '@shared/models/widget.models'; @Component({ - selector: 'tb-rpc-initial-state-settings', - templateUrl: './rpc-state-settings-button.component.html', - styleUrls: ['./rpc-state-settings-button.scss'], + selector: 'tb-get-value-action-settings', + templateUrl: './value-action-settings-button.component.html', + styleUrls: ['./value-action-settings-button.scss'], providers: [ { provide: NG_VALUE_ACCESSOR, - useExisting: forwardRef(() => RpcInitialStateSettingsComponent), + useExisting: forwardRef(() => GetValueActionSettingsComponent), multi: true } ], encapsulation: ViewEncapsulation.None }) -export class RpcInitialStateSettingsComponent implements OnInit, ControlValueAccessor { +export class GetValueActionSettingsComponent implements OnInit, ControlValueAccessor { @HostBinding('style.overflow') overflow = 'hidden'; @Input() - stateValueType: ValueType; + panelTitle: string; + + @Input() + valueType: ValueType; @Input() aliasController: IAliasController; @@ -67,7 +70,7 @@ export class RpcInitialStateSettingsComponent implements OnInit, ControlValueAcc @Input() disabled = false; - modelValue: RpcInitialStateSettings; + modelValue: GetValueSettings; displayValue: string; @@ -95,12 +98,12 @@ export class RpcInitialStateSettingsComponent implements OnInit, ControlValueAcc } } - writeValue(value: RpcInitialStateSettings): void { + writeValue(value: GetValueSettings): void { this.modelValue = value; this.updateDisplayValue(); } - openRpcStateSettingsPopup($event: Event, matButton: MatButton) { + openValueActionSettingsPopup($event: Event, matButton: MatButton) { if ($event) { $event.stopPropagation(); } @@ -109,21 +112,22 @@ export class RpcInitialStateSettingsComponent implements OnInit, ControlValueAcc this.popoverService.hidePopover(trigger); } else { const ctx: any = { - initialState: this.modelValue, - stateValueType: this.stateValueType, + getValueSettings: this.modelValue, + panelTitle: this.panelTitle, + valueType: this.valueType, aliasController: this.aliasController, targetDevice: this.targetDevice }; - const initialStateSettingsPanelPopover = this.popoverService.displayPopover(trigger, this.renderer, - this.viewContainerRef, RpcInitialStateSettingsPanelComponent, + const getValueSettingsPanelPopover = this.popoverService.displayPopover(trigger, this.renderer, + this.viewContainerRef, GetValueActionSettingsPanelComponent, ['leftTopOnly', 'leftOnly', 'leftBottomOnly'], true, null, ctx, {}, {}, {}, true); - initialStateSettingsPanelPopover.tbComponentRef.instance.popover = initialStateSettingsPanelPopover; - initialStateSettingsPanelPopover.tbComponentRef.instance.initialStateSettingsApplied.subscribe((initialState) => { - initialStateSettingsPanelPopover.hide(); - this.modelValue = initialState; + getValueSettingsPanelPopover.tbComponentRef.instance.popover = getValueSettingsPanelPopover; + getValueSettingsPanelPopover.tbComponentRef.instance.getValueSettingsApplied.subscribe((getValueSettings) => { + getValueSettingsPanelPopover.hide(); + this.modelValue = getValueSettings; this.updateDisplayValue(); this.propagateChange(this.modelValue); }); @@ -132,22 +136,22 @@ export class RpcInitialStateSettingsComponent implements OnInit, ControlValueAcc private updateDisplayValue() { switch (this.modelValue.action) { - case RpcInitialStateAction.DO_NOTHING: - if (this.stateValueType === ValueType.BOOLEAN) { - this.displayValue = this.translate.instant(!!this.modelValue.defaultValue ? 'widgets.rpc-state.on' : 'widgets.rpc-state.off'); + case GetValueAction.DO_NOTHING: + if (this.valueType === ValueType.BOOLEAN) { + this.displayValue = this.translate.instant(!!this.modelValue.defaultValue ? 'widgets.value-action.on' : 'widgets.value-action.off'); } else { this.displayValue = this.modelValue.defaultValue + ''; } break; - case RpcInitialStateAction.EXECUTE_RPC: + case GetValueAction.EXECUTE_RPC: const methodName = this.modelValue.executeRpc.method; - this.displayValue = this.translate.instant('widgets.rpc-state.execute-rpc-text', {methodName}); + this.displayValue = this.translate.instant('widgets.value-action.execute-rpc-text', {methodName}); break; - case RpcInitialStateAction.GET_ATTRIBUTE: - this.displayValue = this.translate.instant('widgets.rpc-state.get-attribute-text', {key: this.modelValue.getAttribute.key}); + case GetValueAction.GET_ATTRIBUTE: + this.displayValue = this.translate.instant('widgets.value-action.get-attribute-text', {key: this.modelValue.getAttribute.key}); break; - case RpcInitialStateAction.GET_TIME_SERIES: - this.displayValue = this.translate.instant('widgets.rpc-state.get-time-series-text', {key: this.modelValue.getTimeSeries.key}); + case GetValueAction.GET_TIME_SERIES: + this.displayValue = this.translate.instant('widgets.value-action.get-time-series-text', {key: this.modelValue.getTimeSeries.key}); break; } this.cd.markForCheck(); diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/rpc/rpc-update-state-settings-panel.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/set-value-action-settings-panel.component.html similarity index 56% rename from ui-ngx/src/app/modules/home/components/widget/lib/settings/common/rpc/rpc-update-state-settings-panel.component.html rename to ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/set-value-action-settings-panel.component.html index ad70579d1c..faf27484f9 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/rpc/rpc-update-state-settings-panel.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/set-value-action-settings-panel.component.html @@ -15,41 +15,41 @@ limitations under the License. --> -
-
{{ panelTitle | translate }}
-
+
+
{{ panelTitle | translate }}
+
-
{{ 'widgets.rpc-state.action' | translate }}
+
{{ 'widgets.value-action.action' | translate }}
- - {{ rpcUpdateStateTranslationsMap.get(action) | translate }} + + {{ setValueActionTranslationsMap.get(action) | translate }}
- - + +
-
{{ 'widgets.rpc-state.method' | translate }}*
+
{{ 'widgets.value-action.method' | translate }}*
warning
- +
-
{{ 'widgets.rpc-state.attribute-scope' | translate }}
+
{{ 'widgets.value-action.attribute-scope' | translate }}
@@ -59,30 +59,30 @@
-
{{ 'widgets.rpc-state.attribute-key' | translate }}*
+
{{ 'widgets.value-action.attribute-key' | translate }}*
+ [attributeScope]="setValueSettingsFormGroup.get('setAttribute').get('scope').value">
- +
-
{{ 'widgets.rpc-state.time-series-key' | translate }}*
+
{{ 'widgets.value-action.time-series-key' | translate }}*
-
+
-
{{ (updateStateSettingsFormGroup.get('action').value === rpcUpdateStateAction.EXECUTE_RPC ? - 'widgets.rpc-state.parameters' : 'widgets.rpc-state.value') | translate }}
+
{{ (setValueSettingsFormGroup.get('action').value === setValueAction.EXECUTE_RPC ? + 'widgets.value-action.parameters' : 'widgets.value-action.value') | translate }}
- {{ 'widgets.rpc-state.converter-constant' | translate }} - {{ 'widgets.rpc-state.converter-function' | translate }} - {{ 'widgets.rpc-state.converter-none' | translate }} + {{ 'widgets.value-action.converter-constant' | translate }} + {{ 'widgets.value-action.converter-function' | translate }} + {{ 'widgets.value-action.converter-none' | translate }}
- -
-
@@ -132,16 +132,16 @@
-
{{ 'widgets.rpc-state.request-timeout-ms' | translate }}
+
{{ 'widgets.value-action.request-timeout-ms' | translate }}
warning @@ -149,28 +149,28 @@
+ [expanded]="setValueSettingsFormGroup.get('executeRpc').get('requestPersistent').value" + [disabled]="!setValueSettingsFormGroup.get('executeRpc').get('requestPersistent').value"> - {{ 'widgets.rpc-state.request-persistent' | translate }} + {{ 'widgets.value-action.request-persistent' | translate }}
-
{{ 'widgets.rpc-state.persistent-polling-interval' | translate }}
+
{{ 'widgets.value-action.persistent-polling-interval' | translate }}
warning @@ -183,7 +183,7 @@
-
+
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/set-value-action-settings-panel.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/set-value-action-settings-panel.component.ts new file mode 100644 index 0000000000..229d55c531 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/set-value-action-settings-panel.component.ts @@ -0,0 +1,182 @@ +/// +/// Copyright © 2016-2024 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 { Component, EventEmitter, Input, OnInit, Output, ViewEncapsulation } from '@angular/core'; +import { PageComponent } from '@shared/components/page.component'; +import { TbPopoverComponent } from '@shared/components/popover.component'; +import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms'; +import { Store } from '@ngrx/store'; +import { AppState } from '@core/core.state'; +import { merge } from 'rxjs'; +import { + getValueActions, + SetValueAction, + setValueActions, + setValueActionTranslations, + SetValueSettings, + ValueToDataType +} from '@shared/models/action-widget-settings.models'; +import { ValueType } from '@shared/models/constants'; +import { TargetDevice } from '@shared/models/widget.models'; +import { AttributeScope, DataKeyType, telemetryTypeTranslationsShort } from '@shared/models/telemetry/telemetry.models'; +import { IAliasController } from '@core/api/widget-api.models'; +import { WidgetService } from '@core/http/widget.service'; + +@Component({ + selector: 'tb-set-value-action-settings-panel', + templateUrl: './set-value-action-settings-panel.component.html', + providers: [], + styleUrls: ['./value-action-settings-panel.component.scss'], + encapsulation: ViewEncapsulation.None +}) +export class SetValueActionSettingsPanelComponent extends PageComponent implements OnInit { + + @Input() + panelTitle: string; + + @Input() + setValueSettings: SetValueSettings; + + @Input() + valueType: ValueType; + + @Input() + aliasController: IAliasController; + + @Input() + targetDevice: TargetDevice; + + @Input() + popover: TbPopoverComponent; + + @Output() + setValueSettingsApplied = new EventEmitter(); + + setValueAction = SetValueAction; + + setValueActions = setValueActions; + + setValueActionTranslationsMap = setValueActionTranslations; + + telemetryTypeTranslationsMap = telemetryTypeTranslationsShort; + + attributeScopes = [AttributeScope.SERVER_SCOPE, AttributeScope.SHARED_SCOPE]; + + dataKeyType = DataKeyType; + + valueToDataType = ValueToDataType; + + functionScopeVariables = this.widgetService.getWidgetScopeVariables(); + + ValueType = ValueType; + + setValueSettingsFormGroup: UntypedFormGroup; + + constructor(private fb: UntypedFormBuilder, + private widgetService: WidgetService, + protected store: Store) { + super(store); + } + + ngOnInit(): void { + this.setValueSettingsFormGroup = this.fb.group( + { + action: [this.setValueSettings?.action, []], + executeRpc: this.fb.group({ + method: [this.setValueSettings?.executeRpc?.method, [Validators.required]], + requestTimeout: [this.setValueSettings?.executeRpc?.requestTimeout, [Validators.required, Validators.min(5000)]], + requestPersistent: [this.setValueSettings?.executeRpc?.requestPersistent, []], + persistentPollingInterval: + [this.setValueSettings?.executeRpc?.persistentPollingInterval, [Validators.required, Validators.min(1000)]] + }), + setAttribute: this.fb.group({ + scope: [this.setValueSettings?.setAttribute?.scope, []], + key: [this.setValueSettings?.setAttribute?.key, [Validators.required]], + }), + putTimeSeries: this.fb.group({ + key: [this.setValueSettings?.putTimeSeries?.key, [Validators.required]], + }), + valueToData: this.fb.group({ + type: [this.setValueSettings?.valueToData?.type, [Validators.required]], + constantValue: [this.setValueSettings?.valueToData?.constantValue, [Validators.required]], + valueToDataFunction: [this.setValueSettings?.valueToData?.valueToDataFunction, [Validators.required]], + }), + } + ); + + merge(this.setValueSettingsFormGroup.get('action').valueChanges, + this.setValueSettingsFormGroup.get('valueToData').get('type').valueChanges, + this.setValueSettingsFormGroup.get('executeRpc').get('requestPersistent').valueChanges).subscribe(() => { + this.updateValidators(); + }); + this.updateValidators(); + } + + cancel() { + this.popover?.hide(); + } + + applySetValueSettings() { + const setValueSettings: SetValueSettings = this.setValueSettingsFormGroup.getRawValue(); + this.setValueSettingsApplied.emit(setValueSettings); + } + + private updateValidators() { + const action: SetValueAction = this.setValueSettingsFormGroup.get('action').value; + let valueToDataType: ValueToDataType = this.setValueSettingsFormGroup.get('valueToData').get('type').value; + + this.setValueSettingsFormGroup.get('executeRpc').disable({emitEvent: false}); + this.setValueSettingsFormGroup.get('setAttribute').disable({emitEvent: false}); + this.setValueSettingsFormGroup.get('putTimeSeries').disable({emitEvent: false}); + switch (action) { + case SetValueAction.EXECUTE_RPC: + this.setValueSettingsFormGroup.get('executeRpc').enable({emitEvent: false}); + const requestPersistent: boolean = this.setValueSettingsFormGroup.get('executeRpc').get('requestPersistent').value; + if (requestPersistent) { + this.setValueSettingsFormGroup.get('executeRpc').get('persistentPollingInterval').enable({emitEvent: false}); + } else { + this.setValueSettingsFormGroup.get('executeRpc').get('persistentPollingInterval').disable({emitEvent: false}); + } + break; + case SetValueAction.SET_ATTRIBUTE: + case SetValueAction.ADD_TIME_SERIES: + if (valueToDataType === ValueToDataType.NONE) { + valueToDataType = ValueToDataType.CONSTANT; + this.setValueSettingsFormGroup.get('valueToData').get('type').patchValue(valueToDataType, {emitEvent: false}); + } + if (action === SetValueAction.SET_ATTRIBUTE) { + this.setValueSettingsFormGroup.get('setAttribute').enable({emitEvent: false}); + } else { + this.setValueSettingsFormGroup.get('putTimeSeries').enable({emitEvent: false}); + } + break; + } + switch (valueToDataType) { + case ValueToDataType.CONSTANT: + this.setValueSettingsFormGroup.get('valueToData').get('constantValue').enable({emitEvent: false}); + this.setValueSettingsFormGroup.get('valueToData').get('valueToDataFunction').disable({emitEvent: false}); + break; + case ValueToDataType.FUNCTION: + this.setValueSettingsFormGroup.get('valueToData').get('constantValue').disable({emitEvent: false}); + this.setValueSettingsFormGroup.get('valueToData').get('valueToDataFunction').enable({emitEvent: false}); + break; + case ValueToDataType.NONE: + this.setValueSettingsFormGroup.get('valueToData').get('constantValue').disable({emitEvent: false}); + this.setValueSettingsFormGroup.get('valueToData').get('valueToDataFunction').disable({emitEvent: false}); + break; + } + } +} diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/rpc/rpc-update-state-settings.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/set-value-action-settings.component.ts similarity index 62% rename from ui-ngx/src/app/modules/home/components/widget/lib/settings/common/rpc/rpc-update-state-settings.component.ts rename to ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/set-value-action-settings.component.ts index 8a65861783..d0110226f5 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/rpc/rpc-update-state-settings.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/set-value-action-settings.component.ts @@ -28,34 +28,30 @@ import { import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; import { MatButton } from '@angular/material/button'; import { TbPopoverService } from '@shared/components/popover.service'; -import { - RpcStateToParamsType, - RpcUpdateStateAction, - RpcUpdateStateSettings -} from '@shared/models/rpc-widget-settings.models'; +import { SetValueAction, SetValueSettings, ValueToDataType } from '@shared/models/action-widget-settings.models'; import { TranslateService } from '@ngx-translate/core'; import { ValueType } from '@shared/models/constants'; import { IAliasController } from '@core/api/widget-api.models'; import { TargetDevice } from '@shared/models/widget.models'; import { isDefinedAndNotNull } from '@core/utils'; import { - RpcUpdateStateSettingsPanelComponent -} from '@home/components/widget/lib/settings/common/rpc/rpc-update-state-settings-panel.component'; + SetValueActionSettingsPanelComponent +} from '@home/components/widget/lib/settings/common/action/set-value-action-settings-panel.component'; @Component({ - selector: 'tb-rpc-update-state-settings', - templateUrl: './rpc-state-settings-button.component.html', - styleUrls: ['./rpc-state-settings-button.scss'], + selector: 'tb-set-value-action-settings', + templateUrl: './value-action-settings-button.component.html', + styleUrls: ['./value-action-settings-button.scss'], providers: [ { provide: NG_VALUE_ACCESSOR, - useExisting: forwardRef(() => RpcUpdateStateSettingsComponent), + useExisting: forwardRef(() => SetValueActionSettingsComponent), multi: true } ], encapsulation: ViewEncapsulation.None }) -export class RpcUpdateStateSettingsComponent implements OnInit, ControlValueAccessor { +export class SetValueActionSettingsComponent implements OnInit, ControlValueAccessor { @HostBinding('style.overflow') overflow = 'hidden'; @@ -64,7 +60,7 @@ export class RpcUpdateStateSettingsComponent implements OnInit, ControlValueAcce panelTitle: string; @Input() - stateValueType: ValueType; + valueType: ValueType; @Input() aliasController: IAliasController; @@ -75,7 +71,7 @@ export class RpcUpdateStateSettingsComponent implements OnInit, ControlValueAcce @Input() disabled = false; - modelValue: RpcUpdateStateSettings; + modelValue: SetValueSettings; displayValue: string; @@ -103,12 +99,12 @@ export class RpcUpdateStateSettingsComponent implements OnInit, ControlValueAcce } } - writeValue(value: RpcUpdateStateSettings): void { + writeValue(value: SetValueSettings): void { this.modelValue = value; this.updateDisplayValue(); } - openRpcStateSettingsPopup($event: Event, matButton: MatButton) { + openValueActionSettingsPopup($event: Event, matButton: MatButton) { if ($event) { $event.stopPropagation(); } @@ -117,22 +113,22 @@ export class RpcUpdateStateSettingsComponent implements OnInit, ControlValueAcce this.popoverService.hidePopover(trigger); } else { const ctx: any = { - updateState: this.modelValue, + setValueSettings: this.modelValue, panelTitle: this.panelTitle, - stateValueType: this.stateValueType, + valueType: this.valueType, aliasController: this.aliasController, targetDevice: this.targetDevice }; - const updateStateSettingsPanelPopover = this.popoverService.displayPopover(trigger, this.renderer, - this.viewContainerRef, RpcUpdateStateSettingsPanelComponent, + const setValueSettingsPanelPopover = this.popoverService.displayPopover(trigger, this.renderer, + this.viewContainerRef, SetValueActionSettingsPanelComponent, ['leftTopOnly', 'leftOnly', 'leftBottomOnly'], true, null, ctx, {}, {}, {}, true); - updateStateSettingsPanelPopover.tbComponentRef.instance.popover = updateStateSettingsPanelPopover; - updateStateSettingsPanelPopover.tbComponentRef.instance.updateStateSettingsApplied.subscribe((updateState) => { - updateStateSettingsPanelPopover.hide(); - this.modelValue = updateState; + setValueSettingsPanelPopover.tbComponentRef.instance.popover = setValueSettingsPanelPopover; + setValueSettingsPanelPopover.tbComponentRef.instance.setValueSettingsApplied.subscribe((setValueSettings) => { + setValueSettingsPanelPopover.hide(); + this.modelValue = setValueSettings; this.updateDisplayValue(); this.propagateChange(this.modelValue); }); @@ -141,31 +137,31 @@ export class RpcUpdateStateSettingsComponent implements OnInit, ControlValueAcce private updateDisplayValue() { let value: any; - switch (this.modelValue.stateToParams.type) { - case RpcStateToParamsType.CONSTANT: - value = this.modelValue.stateToParams.constantValue; + switch (this.modelValue.valueToData.type) { + case ValueToDataType.CONSTANT: + value = this.modelValue.valueToData.constantValue; break; - case RpcStateToParamsType.FUNCTION: + case ValueToDataType.FUNCTION: value = 'f(value)'; break; - case RpcStateToParamsType.NONE: + case ValueToDataType.NONE: break; } switch (this.modelValue.action) { - case RpcUpdateStateAction.EXECUTE_RPC: + case SetValueAction.EXECUTE_RPC: let methodName = this.modelValue.executeRpc.method; if (isDefinedAndNotNull(value)) { methodName = `${methodName}(${value})`; } - this.displayValue = this.translate.instant('widgets.rpc-state.execute-rpc-text', {methodName}); + this.displayValue = this.translate.instant('widgets.value-action.execute-rpc-text', {methodName}); break; - case RpcUpdateStateAction.SET_ATTRIBUTE: - this.displayValue = this.translate.instant('widgets.rpc-state.set-attribute-to-value-text', + case SetValueAction.SET_ATTRIBUTE: + this.displayValue = this.translate.instant('widgets.value-action.set-attribute-to-value-text', {key: this.modelValue.setAttribute.key, value}); break; - case RpcUpdateStateAction.ADD_TIME_SERIES: - this.displayValue = this.translate.instant('widgets.rpc-state.add-time-series-value-text', - {key: this.modelValue.setAttribute.key, value}); + case SetValueAction.ADD_TIME_SERIES: + this.displayValue = this.translate.instant('widgets.value-action.add-time-series-value-text', + {key: this.modelValue.putTimeSeries.key, value}); break; } this.cd.markForCheck(); diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/rpc/rpc-state-settings-button.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/value-action-settings-button.component.html similarity index 88% rename from ui-ngx/src/app/modules/home/components/widget/lib/settings/common/rpc/rpc-state-settings-button.component.html rename to ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/value-action-settings-button.component.html index da24002e31..1e54dc3270 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/rpc/rpc-state-settings-button.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/value-action-settings-button.component.html @@ -16,9 +16,9 @@ -->
diff --git a/ui-ngx/src/app/shared/models/action-widget-settings.models.ts b/ui-ngx/src/app/shared/models/action-widget-settings.models.ts new file mode 100644 index 0000000000..d1442c09c5 --- /dev/null +++ b/ui-ngx/src/app/shared/models/action-widget-settings.models.ts @@ -0,0 +1,128 @@ +/// +/// Copyright © 2016-2024 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 { AttributeScope } from '@shared/models/telemetry/telemetry.models'; + +export enum GetValueAction { + DO_NOTHING = 'DO_NOTHING', + EXECUTE_RPC = 'EXECUTE_RPC', + GET_ATTRIBUTE = 'GET_ATTRIBUTE', + GET_TIME_SERIES = 'GET_TIME_SERIES' +} + +export const getValueActions = Object.keys(GetValueAction) as GetValueAction[]; + +export const getValueActionTranslations = new Map( + [ + [GetValueAction.DO_NOTHING, 'widgets.value-action.do-nothing'], + [GetValueAction.EXECUTE_RPC, 'widgets.value-action.execute-rpc'], + [GetValueAction.GET_ATTRIBUTE, 'widgets.value-action.get-attribute'], + [GetValueAction.GET_TIME_SERIES, 'widgets.value-action.get-time-series'] + ] +); + +export interface RpcSettings { + method: string; + requestTimeout: number; + requestPersistent: boolean; + persistentPollingInterval: number; +} + +export interface TelemetryValueSettings { + key: string; +} + +export interface GetTelemetryValueSettings extends TelemetryValueSettings { + subscribeForUpdates: boolean; +} + +export interface GetAttributeValueSettings extends GetTelemetryValueSettings { + scope: AttributeScope | null; +} + +export interface SetAttributeValueSettings extends TelemetryValueSettings { + scope: AttributeScope.SERVER_SCOPE | AttributeScope.SHARED_SCOPE; +} + +export enum DataToValueType { + NONE = 'NONE', + FUNCTION = 'FUNCTION' +} + +export interface DataToValueSettings { + type: DataToValueType; + dataToValueFunction: string; + compareToValue?: any; +} + +export interface ValueActionSettings { + actionLabel?: string; +} + +export interface GetValueSettings extends ValueActionSettings { + action: GetValueAction; + defaultValue: V; + executeRpc: RpcSettings; + getAttribute: GetAttributeValueSettings; + getTimeSeries: GetTelemetryValueSettings; + dataToValue: DataToValueSettings; +} + +export enum SetValueAction { + EXECUTE_RPC = 'EXECUTE_RPC', + SET_ATTRIBUTE = 'SET_ATTRIBUTE', + ADD_TIME_SERIES = 'ADD_TIME_SERIES' +} + +export const setValueActions = Object.keys(SetValueAction) as SetValueAction[]; + +export const setValueActionTranslations = new Map( + [ + [SetValueAction.EXECUTE_RPC, 'widgets.value-action.execute-rpc'], + [SetValueAction.SET_ATTRIBUTE, 'widgets.value-action.set-attribute'], + [SetValueAction.ADD_TIME_SERIES, 'widgets.value-action.add-time-series'] + ] +); + +export enum ValueToDataType { + CONSTANT = 'CONSTANT', + FUNCTION = 'FUNCTION', + NONE = 'NONE' +} + +export interface ValueToDataSettings { + type: ValueToDataType; + constantValue: any; + valueToDataFunction: string; +} + +export interface SetValueSettings extends ValueActionSettings { + action: SetValueAction; + executeRpc: RpcSettings; + setAttribute: SetAttributeValueSettings; + putTimeSeries: TelemetryValueSettings; + valueToData: ValueToDataSettings; +} + +/*export interface RpcStateBehaviourSettings { + initialState: RpcInitialStateSettings; + updateStateByValue: (value: V) => RpcUpdateStateSettings; +} + +export interface RpcStateWidgetSettings { + initialState: RpcInitialStateSettings; + background: BackgroundSettings; +}*/ diff --git a/ui-ngx/src/app/shared/models/rpc-widget-settings.models.ts b/ui-ngx/src/app/shared/models/rpc-widget-settings.models.ts deleted file mode 100644 index b912361805..0000000000 --- a/ui-ngx/src/app/shared/models/rpc-widget-settings.models.ts +++ /dev/null @@ -1,125 +0,0 @@ -/// -/// Copyright © 2016-2024 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 { AttributeScope } from '@shared/models/telemetry/telemetry.models'; -import { BackgroundSettings } from '@shared/models/widget-settings.models'; - -export enum RpcInitialStateAction { - DO_NOTHING = 'DO_NOTHING', - EXECUTE_RPC = 'EXECUTE_RPC', - GET_ATTRIBUTE = 'GET_ATTRIBUTE', - GET_TIME_SERIES = 'GET_TIME_SERIES' -} - -export const rpcInitialStateActions = Object.keys(RpcInitialStateAction) as RpcInitialStateAction[]; - -export const rpcInitialStateTranslations = new Map( - [ - [RpcInitialStateAction.DO_NOTHING, 'widgets.rpc-state.do-nothing'], - [RpcInitialStateAction.EXECUTE_RPC, 'widgets.rpc-state.execute-rpc'], - [RpcInitialStateAction.GET_ATTRIBUTE, 'widgets.rpc-state.get-attribute'], - [RpcInitialStateAction.GET_TIME_SERIES, 'widgets.rpc-state.get-time-series'] - ] -); - -export interface RpcSettings { - method: string; - requestTimeout: number; - requestPersistent: boolean; - persistentPollingInterval: number; -} - -export interface RpcTelemetrySettings { - key: string; -} - -export interface RpcGetAttributeSettings extends RpcTelemetrySettings { - scope: AttributeScope | null; -} - -export interface RpcSetAttributeSettings extends RpcTelemetrySettings { - scope: AttributeScope.SERVER_SCOPE | AttributeScope.SHARED_SCOPE; -} - -export enum RpcDataToStateType { - NONE = 'NONE', - FUNCTION = 'FUNCTION' -} - -export interface RpcDataToStateSettings { - type: RpcDataToStateType; - dataToStateFunction: string; - compareToValue?: any; -} - -export interface RpcActionSettings { - actionLabel?: string; -} - -export interface RpcInitialStateSettings extends RpcActionSettings { - action: RpcInitialStateAction; - defaultValue: V; - executeRpc: RpcSettings; - getAttribute: RpcGetAttributeSettings; - getTimeSeries: RpcTelemetrySettings; - dataToState: RpcDataToStateSettings; -} - -export enum RpcUpdateStateAction { - EXECUTE_RPC = 'EXECUTE_RPC', - SET_ATTRIBUTE = 'SET_ATTRIBUTE', - ADD_TIME_SERIES = 'ADD_TIME_SERIES' -} - -export const rpcUpdateStateActions = Object.keys(RpcUpdateStateAction) as RpcUpdateStateAction[]; - -export const rpcUpdateStateTranslations = new Map( - [ - [RpcUpdateStateAction.EXECUTE_RPC, 'widgets.rpc-state.execute-rpc'], - [RpcUpdateStateAction.SET_ATTRIBUTE, 'widgets.rpc-state.set-attribute'], - [RpcUpdateStateAction.ADD_TIME_SERIES, 'widgets.rpc-state.add-time-series'] - ] -); - -export enum RpcStateToParamsType { - CONSTANT = 'CONSTANT', - FUNCTION = 'FUNCTION', - NONE = 'NONE' -} - -export interface RpcStateToParamsSettings { - type: RpcStateToParamsType; - constantValue: any; - stateToParamsFunction: string; -} - -export interface RpcUpdateStateSettings extends RpcActionSettings { - action: RpcUpdateStateAction; - executeRpc: RpcSettings; - setAttribute: RpcSetAttributeSettings; - putTimeSeries: RpcTelemetrySettings; - stateToParams: RpcStateToParamsSettings; -} - -export interface RpcStateBehaviourSettings { - initialState: RpcInitialStateSettings; - updateStateByValue: (value: V) => RpcUpdateStateSettings; -} - -export interface RpcStateWidgetSettings { - initialState: RpcInitialStateSettings; - background: BackgroundSettings; -} diff --git a/ui-ngx/src/assets/locale/locale.constant-en_US.json b/ui-ngx/src/assets/locale/locale.constant-en_US.json index 0f92abd1f3..e18d21f609 100644 --- a/ui-ngx/src/assets/locale/locale.constant-en_US.json +++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json @@ -6011,60 +6011,6 @@ "min-value": "Minimum value", "max-value": "Maximum value" }, - "rpc-state": { - "initial-state": "Initial state", - "initial-state-hint": "Action to get the initial value of the component.", - "turn-on": "Turn 'On'", - "turn-on-hint": "Action performed to turn ON the component.", - "turn-off": "Turn 'Off'", - "turn-off-hint": "Action performed to turn OFF the component.", - "on": "On", - "off": "Off", - "do-nothing": "Do nothing", - "execute-rpc": "Execute RPC", - "get-attribute": "Get attribute", - "set-attribute": "Set attribute", - "get-time-series": "Get time-series", - "add-time-series": "Add time-series", - "execute-rpc-text": "Execute RPC method '{{methodName}}'", - "get-attribute-text": "Use attribute '{{key}}'", - "get-time-series-text": "Use time-series '{{key}}'", - "set-attribute-to-value-text": "Set '{{key}}' attribute to: {{value}}", - "add-time-series-value-text": "Add '{{key}}' time-series value: {{value}}", - "set-attribute-text": "Set '{{key}}' attribute", - "add-time-series-text": "Add '{{key}}' time-series", - "action": "Action", - "value": "Value", - "init-value-hint": "Value that will be set until device sends data.", - "method": "Method", - "method-name-required": "Method name is required.", - "request-timeout-ms": "RPC request timeout (ms)", - "request-timeout-required": "Request timeout is required.", - "min-request-timeout-error": "Request timeout value should be greater or equal 5000 ms (5 seconds).", - "request-persistent": "RPC request persistent", - "persistent-polling-interval": "Persistent polling interval (ms)", - "persistent-polling-interval-hint": "Polling interval (ms) to get persistent RPC command response", - "persistent-polling-interval-required": "Persistent polling interval is required.", - "min-persistent-polling-interval-error": "Persistent polling interval value should be greater or equal 1000 ms (1 second).", - "attribute-scope": "Attribute scope", - "attribute-key": "Attribute key", - "attribute-key-required": "Attribute key is required.", - "time-series-key": "Time-series key", - "time-series-key-required": "Time-series key is required.", - "action-result-converter": "Action result converter", - "converter-none": "None", - "converter-function": "Function", - "converter-constant": "Constant", - "parse-value-function": "Parse value function", - "on-when-result-is": "'On' when result is", - "parameters": "Parameters", - "convert-value-function": "Convert value function", - "error": { - "target-entity-is-not-set": "Target entity is not set!", - "failed-to-perform-action": "Failed to perform the {{ actionLabel }} action.", - "invalid-attribute-scope": "{{scope}} attribute scope is not supported by {{entityType}} entity." - } - }, "maps": { "select-entity": "Select entity", "select-entity-hint": "Hint: after selection click at the map to set position", @@ -6537,6 +6483,62 @@ "source-entity-alias": "Source entity alias", "source-entity-attribute": "Source entity attribute" }, + "value-action": { + "initial-state": "Initial state", + "initial-state-hint": "Action to get the initial value of the component.", + "turn-on": "Turn 'On'", + "turn-on-hint": "Action performed to turn ON the component.", + "turn-off": "Turn 'Off'", + "turn-off-hint": "Action performed to turn OFF the component.", + "on": "On", + "off": "Off", + "do-nothing": "Do nothing", + "execute-rpc": "Execute RPC", + "get-attribute": "Get attribute", + "set-attribute": "Set attribute", + "get-time-series": "Get time-series", + "add-time-series": "Add time-series", + "execute-rpc-text": "Execute RPC method '{{methodName}}'", + "get-attribute-text": "Use attribute '{{key}}'", + "get-time-series-text": "Use time-series '{{key}}'", + "set-attribute-to-value-text": "Set '{{key}}' attribute to: {{value}}", + "add-time-series-value-text": "Add '{{key}}' time-series value: {{value}}", + "set-attribute-text": "Set '{{key}}' attribute", + "add-time-series-text": "Add '{{key}}' time-series", + "action": "Action", + "value": "Value", + "init-value-hint": "Value that will be set until device sends data.", + "method": "Method", + "method-name-required": "Method name is required.", + "request-timeout-ms": "RPC request timeout (ms)", + "request-timeout-required": "Request timeout is required.", + "min-request-timeout-error": "Request timeout value should be greater or equal 5000 ms (5 seconds).", + "request-persistent": "RPC request persistent", + "persistent-polling-interval": "Persistent polling interval (ms)", + "persistent-polling-interval-hint": "Polling interval (ms) to get persistent RPC command response", + "persistent-polling-interval-required": "Persistent polling interval is required.", + "min-persistent-polling-interval-error": "Persistent polling interval value should be greater or equal 1000 ms (1 second).", + "attribute-scope": "Attribute scope", + "attribute-key": "Attribute key", + "attribute-key-required": "Attribute key is required.", + "time-series-key": "Time-series key", + "time-series-key-required": "Time-series key is required.", + "subscribe-for-updates": "Subscribe for updates", + "subscribe-for-updates-hint": "Subscribe for updates", + "action-result-converter": "Action result converter", + "converter-none": "None", + "converter-function": "Function", + "converter-constant": "Constant", + "parse-value-function": "Parse value function", + "on-when-result-is": "'On' when result is", + "parameters": "Parameters", + "convert-value-function": "Convert value function", + "error": { + "target-entity-is-not-set": "Target entity is not set!", + "failed-to-perform-action": "Failed to perform the {{ actionLabel }} action.", + "invalid-attribute-scope": "{{scope}} attribute scope is not supported by {{entityType}} entity." + } + }, "widget-font": { "font-settings": "Font settings", "font-family": "Font family", From df91e0a38e302862c269de7afb276b7ff35f9ee4 Mon Sep 17 00:00:00 2001 From: Andrew Shvayka Date: Tue, 30 Jan 2024 13:57:39 +0200 Subject: [PATCH 144/179] Update the Bug report template --- .github/ISSUE_TEMPLATE/---bug-report.md | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/---bug-report.md b/.github/ISSUE_TEMPLATE/---bug-report.md index bffb88ebb7..07c5c150cb 100644 --- a/.github/ISSUE_TEMPLATE/---bug-report.md +++ b/.github/ISSUE_TEMPLATE/---bug-report.md @@ -2,8 +2,8 @@ name: "\U0001F41E Bug report" about: Create a report to help us improve title: "[Bug] " -labels: bug -assignees: ashvayka, vvlladd28 +labels: ['bug', 'status: unconfirmed'] +assignees: AndriichnekoDm --- @@ -12,11 +12,13 @@ A clear and concise description of what the bug is. **Your Server Environment** -* demo.thingsboard.io -* cloud.thingsboard.io +* [https://demo.thingsboard.io](demo.thingsboard.io) +* [https://thingsboard.cloud](thingsboard.cloud) * own setup - * cloud or local infrastructure or docker deployment + * Deployment: monolith or microservices + * Deployment type: deb, rpm, exe, docker-compose, k8s, ami * ThingsBoard Version + * Community or Professional Edition * OS Name and Version **Your Client Environment** @@ -54,7 +56,7 @@ Steps to reproduce the behavior: A clear and concise description of what you expected to happen. **Screenshots** -If applicable, add screenshots to help explain your problem. +If applicable, please add screenshots to help explain your problem. **Additional context** -Add any other context about the problem here. +Please feel free to add any other context about the problem here. From 098f72b86b72764a9ef497eb8b347e24311e924e Mon Sep 17 00:00:00 2001 From: Andrew Shvayka Date: Tue, 30 Jan 2024 14:00:47 +0200 Subject: [PATCH 145/179] Update ---bug-report.md --- .github/ISSUE_TEMPLATE/---bug-report.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/---bug-report.md b/.github/ISSUE_TEMPLATE/---bug-report.md index 07c5c150cb..33a0652e15 100644 --- a/.github/ISSUE_TEMPLATE/---bug-report.md +++ b/.github/ISSUE_TEMPLATE/---bug-report.md @@ -2,7 +2,7 @@ name: "\U0001F41E Bug report" about: Create a report to help us improve title: "[Bug] " -labels: ['bug', 'status: unconfirmed'] +labels: ['bug', 'unconfirmed'] assignees: AndriichnekoDm --- From f6b796027edbd3f9fda7af173f83d56143eb886d Mon Sep 17 00:00:00 2001 From: Andrew Shvayka Date: Tue, 30 Jan 2024 14:01:58 +0200 Subject: [PATCH 146/179] Update feature_request.md --- .github/ISSUE_TEMPLATE/feature_request.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index e5a710c155..fcb1448199 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -2,7 +2,7 @@ name: Feature request about: Suggest an idea for this project title: "[Feature Request]" -labels: ['Feature'] +labels: ['feature'] assignees: 'AndriichnekoDm' --- From 7dfc89aac22e186ac270665ed137d063af6e4f98 Mon Sep 17 00:00:00 2001 From: Andrew Shvayka Date: Tue, 30 Jan 2024 14:04:12 +0200 Subject: [PATCH 147/179] Update question.md --- .github/ISSUE_TEMPLATE/question.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/question.md b/.github/ISSUE_TEMPLATE/question.md index 99d82ca698..3fb84817ca 100644 --- a/.github/ISSUE_TEMPLATE/question.md +++ b/.github/ISSUE_TEMPLATE/question.md @@ -1,9 +1,9 @@ --- name: Question about: Describe your questions in details -title: "[Question] your title here" -labels: question -assignees: ashvayka +title: "Your title here" +labels: ['question'] +assignees: 'AndriichnekoDm' --- @@ -16,7 +16,7 @@ assignees: ashvayka * Generic **Description** -A clear and concise details. +Clear and concise details. **Environment** From 6d624ce17d2a2022b6cb6268120a6db3d23f06d3 Mon Sep 17 00:00:00 2001 From: Andrew Shvayka Date: Tue, 30 Jan 2024 14:04:54 +0200 Subject: [PATCH 148/179] Update question.md --- .github/ISSUE_TEMPLATE/question.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/question.md b/.github/ISSUE_TEMPLATE/question.md index 3fb84817ca..2f15690f68 100644 --- a/.github/ISSUE_TEMPLATE/question.md +++ b/.github/ISSUE_TEMPLATE/question.md @@ -1,6 +1,6 @@ --- name: Question -about: Describe your questions in details +about: Describe your questions in detail title: "Your title here" labels: ['question'] assignees: 'AndriichnekoDm' From 08c8a455a575fe2f7de551b160128dc27fd350d2 Mon Sep 17 00:00:00 2001 From: Andrew Shvayka Date: Tue, 30 Jan 2024 14:05:20 +0200 Subject: [PATCH 149/179] Update feature_request.md --- .github/ISSUE_TEMPLATE/feature_request.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index fcb1448199..c73f810cd8 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -1,7 +1,7 @@ --- name: Feature request about: Suggest an idea for this project -title: "[Feature Request]" +title: "Your title here" labels: ['feature'] assignees: 'AndriichnekoDm' From 847bbbdd228efeeb0d3c08ac7e40bf1e50633c52 Mon Sep 17 00:00:00 2001 From: Andrew Shvayka Date: Tue, 30 Jan 2024 14:05:42 +0200 Subject: [PATCH 150/179] Update ---bug-report.md --- .github/ISSUE_TEMPLATE/---bug-report.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/---bug-report.md b/.github/ISSUE_TEMPLATE/---bug-report.md index 33a0652e15..6d8889f98d 100644 --- a/.github/ISSUE_TEMPLATE/---bug-report.md +++ b/.github/ISSUE_TEMPLATE/---bug-report.md @@ -1,7 +1,7 @@ --- name: "\U0001F41E Bug report" about: Create a report to help us improve -title: "[Bug] " +title: "Your title here" labels: ['bug', 'unconfirmed'] assignees: AndriichnekoDm From ce9351ba276f40f5e9f080519def16239621ec0d Mon Sep 17 00:00:00 2001 From: dashevchenko Date: Tue, 30 Jan 2024 18:20:23 +0200 Subject: [PATCH 151/179] deleted unused classes --- ...leEngineQueueAckStrategyConfiguration.java | 30 ----------------- .../TbRuleEngineQueueConfiguration.java | 33 ------------------- ...ngineQueueSubmitStrategyConfiguration.java | 27 --------------- 3 files changed, 90 deletions(-) delete mode 100644 common/queue/src/main/java/org/thingsboard/server/queue/settings/TbRuleEngineQueueAckStrategyConfiguration.java delete mode 100644 common/queue/src/main/java/org/thingsboard/server/queue/settings/TbRuleEngineQueueConfiguration.java delete mode 100644 common/queue/src/main/java/org/thingsboard/server/queue/settings/TbRuleEngineQueueSubmitStrategyConfiguration.java diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/settings/TbRuleEngineQueueAckStrategyConfiguration.java b/common/queue/src/main/java/org/thingsboard/server/queue/settings/TbRuleEngineQueueAckStrategyConfiguration.java deleted file mode 100644 index 8edb224fec..0000000000 --- a/common/queue/src/main/java/org/thingsboard/server/queue/settings/TbRuleEngineQueueAckStrategyConfiguration.java +++ /dev/null @@ -1,30 +0,0 @@ -/** - * Copyright © 2016-2024 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.server.queue.settings; - -import lombok.Data; - -@Data -@Deprecated -public class TbRuleEngineQueueAckStrategyConfiguration { - - private String type; - private int retries; - private double failurePercentage; - private long pauseBetweenRetries; - private long maxPauseBetweenRetries; - -} diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/settings/TbRuleEngineQueueConfiguration.java b/common/queue/src/main/java/org/thingsboard/server/queue/settings/TbRuleEngineQueueConfiguration.java deleted file mode 100644 index 8199977618..0000000000 --- a/common/queue/src/main/java/org/thingsboard/server/queue/settings/TbRuleEngineQueueConfiguration.java +++ /dev/null @@ -1,33 +0,0 @@ -/** - * Copyright © 2016-2024 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.server.queue.settings; - -import lombok.Data; - -@Data -@Deprecated -public class TbRuleEngineQueueConfiguration { - - private String name; - private String topic; - private int pollInterval; - private int partitions; - private boolean consumerPerPartition; - private long packProcessingTimeout; - private TbRuleEngineQueueSubmitStrategyConfiguration submitStrategy; - private TbRuleEngineQueueAckStrategyConfiguration processingStrategy; - -} diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/settings/TbRuleEngineQueueSubmitStrategyConfiguration.java b/common/queue/src/main/java/org/thingsboard/server/queue/settings/TbRuleEngineQueueSubmitStrategyConfiguration.java deleted file mode 100644 index f073afad17..0000000000 --- a/common/queue/src/main/java/org/thingsboard/server/queue/settings/TbRuleEngineQueueSubmitStrategyConfiguration.java +++ /dev/null @@ -1,27 +0,0 @@ -/** - * Copyright © 2016-2024 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.server.queue.settings; - -import lombok.Data; - -@Data -@Deprecated -public class TbRuleEngineQueueSubmitStrategyConfiguration { - - private String type; - private int batchSize; - -} From 46585240227a56db505dc63b0311d6a9ada0371e Mon Sep 17 00:00:00 2001 From: dashevchenko Date: Wed, 31 Jan 2024 14:37:16 +0200 Subject: [PATCH 152/179] fixed license --- .../thingsboard/server/dao/sql/JpaPartitionedAbstractDao.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/JpaPartitionedAbstractDao.java b/dao/src/main/java/org/thingsboard/server/dao/sql/JpaPartitionedAbstractDao.java index 76db367ffb..a933837f5d 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/JpaPartitionedAbstractDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/JpaPartitionedAbstractDao.java @@ -1,5 +1,5 @@ /** - * Copyright © 2016-2023 The Thingsboard Authors + * Copyright © 2016-2024 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. From 54e9aba8fb2cb36de40fc260b9926a54fc50db00 Mon Sep 17 00:00:00 2001 From: Andrii Shvaika Date: Wed, 31 Jan 2024 16:59:39 +0200 Subject: [PATCH 153/179] Fix compilation issue --- .../service/edge/rpc/processor/alarm/BaseAlarmProcessor.java | 2 +- .../thingsboard/server/dao/sql/JpaPartitionedAbstractDao.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/alarm/BaseAlarmProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/alarm/BaseAlarmProcessor.java index 11cd2ab56c..97e1590b5b 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/alarm/BaseAlarmProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/alarm/BaseAlarmProcessor.java @@ -113,7 +113,7 @@ public abstract class BaseAlarmProcessor extends BaseEdgeProcessor { } switch (alarmCommentUpdateMsg.getMsgType()) { case ENTITY_CREATED_RPC_MESSAGE: - alarmCommentDao.createAlarmComment(tenantId, alarmComment); + alarmCommentDao.save(tenantId, alarmComment); break; case ENTITY_UPDATED_RPC_MESSAGE: alarmCommentService.createOrUpdateAlarmComment(tenantId, alarmComment); diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/JpaPartitionedAbstractDao.java b/dao/src/main/java/org/thingsboard/server/dao/sql/JpaPartitionedAbstractDao.java index 76db367ffb..a933837f5d 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/JpaPartitionedAbstractDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/JpaPartitionedAbstractDao.java @@ -1,5 +1,5 @@ /** - * Copyright © 2016-2023 The Thingsboard Authors + * Copyright © 2016-2024 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. From 9b32a51d4b100d26f976b52e73a83ec380f18722 Mon Sep 17 00:00:00 2001 From: Andrii Landiak Date: Thu, 1 Feb 2024 13:46:31 +0200 Subject: [PATCH 154/179] Refactoring due to review. Fix naming, improve upgrade logic --- .../server/service/edge/rpc/EdgeGrpcSession.java | 4 +++- .../install/DefaultSystemDataLoaderService.java | 3 +++ .../notification/DefaultNotificationCenter.java | 10 ++++++---- .../EdgeCommunicationFailureTriggerProcessor.java | 2 +- .../impl/NotificationRuleExportService.java | 7 ++++--- .../EdgeCommunicationFailureNotificationInfo.java | 1 - .../info/EdgeConnectionNotificationInfo.java | 1 - .../trigger/EdgeCommunicationFailureTrigger.java | 2 +- .../rule/trigger/EdgeConnectionTrigger.java | 4 ++-- .../server/dao/edge/BaseEdgeEventService.java | 7 ++++--- .../DefaultNotificationSettingsService.java | 13 ++++++++----- .../notification/edge_communication_failure.md | 2 +- .../help/en_US/notification/edge_connection.md | 2 +- 13 files changed, 34 insertions(+), 24 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java index 44bdfcdb1c..b61d7d5e95 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java @@ -479,11 +479,13 @@ public final class EdgeGrpcSession implements Closeable { log.trace("[{}][{}][{}] downlink msg(s) are going to be send.", this.tenantId, this.sessionId, copy.size()); for (DownlinkMsg downlinkMsg : copy) { if (this.clientMaxInboundMessageSize != 0 && downlinkMsg.getSerializedSize() > this.clientMaxInboundMessageSize) { + String error = String.format("Client max inbound message size [{%s}] is exceeded. Please increase value of CLOUD_RPC_MAX_INBOUND_MESSAGE_SIZE " + + "env variable on the edge and restart it.", this.clientMaxInboundMessageSize); String message = String.format("Downlink msg size [{%s}] exceeds client max inbound message size [{%s}]. " + "Please increase value of CLOUD_RPC_MAX_INBOUND_MESSAGE_SIZE env variable on the edge and restart it.", downlinkMsg.getSerializedSize(), this.clientMaxInboundMessageSize); log.error("[{}][{}][{}] {} Message {}", this.tenantId, edge.getId(), this.sessionId, message, downlinkMsg); ctx.getNotificationRuleProcessor().process(EdgeCommunicationFailureTrigger.builder().tenantId(tenantId) - .edgeId(edge.getId()).customerId(edge.getCustomerId()).edgeName(edge.getName()).failureMsg(message).error(message).build()); + .edgeId(edge.getId()).customerId(edge.getCustomerId()).edgeName(edge.getName()).failureMsg(message).error(error).build()); sessionState.getPendingMsgsMap().remove(downlinkMsg.getDownlinkMsgId()); } else { sendDownlinkMsg(ResponseMsg.newBuilder() diff --git a/application/src/main/java/org/thingsboard/server/service/install/DefaultSystemDataLoaderService.java b/application/src/main/java/org/thingsboard/server/service/install/DefaultSystemDataLoaderService.java index fcc829886c..e50da5ea62 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/DefaultSystemDataLoaderService.java +++ b/application/src/main/java/org/thingsboard/server/service/install/DefaultSystemDataLoaderService.java @@ -696,6 +696,7 @@ public class DefaultSystemDataLoaderService implements SystemDataLoaderService { } @Override + @SneakyThrows public void updateDefaultNotificationConfigs() { PageDataIterable tenants = new PageDataIterable<>(tenantService::findTenantsIds, 500); ExecutorService executor = Executors.newFixedThreadPool(Math.max(Runtime.getRuntime().availableProcessors(), 4)); @@ -710,6 +711,8 @@ public class DefaultSystemDataLoaderService implements SystemDataLoaderService { } }); } + executor.shutdown(); + executor.awaitTermination(Integer.MAX_VALUE, TimeUnit.SECONDS); notificationSettingsService.updateDefaultNotificationConfigs(TenantId.SYS_TENANT_ID); } diff --git a/application/src/main/java/org/thingsboard/server/service/notification/DefaultNotificationCenter.java b/application/src/main/java/org/thingsboard/server/service/notification/DefaultNotificationCenter.java index 5bbde6de81..be37d98bb5 100644 --- a/application/src/main/java/org/thingsboard/server/service/notification/DefaultNotificationCenter.java +++ b/application/src/main/java/org/thingsboard/server/service/notification/DefaultNotificationCenter.java @@ -241,11 +241,13 @@ public class DefaultNotificationCenter extends AbstractSubscriptionService imple case PLATFORM_USERS: { PlatformUsersNotificationTargetConfig targetConfig = (PlatformUsersNotificationTargetConfig) target.getConfiguration(); if (targetConfig.getUsersFilter().getType().isForRules() && ctx.getRequest().getInfo() instanceof RuleOriginatedNotificationInfo) { - recipients = new PageDataIterable<>(pageLink -> - notificationTargetService.findRecipientsForRuleNotificationTargetConfig(ctx.getTenantId(), targetConfig, (RuleOriginatedNotificationInfo) ctx.getRequest().getInfo(), pageLink), 500); + recipients = new PageDataIterable<>(pageLink -> { + return notificationTargetService.findRecipientsForRuleNotificationTargetConfig(ctx.getTenantId(), targetConfig, (RuleOriginatedNotificationInfo) ctx.getRequest().getInfo(), pageLink); + }, 500); } else { - recipients = new PageDataIterable<>(pageLink -> - notificationTargetService.findRecipientsForNotificationTargetConfig(ctx.getTenantId(), targetConfig, pageLink), 500); + recipients = new PageDataIterable<>(pageLink -> { + return notificationTargetService.findRecipientsForNotificationTargetConfig(ctx.getTenantId(), targetConfig, pageLink); + }, 500); } break; } diff --git a/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/EdgeCommunicationFailureTriggerProcessor.java b/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/EdgeCommunicationFailureTriggerProcessor.java index dc54024eec..38d8ae9805 100644 --- a/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/EdgeCommunicationFailureTriggerProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/EdgeCommunicationFailureTriggerProcessor.java @@ -53,7 +53,7 @@ public class EdgeCommunicationFailureTriggerProcessor implements NotificationRul } private String truncateFailureMsg(String input) { - int maxLength = 800; + int maxLength = 500; if (input != null && input.length() > maxLength) { return input.substring(0, maxLength); } diff --git a/application/src/main/java/org/thingsboard/server/service/sync/ie/exporting/impl/NotificationRuleExportService.java b/application/src/main/java/org/thingsboard/server/service/sync/ie/exporting/impl/NotificationRuleExportService.java index 40d7d7c2b5..35f2489f83 100644 --- a/application/src/main/java/org/thingsboard/server/service/sync/ie/exporting/impl/NotificationRuleExportService.java +++ b/application/src/main/java/org/thingsboard/server/service/sync/ie/exporting/impl/NotificationRuleExportService.java @@ -29,8 +29,8 @@ import org.thingsboard.server.common.data.notification.rule.EscalatedNotificatio import org.thingsboard.server.common.data.notification.rule.NotificationRule; import org.thingsboard.server.common.data.notification.rule.NotificationRuleRecipientsConfig; import org.thingsboard.server.common.data.notification.rule.trigger.config.DeviceActivityNotificationRuleTriggerConfig; -import org.thingsboard.server.common.data.notification.rule.trigger.config.EdgeConnectionNotificationRuleTriggerConfig; import org.thingsboard.server.common.data.notification.rule.trigger.config.EdgeCommunicationFailureNotificationRuleTriggerConfig; +import org.thingsboard.server.common.data.notification.rule.trigger.config.EdgeConnectionNotificationRuleTriggerConfig; import org.thingsboard.server.common.data.notification.rule.trigger.config.NotificationRuleTriggerConfig; import org.thingsboard.server.common.data.notification.rule.trigger.config.RuleEngineComponentLifecycleEventNotificationRuleTriggerConfig; import org.thingsboard.server.common.data.sync.ie.EntityExportData; @@ -92,8 +92,9 @@ public class NotificationRuleExportService> escalationTable = new LinkedHashMap<>(recipientsConfig.getEscalationTable()); - escalationTable.replaceAll((delay, targets) -> - toExternalIds(targets, NotificationTargetId::new, ctx).collect(Collectors.toList())); + escalationTable.replaceAll((delay, targets) -> { + return toExternalIds(targets, NotificationTargetId::new, ctx).collect(Collectors.toList()); + }); recipientsConfig.setEscalationTable(escalationTable); break; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/notification/info/EdgeCommunicationFailureNotificationInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/info/EdgeCommunicationFailureNotificationInfo.java index 2edab592d5..6d0f2ae5f5 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/notification/info/EdgeCommunicationFailureNotificationInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/info/EdgeCommunicationFailureNotificationInfo.java @@ -43,7 +43,6 @@ public class EdgeCommunicationFailureNotificationInfo implements RuleOriginatedN @Override public Map getTemplateData() { return mapOf( - "tenantId", tenantId.toString(), "edgeId", edgeId.toString(), "edgeName", edgeName, "failureMsg", failureMsg diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/notification/info/EdgeConnectionNotificationInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/info/EdgeConnectionNotificationInfo.java index e7b6494fdb..62b1370566 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/notification/info/EdgeConnectionNotificationInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/info/EdgeConnectionNotificationInfo.java @@ -44,7 +44,6 @@ public class EdgeConnectionNotificationInfo implements RuleOriginatedNotificatio public Map getTemplateData() { return mapOf( "eventType", eventType, - "tenantId", tenantId.toString(), "edgeId", edgeId.toString(), "edgeName", edgeName ); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/EdgeCommunicationFailureTrigger.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/EdgeCommunicationFailureTrigger.java index 6400a5c67a..6212c22a0d 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/EdgeCommunicationFailureTrigger.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/EdgeCommunicationFailureTrigger.java @@ -43,7 +43,7 @@ public class EdgeCommunicationFailureTrigger implements NotificationRuleTrigger @Override public String getDeduplicationKey() { - return String.join(":", NotificationRuleTrigger.super.getDeduplicationKey(), edgeId.toString(), error); + return String.join(":", NotificationRuleTrigger.super.getDeduplicationKey(), error); } @Override diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/EdgeConnectionTrigger.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/EdgeConnectionTrigger.java index fe5f6fa6b1..766338dba6 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/EdgeConnectionTrigger.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/EdgeConnectionTrigger.java @@ -42,12 +42,12 @@ public class EdgeConnectionTrigger implements NotificationRuleTrigger { @Override public String getDeduplicationKey() { - return String.join(":", NotificationRuleTrigger.super.getDeduplicationKey(), edgeName, String.valueOf(connected)); + return String.join(":", NotificationRuleTrigger.super.getDeduplicationKey(), String.valueOf(connected)); } @Override public long getDefaultDeduplicationDuration() { - return TimeUnit.MINUTES.toMillis(30); + return TimeUnit.MINUTES.toMillis(1); } @Override diff --git a/dao/src/main/java/org/thingsboard/server/dao/edge/BaseEdgeEventService.java b/dao/src/main/java/org/thingsboard/server/dao/edge/BaseEdgeEventService.java index 6a05b98d16..43c3dc4914 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/edge/BaseEdgeEventService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/edge/BaseEdgeEventService.java @@ -41,9 +41,10 @@ public class BaseEdgeEventService implements EdgeEventService { @Override public ListenableFuture saveAsync(EdgeEvent edgeEvent) { - boolean isEdgeEventTenantRateLimitReached = !rateLimitService.checkRateLimit(LimitedApi.EDGE_EVENTS, edgeEvent.getTenantId()); - boolean isEdgeEventRateLimitPerEdgeReached = !rateLimitService.checkRateLimit(LimitedApi.EDGE_EVENTS_PER_EDGE, edgeEvent.getTenantId(), edgeEvent.getEdgeId()); - if (isEdgeEventTenantRateLimitReached || isEdgeEventRateLimitPerEdgeReached) { + if (!rateLimitService.checkRateLimit(LimitedApi.EDGE_EVENTS, edgeEvent.getTenantId())) { + throw new TbRateLimitsException(EntityType.TENANT); + } + if (!rateLimitService.checkRateLimit(LimitedApi.EDGE_EVENTS_PER_EDGE, edgeEvent.getTenantId(), edgeEvent.getEdgeId())) { throw new TbRateLimitsException(EntityType.EDGE); } edgeEventValidator.validate(edgeEvent, EdgeEvent::getTenantId); diff --git a/dao/src/main/java/org/thingsboard/server/dao/notification/DefaultNotificationSettingsService.java b/dao/src/main/java/org/thingsboard/server/dao/notification/DefaultNotificationSettingsService.java index b42fdd7645..c858eecf62 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/notification/DefaultNotificationSettingsService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/notification/DefaultNotificationSettingsService.java @@ -210,19 +210,22 @@ public class DefaultNotificationSettingsService implements NotificationSettingsS defaultNotifications.create(tenantId, DefaultNotifications.exceededPerEntityRateLimits, affectedTenantAdmins.getId()); defaultNotifications.create(tenantId, DefaultNotifications.exceededRateLimitsForSysadmin, sysAdmins.getId()); } else { - List requiredNotificationTypes = List.of(NotificationType.EDGE_CONNECTION, NotificationType.EDGE_COMMUNICATION_FAILURE); - List existingNotificationTypes = notificationTemplateService.findNotificationTemplatesByTenantIdAndNotificationTypes( + var requiredNotificationTypes = List.of(NotificationType.EDGE_CONNECTION, NotificationType.EDGE_COMMUNICATION_FAILURE); + var existingNotificationTypes = notificationTemplateService.findNotificationTemplatesByTenantIdAndNotificationTypes( tenantId, requiredNotificationTypes, new PageLink(1)) .getData() .stream() .map(NotificationTemplate::getNotificationType) - .collect(Collectors.toList()); + .collect(Collectors.toSet()); + + if (existingNotificationTypes.containsAll(requiredNotificationTypes)) { + return; + } NotificationTarget tenantAdmins = notificationTargetService.findNotificationTargetsByTenantIdAndUsersFilterType(tenantId, UsersFilterType.TENANT_ADMINISTRATORS) .stream() .findFirst() - .orElseGet(() -> createTarget(tenantId, "Tenant administrators", new TenantAdministratorsFilter(), - tenantId.isSysTenantId() ? "All tenant administrators" : "Tenant administrators")); + .orElseGet(() -> createTarget(tenantId, "Tenant administrators", new TenantAdministratorsFilter(), "Tenant administrators")); for (NotificationType type : requiredNotificationTypes) { if (!existingNotificationTypes.contains(type)) { diff --git a/ui-ngx/src/assets/help/en_US/notification/edge_communication_failure.md b/ui-ngx/src/assets/help/en_US/notification/edge_communication_failure.md index 03f2a2816a..712f2b45e7 100644 --- a/ui-ngx/src/assets/help/en_US/notification/edge_communication_failure.md +++ b/ui-ngx/src/assets/help/en_US/notification/edge_communication_failure.md @@ -1,4 +1,4 @@ -#### Edge notification templatization +#### Edge communication failure notification templatization

diff --git a/ui-ngx/src/assets/help/en_US/notification/edge_connection.md b/ui-ngx/src/assets/help/en_US/notification/edge_connection.md index fed6c0372e..37f0ec7573 100644 --- a/ui-ngx/src/assets/help/en_US/notification/edge_connection.md +++ b/ui-ngx/src/assets/help/en_US/notification/edge_connection.md @@ -1,4 +1,4 @@ -#### Edge notification templatization +#### Edge connection notification templatization

From 4b29a8f3ff3aec1777828630e03e7ea20841ba0f Mon Sep 17 00:00:00 2001 From: Igor Kulikov Date: Thu, 1 Feb 2024 19:16:37 +0200 Subject: [PATCH 155/179] UI: Implement action button widget. --- .../json/system/widget_bundles/buttons.json | 13 + .../system/widget_types/action_button.json | 27 ++ ui-ngx/src/app/core/api/widget-api.models.ts | 1 + ui-ngx/src/app/core/services/utils.service.ts | 26 +- ui-ngx/src/app/modules/common/modules-map.ts | 16 +- .../dashboard/dashboard.component.html | 1 + .../dashboard/dashboard.component.ts | 3 + .../action/widget-action-dialog.component.ts | 11 +- .../basic/basic-widget-config.module.ts | 12 +- .../action-button-basic-config.component.html | 77 ++++++ .../action-button-basic-config.component.ts | 139 ++++++++++ .../single-switch-basic-config.component.html | 18 +- .../widget/config/datasource.component.html | 4 +- .../widget/config/datasource.component.ts | 30 +- .../widget/config/datasources.component.ts | 5 +- .../config/widget-config-components.module.ts | 17 +- .../config/widget-config.component.models.ts | 14 +- .../widget/lib/action/action-widget.scss | 46 ++++ .../action-button-widget.component.html | 35 +++ .../action-button-widget.component.scss | 28 ++ .../button/action-button-widget.component.ts | 100 +++++++ .../lib/button/action-button-widget.models.ts | 67 +++++ .../rpc/single-switch-widget.component.html | 8 +- .../rpc/single-switch-widget.component.scss | 30 -- .../lib/rpc/single-switch-widget.component.ts | 26 +- ... => action-settings-button.component.html} | 4 +- ...utton.scss => action-settings-button.scss} | 2 +- ...s => action-settings-panel.component.scss} | 8 +- ...custom-action-pretty-editor.component.html | 0 ...custom-action-pretty-editor.component.scss | 2 +- .../custom-action-pretty-editor.component.ts | 4 +- ...ction-pretty-resources-tabs.component.html | 0 ...ction-pretty-resources-tabs.component.scss | 0 ...-action-pretty-resources-tabs.component.ts | 2 +- .../common}/action/custom-action.models.ts | 0 .../common}/action/custom-sample-css.raw | 0 .../common}/action/custom-sample-html.raw | 0 .../common}/action/custom-sample-js.raw | 0 ...value-action-settings-panel.component.html | 14 +- ...t-value-action-settings-panel.component.ts | 21 +- .../get-value-action-settings.component.ts | 29 +- .../mobile-action-editor.component.html | 0 .../action/mobile-action-editor.component.ts | 4 +- .../action/mobile-action-editor.models.ts | 0 ...value-action-settings-panel.component.html | 8 +- ...t-value-action-settings-panel.component.ts | 12 +- .../set-value-action-settings.component.ts | 14 +- ...idget-action-settings-panel.component.html | 42 +++ .../widget-action-settings-panel.component.ts | 88 ++++++ .../widget-action-settings.component.ts | 136 +++++++++ .../action/widget-action.component.html | 0 .../common}/action/widget-action.component.ts | 2 +- .../widget-button-appearance.component.html | 97 +++++++ .../widget-button-appearance.component.ts | 141 ++++++++++ ...t-button-custom-style-panel.component.html | 93 +++++++ ...t-button-custom-style-panel.component.scss | 68 +++++ ...get-button-custom-style-panel.component.ts | 171 ++++++++++++ .../widget-button-custom-style.component.html | 44 +++ .../widget-button-custom-style.component.scss | 46 ++++ .../widget-button-custom-style.component.ts | 157 +++++++++++ .../common/widget-settings-common.module.ts | 47 +++- ...ngle-switch-widget-settings.component.html | 18 +- ...single-switch-widget-settings.component.ts | 6 +- .../widget/widget-component.service.ts | 3 + .../widget/widget-components.module.ts | 7 +- .../widget/widget-container.component.html | 2 + .../widget/widget-container.component.scss | 7 + .../widget/widget-container.component.ts | 24 +- .../widget/widget-preview.component.html | 1 + .../components/widget/widget.component.ts | 16 +- .../home/models/widget-component.models.ts | 2 + .../button/widget-button.component.html | 39 +++ .../button/widget-button.component.scss | 189 +++++++++++++ .../button/widget-button.component.ts | 178 ++++++++++++ .../components/button/widget-button.models.ts | 259 ++++++++++++++++++ .../models/action-widget-settings.models.ts | 19 +- .../shared/models/widget-settings.models.ts | 27 +- ui-ngx/src/app/shared/models/widget.models.ts | 26 ++ ui-ngx/src/app/shared/shared.module.ts | 7 +- .../assets/locale/locale.constant-en_US.json | 47 +++- ui-ngx/src/assets/widget/button/basic.svg | 17 ++ ui-ngx/src/assets/widget/button/filled.svg | 19 ++ ui-ngx/src/assets/widget/button/outlined.svg | 20 ++ .../src/assets/widget/button/underlined.svg | 23 ++ ui-ngx/src/form.scss | 8 + 85 files changed, 2790 insertions(+), 184 deletions(-) create mode 100644 application/src/main/data/json/system/widget_bundles/buttons.json create mode 100644 application/src/main/data/json/system/widget_types/action_button.json create mode 100644 ui-ngx/src/app/modules/home/components/widget/config/basic/button/action-button-basic-config.component.html create mode 100644 ui-ngx/src/app/modules/home/components/widget/config/basic/button/action-button-basic-config.component.ts create mode 100644 ui-ngx/src/app/modules/home/components/widget/lib/action/action-widget.scss create mode 100644 ui-ngx/src/app/modules/home/components/widget/lib/button/action-button-widget.component.html create mode 100644 ui-ngx/src/app/modules/home/components/widget/lib/button/action-button-widget.component.scss create mode 100644 ui-ngx/src/app/modules/home/components/widget/lib/button/action-button-widget.component.ts create mode 100644 ui-ngx/src/app/modules/home/components/widget/lib/button/action-button-widget.models.ts rename ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/{value-action-settings-button.component.html => action-settings-button.component.html} (88%) rename ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/{value-action-settings-button.scss => action-settings-button.scss} (95%) rename ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/{value-action-settings-panel.component.scss => action-settings-panel.component.scss} (87%) rename ui-ngx/src/app/modules/home/components/widget/{config => lib/settings/common}/action/custom-action-pretty-editor.component.html (100%) rename ui-ngx/src/app/modules/home/components/widget/{config => lib/settings/common}/action/custom-action-pretty-editor.component.scss (95%) rename ui-ngx/src/app/modules/home/components/widget/{config => lib/settings/common}/action/custom-action-pretty-editor.component.ts (95%) rename ui-ngx/src/app/modules/home/components/widget/{config => lib/settings/common}/action/custom-action-pretty-resources-tabs.component.html (100%) rename ui-ngx/src/app/modules/home/components/widget/{config => lib/settings/common}/action/custom-action-pretty-resources-tabs.component.scss (100%) rename ui-ngx/src/app/modules/home/components/widget/{config => lib/settings/common}/action/custom-action-pretty-resources-tabs.component.ts (99%) rename ui-ngx/src/app/modules/home/components/widget/{config => lib/settings/common}/action/custom-action.models.ts (100%) rename ui-ngx/src/app/modules/home/components/widget/{config => lib/settings/common}/action/custom-sample-css.raw (100%) rename ui-ngx/src/app/modules/home/components/widget/{config => lib/settings/common}/action/custom-sample-html.raw (100%) rename ui-ngx/src/app/modules/home/components/widget/{config => lib/settings/common}/action/custom-sample-js.raw (100%) rename ui-ngx/src/app/modules/home/components/widget/{config => lib/settings/common}/action/mobile-action-editor.component.html (100%) rename ui-ngx/src/app/modules/home/components/widget/{config => lib/settings/common}/action/mobile-action-editor.component.ts (98%) rename ui-ngx/src/app/modules/home/components/widget/{config => lib/settings/common}/action/mobile-action-editor.models.ts (100%) create mode 100644 ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/widget-action-settings-panel.component.html create mode 100644 ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/widget-action-settings-panel.component.ts create mode 100644 ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/widget-action-settings.component.ts rename ui-ngx/src/app/modules/home/components/widget/{config => lib/settings/common}/action/widget-action.component.html (100%) rename ui-ngx/src/app/modules/home/components/widget/{config => lib/settings/common}/action/widget-action.component.ts (99%) create mode 100644 ui-ngx/src/app/modules/home/components/widget/lib/settings/common/button/widget-button-appearance.component.html create mode 100644 ui-ngx/src/app/modules/home/components/widget/lib/settings/common/button/widget-button-appearance.component.ts create mode 100644 ui-ngx/src/app/modules/home/components/widget/lib/settings/common/button/widget-button-custom-style-panel.component.html create mode 100644 ui-ngx/src/app/modules/home/components/widget/lib/settings/common/button/widget-button-custom-style-panel.component.scss create mode 100644 ui-ngx/src/app/modules/home/components/widget/lib/settings/common/button/widget-button-custom-style-panel.component.ts create mode 100644 ui-ngx/src/app/modules/home/components/widget/lib/settings/common/button/widget-button-custom-style.component.html create mode 100644 ui-ngx/src/app/modules/home/components/widget/lib/settings/common/button/widget-button-custom-style.component.scss create mode 100644 ui-ngx/src/app/modules/home/components/widget/lib/settings/common/button/widget-button-custom-style.component.ts create mode 100644 ui-ngx/src/app/shared/components/button/widget-button.component.html create mode 100644 ui-ngx/src/app/shared/components/button/widget-button.component.scss create mode 100644 ui-ngx/src/app/shared/components/button/widget-button.component.ts create mode 100644 ui-ngx/src/app/shared/components/button/widget-button.models.ts create mode 100644 ui-ngx/src/assets/widget/button/basic.svg create mode 100644 ui-ngx/src/assets/widget/button/filled.svg create mode 100644 ui-ngx/src/assets/widget/button/outlined.svg create mode 100644 ui-ngx/src/assets/widget/button/underlined.svg diff --git a/application/src/main/data/json/system/widget_bundles/buttons.json b/application/src/main/data/json/system/widget_bundles/buttons.json new file mode 100644 index 0000000000..046e16dd7e --- /dev/null +++ b/application/src/main/data/json/system/widget_bundles/buttons.json @@ -0,0 +1,13 @@ +{ + "widgetsBundle": { + "alias": "buttons", + "title": "Buttons", + "image": null, + "description": null, + "order": 7500, + "name": "Buttons" + }, + "widgetTypeFqns": [ + "action_button" + ] +} \ No newline at end of file diff --git a/application/src/main/data/json/system/widget_types/action_button.json b/application/src/main/data/json/system/widget_types/action_button.json new file mode 100644 index 0000000000..3ad518ce23 --- /dev/null +++ b/application/src/main/data/json/system/widget_types/action_button.json @@ -0,0 +1,27 @@ +{ + "fqn": "action_button", + "name": "Action button", + "deprecated": false, + "image": "tb-image:YWN0aW9uLWJ1dHRvbi5zdmc=:IkFjdGlvbiBidXR0b24iIHN5c3RlbSB3aWRnZXQgaW1hZ2U=;data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAwIiBoZWlnaHQ9IjE2MCIgdmlld0JveD0iMCAwIDIwMCAxNjAiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHg9IjAuNzUiIHk9IjUwLjc1IiB3aWR0aD0iMTk4LjUiIGhlaWdodD0iNTguNSIgcng9IjMuMjUiIGZpbGw9IndoaXRlIi8+CjxyZWN0IHg9IjAuNzUiIHk9IjUwLjc1IiB3aWR0aD0iMTk4LjUiIGhlaWdodD0iNTguNSIgcng9IjMuMjUiIHN0cm9rZT0iIzNGNTJERCIgc3Ryb2tlLXdpZHRoPSIxLjUiLz4KPHBhdGggZD0iTTYyLjE2NzMgODkuMzMzM1Y4Mi4zMzMzSDY2LjgzNFY4OS4zMzMzSDcyLjY2NzNWODBINzYuMTY3M0w2NC41MDA3IDY5LjVMNTIuODM0IDgwSDU2LjMzNFY4OS4zMzMzSDYyLjE2NzNaIiBmaWxsPSIjM0Y1MkREIi8+CjxwYXRoIGQ9Ik05MC4xOTUzIDgwLjkzMTZIODYuMjFMODYuMTg4NSA3OC45NjU4SDg5LjY2ODlDOTAuMjU2MiA3OC45NjU4IDkwLjc1MzkgNzguODc5OSA5MS4xNjIxIDc4LjcwOEM5MS41Nzc1IDc4LjUyOSA5MS44OTI2IDc4LjI3NDcgOTIuMTA3NCA3Ny45NDUzQzkyLjMyMjMgNzcuNjA4NyA5Mi40Mjk3IDc3LjIwNDEgOTIuNDI5NyA3Ni43MzE0QzkyLjQyOTcgNzYuMjA4NyA5Mi4zMjk0IDc1Ljc4MjYgOTIuMTI4OSA3NS40NTMxQzkxLjkyODQgNzUuMTIzNyA5MS42MjA0IDc0Ljg4MzggOTEuMjA1MSA3NC43MzM0QzkwLjc5NjkgNzQuNTgzIDkwLjI3NDEgNzQuNTA3OCA4OS42MzY3IDc0LjUwNzhIODcuMDI2NFY4OEg4NC4zMzAxVjcyLjM1OTRIODkuNjM2N0M5MC40OTYxIDcyLjM1OTQgOTEuMjYyNCA3Mi40NDE3IDkxLjkzNTUgNzIuNjA2NEM5Mi42MTU5IDcyLjc3MTIgOTMuMTkyNCA3My4wMjkgOTMuNjY1IDczLjM3OTlDOTQuMTQ0OSA3My43MjM2IDk0LjUwNjUgNzQuMTYwNSA5NC43NSA3NC42OTA0Qzk1LjAwMDcgNzUuMjIwNCA5NS4xMjYgNzUuODUwNiA5NS4xMjYgNzYuNTgxMUM5NS4xMjYgNzcuMjI1NiA5NC45NzIgNzcuODE2NCA5NC42NjQxIDc4LjM1MzVDOTQuMzU2MSA3OC44ODM1IDkzLjkwMTQgNzkuMzE2NyA5My4yOTk4IDc5LjY1MzNDOTIuNjk4MiA3OS45ODk5IDkxLjk0OTkgODAuMTkwNCA5MS4wNTQ3IDgwLjI1NDlMOTAuMTk1MyA4MC45MzE2Wk05MC4wNzcxIDg4SDg1LjM2MTNMODYuNTc1MiA4NS44NjIzSDkwLjA3NzFDOTAuNjg1OSA4NS44NjIzIDkxLjE5NDMgODUuNzYyIDkxLjYwMjUgODUuNTYxNUM5Mi4wMTA3IDg1LjM1MzggOTIuMzE1MSA4NS4wNzEgOTIuNTE1NiA4NC43MTI5QzkyLjcyMzMgODQuMzQ3NyA5Mi44MjcxIDgzLjkyMTUgOTIuODI3MSA4My40MzQ2QzkyLjgyNzEgODIuOTI2MSA5Mi43Mzc2IDgyLjQ4NTcgOTIuNTU4NiA4Mi4xMTMzQzkyLjM3OTYgODEuNzMzNyA5Mi4wOTY3IDgxLjQ0MzcgOTEuNzEgODEuMjQzMkM5MS4zMjMyIDgxLjAzNTUgOTAuODE4NCA4MC45MzE2IDkwLjE5NTMgODAuOTMxNkg4Ny4xNjZMODcuMTg3NSA3OC45NjU4SDkxLjEyOTlMOTEuNzQyMiA3OS43MDdDOTIuNjAxNiA3OS43MzU3IDkzLjMwNyA3OS45MjU1IDkzLjg1ODQgODAuMjc2NEM5NC40MTcgODAuNjI3MyA5NC44MzI0IDgxLjA4MiA5NS4xMDQ1IDgxLjY0MDZDOTUuMzc2NiA4Mi4xOTkyIDk1LjUxMjcgODIuODAwOCA5NS41MTI3IDgzLjQ0NTNDOTUuNTEyNyA4NC40NDA4IDk1LjI5NDMgODUuMjc1MSA5NC44NTc0IDg1Ljk0ODJDOTQuNDI3NyA4Ni42MjE0IDkzLjgwODMgODcuMTMzNSA5Mi45OTkgODcuNDg0NEM5Mi4xODk4IDg3LjgyODEgOTEuMjE1OCA4OCA5MC4wNzcxIDg4Wk0xMDUuMjE2IDg1LjI2MDdWNzYuMzc3SDEwNy44MTVWODhIMTA1LjM2NkwxMDUuMjE2IDg1LjI2MDdaTTEwNS41ODEgODIuODQzOEwxMDYuNDUxIDgyLjgyMjNDMTA2LjQ1MSA4My42MDI5IDEwNi4zNjUgODQuMzIyNiAxMDYuMTkzIDg0Ljk4MTRDMTA2LjAyMSA4NS42MzMxIDEwNS43NTcgODYuMjAyNSAxMDUuMzk4IDg2LjY4OTVDMTA1LjA0IDg3LjE2OTMgMTA0LjU4MiA4Ny41NDUyIDEwNC4wMjMgODcuODE3NEMxMDMuNDY1IDg4LjA4MjQgMTAyLjc5NSA4OC4yMTQ4IDEwMi4wMTUgODguMjE0OEMxMDEuNDQ5IDg4LjIxNDggMTAwLjkzIDg4LjEzMjUgMTAwLjQ1NyA4Ny45Njc4Qzk5Ljk4NDQgODcuODAzMSA5OS41NzYyIDg3LjU0ODggOTkuMjMyNCA4Ny4yMDUxQzk4Ljg5NTggODYuODYxMyA5OC42MzQ0IDg2LjQxMzcgOTguNDQ4MiA4NS44NjIzQzk4LjI2MiA4NS4zMTA5IDk4LjE2ODkgODQuNjUyIDk4LjE2ODkgODMuODg1N1Y3Ni4zNzdIMTAwLjc1OFY4My45MDcyQzEwMC43NTggODQuMzI5OCAxMDAuODA4IDg0LjY4NDIgMTAwLjkwOCA4NC45NzA3QzEwMS4wMDggODUuMjUgMTAxLjE0NSA4NS40NzU2IDEwMS4zMTYgODUuNjQ3NUMxMDEuNDg4IDg1LjgxOTMgMTAxLjY4OSA4NS45NDExIDEwMS45MTggODYuMDEyN0MxMDIuMTQ3IDg2LjA4NDMgMTAyLjM5MSA4Ni4xMjAxIDEwMi42NDggODYuMTIwMUMxMDMuMzg2IDg2LjEyMDEgMTAzLjk2NiA4NS45NzY5IDEwNC4zODkgODUuNjkwNEMxMDQuODE4IDg1LjM5NjggMTA1LjEyMyA4NS4wMDI5IDEwNS4zMDIgODQuNTA4OEMxMDUuNDg4IDg0LjAxNDYgMTA1LjU4MSA4My40NTk2IDEwNS41ODEgODIuODQzOFpNMTE2LjA0NyA3Ni4zNzdWNzguMjY3NkgxMDkuNDk0Vjc2LjM3N0gxMTYuMDQ3Wk0xMTEuMzg1IDczLjUzMDNIMTEzLjk3NFY4NC43ODgxQzExMy45NzQgODUuMTQ2MiAxMTQuMDI0IDg1LjQyMTkgMTE0LjEyNCA4NS42MTUyQzExNC4yMzEgODUuODAxNCAxMTQuMzc4IDg1LjkyNjggMTE0LjU2NCA4NS45OTEyQzExNC43NTEgODYuMDU1NyAxMTQuOTY5IDg2LjA4NzkgMTE1LjIyIDg2LjA4NzlDMTE1LjM5OSA4Ni4wODc5IDExNS41NzEgODYuMDc3MSAxMTUuNzM1IDg2LjA1NTdDMTE1LjkgODYuMDM0MiAxMTYuMDMzIDg2LjAxMjcgMTE2LjEzMyA4NS45OTEyTDExNi4xNDQgODcuOTY3OEMxMTUuOTI5IDg4LjAzMjIgMTE1LjY3OCA4OC4wODk1IDExNS4zOTIgODguMTM5NkMxMTUuMTEyIDg4LjE4OTggMTE0Ljc5IDg4LjIxNDggMTE0LjQyNSA4OC4yMTQ4QzExMy44MyA4OC4yMTQ4IDExMy4zMDQgODguMTExIDExMi44NDYgODcuOTAzM0MxMTIuMzg3IDg3LjY4ODUgMTEyLjAyOSA4Ny4zNDExIDExMS43NzEgODYuODYxM0MxMTEuNTE0IDg2LjM4MTUgMTExLjM4NSA4NS43NDQxIDExMS4zODUgODQuOTQ5MlY3My41MzAzWk0xMjMuNjIzIDc2LjM3N1Y3OC4yNjc2SDExNy4wN1Y3Ni4zNzdIMTIzLjYyM1pNMTE4Ljk2MSA3My41MzAzSDEyMS41NVY4NC43ODgxQzEyMS41NSA4NS4xNDYyIDEyMS42IDg1LjQyMTkgMTIxLjcgODUuNjE1MkMxMjEuODA4IDg1LjgwMTQgMTIxLjk1NCA4NS45MjY4IDEyMi4xNDEgODUuOTkxMkMxMjIuMzI3IDg2LjA1NTcgMTIyLjU0NSA4Ni4wODc5IDEyMi43OTYgODYuMDg3OUMxMjIuOTc1IDg2LjA4NzkgMTIzLjE0NyA4Ni4wNzcxIDEyMy4zMTIgODYuMDU1N0MxMjMuNDc2IDg2LjAzNDIgMTIzLjYwOSA4Ni4wMTI3IDEyMy43MDkgODUuOTkxMkwxMjMuNzIgODcuOTY3OEMxMjMuNTA1IDg4LjAzMjIgMTIzLjI1NCA4OC4wODk1IDEyMi45NjggODguMTM5NkMxMjIuNjg4IDg4LjE4OTggMTIyLjM2NiA4OC4yMTQ4IDEyMi4wMDEgODguMjE0OEMxMjEuNDA3IDg4LjIxNDggMTIwLjg4IDg4LjExMSAxMjAuNDIyIDg3LjkwMzNDMTE5Ljk2NCA4Ny42ODg1IDExOS42MDUgODcuMzQxMSAxMTkuMzQ4IDg2Ljg2MTNDMTE5LjA5IDg2LjM4MTUgMTE4Ljk2MSA4NS43NDQxIDExOC45NjEgODQuOTQ5MlY3My41MzAzWk0xMjUuMTE5IDgyLjMxNzRWODIuMDcwM0MxMjUuMTE5IDgxLjIzMjQgMTI1LjI0MSA4MC40NTU0IDEyNS40ODQgNzkuNzM5M0MxMjUuNzI4IDc5LjAxNiAxMjYuMDc5IDc4LjM4OTMgMTI2LjUzNyA3Ny44NTk0QzEyNy4wMDMgNzcuMzIyMyAxMjcuNTY4IDc2LjkwNjkgMTI4LjIzNCA3Ni42MTMzQzEyOC45MDggNzYuMzEyNSAxMjkuNjY3IDc2LjE2MjEgMTMwLjUxMiA3Ni4xNjIxQzEzMS4zNjQgNzYuMTYyMSAxMzIuMTIzIDc2LjMxMjUgMTMyLjc4OSA3Ni42MTMzQzEzMy40NjIgNzYuOTA2OSAxMzQuMDMyIDc3LjMyMjMgMTM0LjQ5NyA3Ny44NTk0QzEzNC45NjMgNzguMzg5MyAxMzUuMzE3IDc5LjAxNiAxMzUuNTYxIDc5LjczOTNDMTM1LjgwNCA4MC40NTU0IDEzNS45MjYgODEuMjMyNCAxMzUuOTI2IDgyLjA3MDNWODIuMzE3NEMxMzUuOTI2IDgzLjE1NTMgMTM1LjgwNCA4My45MzIzIDEzNS41NjEgODQuNjQ4NEMxMzUuMzE3IDg1LjM2NDYgMTM0Ljk2MyA4NS45OTEyIDEzNC40OTcgODYuNTI4M0MxMzQuMDMyIDg3LjA1ODMgMTMzLjQ2NiA4Ny40NzM2IDEzMi44IDg3Ljc3NDRDMTMyLjEzNCA4OC4wNjggMTMxLjM3OCA4OC4yMTQ4IDEzMC41MzMgODguMjE0OEMxMjkuNjgxIDg4LjIxNDggMTI4LjkxOCA4OC4wNjggMTI4LjI0NSA4Ny43NzQ0QzEyNy41NzkgODcuNDczNiAxMjcuMDEzIDg3LjA1ODMgMTI2LjU0OCA4Ni41MjgzQzEyNi4wODIgODUuOTkxMiAxMjUuNzI4IDg1LjM2NDYgMTI1LjQ4NCA4NC42NDg0QzEyNS4yNDEgODMuOTMyMyAxMjUuMTE5IDgzLjE1NTMgMTI1LjExOSA4Mi4zMTc0Wk0xMjcuNzA4IDgyLjA3MDNWODIuMzE3NEMxMjcuNzA4IDgyLjg0MDIgMTI3Ljc2MiA4My4zMzQzIDEyNy44NjkgODMuNzk5OEMxMjcuOTc3IDg0LjI2NTMgMTI4LjE0NSA4NC42NzM1IDEyOC4zNzQgODUuMDI0NEMxMjguNjAzIDg1LjM3NTMgMTI4Ljg5NyA4NS42NTEgMTI5LjI1NSA4NS44NTE2QzEyOS42MTMgODYuMDUyMSAxMzAuMDM5IDg2LjE1MjMgMTMwLjUzMyA4Ni4xNTIzQzEzMS4wMTMgODYuMTUyMyAxMzEuNDI4IDg2LjA1MjEgMTMxLjc3OSA4NS44NTE2QzEzMi4xMzcgODUuNjUxIDEzMi40MzEgODUuMzc1MyAxMzIuNjYgODUuMDI0NEMxMzIuODg5IDg0LjY3MzUgMTMzLjA1OCA4NC4yNjUzIDEzMy4xNjUgODMuNzk5OEMxMzMuMjggODMuMzM0MyAxMzMuMzM3IDgyLjg0MDIgMTMzLjMzNyA4Mi4zMTc0VjgyLjA3MDNDMTMzLjMzNyA4MS41NTQ3IDEzMy4yOCA4MS4wNjc3IDEzMy4xNjUgODAuNjA5NEMxMzMuMDU4IDgwLjE0MzkgMTMyLjg4NiA3OS43MzIxIDEzMi42NDkgNzkuMzc0QzEzMi40MiA3OS4wMTYgMTMyLjEyNyA3OC43MzY3IDEzMS43NjkgNzguNTM2MUMxMzEuNDE4IDc4LjMyODUgMTMwLjk5OSA3OC4yMjQ2IDEzMC41MTIgNzguMjI0NkMxMzAuMDI1IDc4LjIyNDYgMTI5LjYwMiA3OC4zMjg1IDEyOS4yNDQgNzguNTM2MUMxMjguODkzIDc4LjczNjcgMTI4LjYwMyA3OS4wMTYgMTI4LjM3NCA3OS4zNzRDMTI4LjE0NSA3OS43MzIxIDEyNy45NzcgODAuMTQzOSAxMjcuODY5IDgwLjYwOTRDMTI3Ljc2MiA4MS4wNjc3IDEyNy43MDggODEuNTU0NyAxMjcuNzA4IDgyLjA3MDNaTTE0MC45MTMgNzguODU4NFY4OEgxMzguMzI0Vjc2LjM3N0gxNDAuNzYzTDE0MC45MTMgNzguODU4NFpNMTQwLjQ1MSA4MS43NTg4TDEzOS42MTMgODEuNzQ4QzEzOS42MiA4MC45MjQ1IDEzOS43MzUgODAuMTY4OSAxMzkuOTU3IDc5LjQ4MTRDMTQwLjE4NiA3OC43OTM5IDE0MC41MDEgNzguMjAzMSAxNDAuOTAyIDc3LjcwOUMxNDEuMzExIDc3LjIxNDggMTQxLjc5OCA3Ni44MzUzIDE0Mi4zNjMgNzYuNTcwM0MxNDIuOTI5IDc2LjI5ODIgMTQzLjU1OSA3Ni4xNjIxIDE0NC4yNTQgNzYuMTYyMUMxNDQuODEyIDc2LjE2MjEgMTQ1LjMxNyA3Ni4yNDA5IDE0NS43NjkgNzYuMzk4NEMxNDYuMjI3IDc2LjU0ODggMTQ2LjYxNyA3Ni43OTU5IDE0Ni45MzkgNzcuMTM5NkMxNDcuMjY5IDc3LjQ4MzQgMTQ3LjUyIDc3LjkzMSAxNDcuNjkxIDc4LjQ4MjRDMTQ3Ljg2MyA3OS4wMjY3IDE0Ny45NDkgNzkuNjk2MyAxNDcuOTQ5IDgwLjQ5MTJWODhIMTQ1LjM1VjgwLjQ4MDVDMTQ1LjM1IDc5LjkyMTkgMTQ1LjI2NyA3OS40ODE0IDE0NS4xMDMgNzkuMTU5MkMxNDQuOTQ1IDc4LjgyOTggMTQ0LjcxMiA3OC41OTcgMTQ0LjQwNCA3OC40NjA5QzE0NC4xMDQgNzguMzE3NyAxNDMuNzI4IDc4LjI0NjEgMTQzLjI3NiA3OC4yNDYxQzE0Mi44MzIgNzguMjQ2MSAxNDIuNDM1IDc4LjMzOTIgMTQyLjA4NCA3OC41MjU0QzE0MS43MzMgNzguNzExNiAxNDEuNDM2IDc4Ljk2NTggMTQxLjE5MiA3OS4yODgxQzE0MC45NTYgNzkuNjEwNCAxNDAuNzczIDc5Ljk4MjcgMTQwLjY0NSA4MC40MDUzQzE0MC41MTYgODAuODI3OCAxNDAuNDUxIDgxLjI3OSAxNDAuNDUxIDgxLjc1ODhaIiBmaWxsPSIjM0Y1MkREIi8+Cjwvc3ZnPgo=", + "description": "Action button.", + "descriptor": { + "type": "latest", + "sizeX": 3, + "sizeY": 1, + "resources": [], + "templateHtml": "\n", + "templateCss": "#container tb-markdown-widget {\n height: 100%;\n display: block;\n}\n\n#container tb-markdown-widget .tb-markdown-view {\n height: 100%;\n overflow: auto;\n}\n", + "controllerScript": "self.onInit = function() {\n self.ctx.$scope.actionWidget.onInit();\n}\n\nself.actionSources = function() {\n return {\n 'click': {\n name: 'widget-action.click',\n multiple: false\n }\n };\n}\n\nself.typeParameters = function() {\n return {\n dataKeysOptional: true,\n datasourcesOptional: true,\n maxDatasources: 1,\n maxDataKeys: 0,\n singleEntity: true,\n previewWidth: '200px',\n previewHeight: '80px',\n embedTitlePanel: true,\n overflowVisible: true\n };\n}\n\nself.onDestroy = function() {\n}\n\n", + "settingsSchema": "", + "dataKeySettingsSchema": "", + "settingsDirective": "", + "hasBasicMode": true, + "basicModeDirective": "tb-action-button-basic-config", + "defaultConfig": "{\"datasources\":[],\"timewindow\":{\"realtime\":{\"timewindowMs\":60000}},\"showTitle\":false,\"backgroundColor\":\"#FFFFFF01\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"0px\",\"settings\":{},\"title\":\"Action button\",\"showTitleIcon\":false,\"iconColor\":\"rgba(0, 0, 0, 0.87)\",\"iconSize\":\"24px\",\"titleTooltip\":\"\",\"dropShadow\":false,\"enableFullscreen\":false,\"widgetStyle\":{},\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"showLegend\":false,\"useDashboardTimewindow\":true,\"displayTimewindow\":true,\"widgetCss\":\"\",\"pageSize\":1024,\"noDataDisplayMessage\":\"\",\"borderRadius\":\"4px\",\"configMode\":\"basic\"}" + }, + "tags": [ + "button", + "action", + "navigation" + ] +} \ No newline at end of file diff --git a/ui-ngx/src/app/core/api/widget-api.models.ts b/ui-ngx/src/app/core/api/widget-api.models.ts index 548cbc7041..90d74a4c16 100644 --- a/ui-ngx/src/app/core/api/widget-api.models.ts +++ b/ui-ngx/src/app/core/api/widget-api.models.ts @@ -91,6 +91,7 @@ export interface WidgetActionsApi { entityId?: EntityId, entityName?: string, additionalParams?: any, entityLabel?: string) => void; elementClick: ($event: Event) => void; cardClick: ($event: Event) => void; + click: ($event: Event) => void; getActiveEntityInfo: () => SubscriptionEntityInfo; openDashboardStateInSeparateDialog: (targetDashboardStateId: string, params?: StateParams, dialogTitle?: string, hideDashboardToolbar?: boolean, dialogWidth?: number, dialogHeight?: number) => void; diff --git a/ui-ngx/src/app/core/services/utils.service.ts b/ui-ngx/src/app/core/services/utils.service.ts index 440f9c1d3d..70b04ee4eb 100644 --- a/ui-ngx/src/app/core/services/utils.service.ts +++ b/ui-ngx/src/app/core/services/utils.service.ts @@ -17,7 +17,7 @@ // eslint-disable-next-line @typescript-eslint/triple-slash-reference /// -import { Inject, Injectable, NgZone } from '@angular/core'; +import { Inject, Injectable, NgZone, Renderer2 } from '@angular/core'; import { WINDOW } from '@core/services/window.service'; import { ExceptionData } from '@app/shared/models/error.models'; import { @@ -55,8 +55,9 @@ import { TelemetryType } from '@shared/models/telemetry/telemetry.models'; import { EntityId } from '@shared/models/id/entity-id'; -import { DatePipe } from '@angular/common'; +import { DatePipe, DOCUMENT } from '@angular/common'; import { entityTypeTranslations } from '@shared/models/entity-type.models'; +import cssjs from '@core/css/css'; const i18nRegExp = new RegExp(`{${i18nPrefix}:[^{}]+}`, 'g'); @@ -116,6 +117,7 @@ export class UtilsService { defaultAlarmDataKeys: Array = []; constructor(@Inject(WINDOW) private window: Window, + @Inject(DOCUMENT) private document: Document, private zone: NgZone, private datePipe: DatePipe, private translate: TranslateService) { @@ -502,4 +504,24 @@ export class UtilsService { return base64toObj(b64Encoded); } + public applyCssToElement(renderer: Renderer2, element: any, cssClassPrefix: string, css: string): string { + const cssParser = new cssjs(); + cssParser.testMode = false; + const cssClass = `${cssClassPrefix}-${guid()}`; + cssParser.cssPreviewNamespace = cssClass; + cssParser.createStyleElement(cssClass, css); + renderer.addClass(element, cssClass); + return cssClass; + } + + public clearCssElement(renderer: Renderer2, cssClass: string, element?: any): void { + if (element) { + renderer.removeClass(element, cssClass); + } + const el = this.document.getElementById(cssClass); + if (el) { + el.parentNode.removeChild(el); + } + } + } diff --git a/ui-ngx/src/app/modules/common/modules-map.ts b/ui-ngx/src/app/modules/common/modules-map.ts index f8dab27af9..a12829f7c9 100644 --- a/ui-ngx/src/app/modules/common/modules-map.ts +++ b/ui-ngx/src/app/modules/common/modules-map.ts @@ -14,6 +14,8 @@ /// limitations under the License. /// +/* eslint-disable max-len */ + import * as AngularAnimations from '@angular/animations'; import * as AngularCore from '@angular/core'; import * as AngularCommon from '@angular/common'; @@ -226,9 +228,9 @@ import * as DataKeyConfigComponent from '@home/components/widget/config/data-key import * as LegendConfigComponent from '@home/components/widget/lib/settings/common/legend-config.component'; import * as ManageWidgetActionsComponent from '@home/components/widget/action/manage-widget-actions.component'; import * as WidgetActionDialogComponent from '@home/components/widget/action/widget-action-dialog.component'; -import * as CustomActionPrettyResourcesTabsComponent from '@home/components/widget/config/action/custom-action-pretty-resources-tabs.component'; -import * as CustomActionPrettyEditorComponent from '@home/components/widget/config/action/custom-action-pretty-editor.component'; -import * as MobileActionEditorComponent from '@home/components/widget/config/action/mobile-action-editor.component'; +import * as CustomActionPrettyResourcesTabsComponent from '@home/components/widget/lib/settings/common/action/custom-action-pretty-resources-tabs.component'; +import * as CustomActionPrettyEditorComponent from '@home/components/widget/lib/settings/common/action/custom-action-pretty-editor.component'; +import * as MobileActionEditorComponent from '@home/components/widget/lib/settings/common/action/mobile-action-editor.component'; import * as CustomDialogService from '@home/components/widget/dialog/custom-dialog.service'; import * as CustomDialogContainerComponent from '@home/components/widget/dialog/custom-dialog-container.component'; import * as ImportDialogComponent from '@shared/import-export/import-dialog.component'; @@ -261,7 +263,6 @@ import * as FilterPredicateValueComponent from '@home/components/filter/filter-p import * as TenantProfileComponent from '@home/components/profile/tenant-profile.component'; import * as TenantProfileDialogComponent from '@home/components/profile/tenant-profile-dialog.component'; import * as TenantProfileDataComponent from '@home/components/profile/tenant-profile-data.component'; -// eslint-disable-next-line max-len import * as DefaultDeviceProfileConfigurationComponent from '@home/components/profile/device/default-device-profile-configuration.component'; import * as DeviceProfileConfigurationComponent from '@home/components/profile/device/device-profile-configuration.component'; import * as DeviceProfileComponent from '@home/components/profile/device-profile.component'; @@ -286,7 +287,6 @@ import * as AlarmScheduleInfoComponent from '@home/components/profile/alarm/alar import * as AlarmScheduleDialogComponent from '@home/components/profile/alarm/alarm-schedule-dialog.component'; import * as EditAlarmDetailsDialogComponent from '@home/components/profile/alarm/edit-alarm-details-dialog.component'; import * as AlarmRuleConditionDialogComponent from '@home/components/profile/alarm/alarm-rule-condition-dialog.component'; -// eslint-disable-next-line max-len import * as DefaultTenantProfileConfigurationComponent from '@home/components/profile/tenant/default-tenant-profile-configuration.component'; import * as TenantProfileConfigurationComponent from '@home/components/profile/tenant/tenant-profile-configuration.component'; import * as SmsProviderConfigurationComponent from '@home/components/sms/sms-provider-configuration.component'; @@ -541,9 +541,9 @@ class ModulesMap implements IModulesMap { '@home/components/widget/lib/settings/common/legend-config.component': LegendConfigComponent, '@home/components/widget/action/manage-widget-actions.component': ManageWidgetActionsComponent, '@home/components/widget/action/widget-action-dialog.component': WidgetActionDialogComponent, - '@home/components/widget/config/action/custom-action-pretty-resources-tabs.component': CustomActionPrettyResourcesTabsComponent, - '@home/components/widget/config/action/custom-action-pretty-editor.component': CustomActionPrettyEditorComponent, - '@home/components/widget/config/action/mobile-action-editor.component': MobileActionEditorComponent, + '@home/components/widget/lib/settings/common/action/custom-action-pretty-resources-tabs.component': CustomActionPrettyResourcesTabsComponent, + '@home/components/widget/lib/settings/common/action/custom-action-pretty-editor.component': CustomActionPrettyEditorComponent, + '@home/components/widget/lib/settings/common/action/mobile-action-editor.component': MobileActionEditorComponent, '@home/components/widget/dialog/custom-dialog.service': CustomDialogService, '@home/components/widget/dialog/custom-dialog-container.component': CustomDialogContainerComponent, '@home/components/attribute/add-widget-to-dashboard-dialog.component': AddWidgetToDashboardDialogComponent, diff --git a/ui-ngx/src/app/modules/home/components/dashboard/dashboard.component.html b/ui-ngx/src/app/modules/home/components/dashboard/dashboard.component.html index 5ca942f33c..c69a2a4de9 100644 --- a/ui-ngx/src/app/modules/home/components/dashboard/dashboard.component.html +++ b/ui-ngx/src/app/modules/home/components/dashboard/dashboard.component.html @@ -71,6 +71,7 @@ [dashboardStyle]="dashboardStyle" [backgroundImage]="backgroundImage" [isEdit]="isEdit" + [isPreview]="isPreview" [isMobile]="isMobileSize" [isEditActionEnabled]="isEditActionEnabled" [isExportActionEnabled]="isExportActionEnabled" diff --git a/ui-ngx/src/app/modules/home/components/dashboard/dashboard.component.ts b/ui-ngx/src/app/modules/home/components/dashboard/dashboard.component.ts index 469630c212..2d143f4e16 100644 --- a/ui-ngx/src/app/modules/home/components/dashboard/dashboard.component.ts +++ b/ui-ngx/src/app/modules/home/components/dashboard/dashboard.component.ts @@ -97,6 +97,9 @@ export class DashboardComponent extends PageComponent implements IDashboardCompo @Input() isEdit: boolean; + @Input() + isPreview: boolean; + @Input() autofillHeight: boolean; diff --git a/ui-ngx/src/app/modules/home/components/widget/action/widget-action-dialog.component.ts b/ui-ngx/src/app/modules/home/components/widget/action/widget-action-dialog.component.ts index 1eec44b714..b10085c294 100644 --- a/ui-ngx/src/app/modules/home/components/widget/action/widget-action-dialog.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/action/widget-action-dialog.component.ts @@ -38,13 +38,12 @@ import { } from '@home/components/widget/action/manage-widget-actions.component.models'; import { UtilsService } from '@core/services/utils.service'; import { - actionDescriptorToAction, + actionDescriptorToAction, defaultWidgetAction, WidgetActionSource, - WidgetActionType, widgetType } from '@shared/models/widget.models'; import { takeUntil } from 'rxjs/operators'; -import { CustomActionEditorCompleter } from '@home/components/widget/config/action/custom-action.models'; +import { CustomActionEditorCompleter } from '@home/components/widget/lib/settings/common/action/custom-action.models'; import { WidgetService } from '@core/http/widget.service'; export interface WidgetActionDialogData { @@ -92,11 +91,7 @@ export class WidgetActionDialogComponent extends DialogComponent + + + +
+
widgets.action-button.behavior
+
+
widgets.action-button.on-click
+ + +
+
+
widgets.button-state.activated-state
+ +
+
+
widgets.button-state.disabled-state
+ +
+
+
+
widget-config.appearance
+ + +
+
+
widget-config.card-appearance
+
+
{{ 'widget-config.card-border-radius' | translate }}
+ + + +
+
+
diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/button/action-button-basic-config.component.ts b/ui-ngx/src/app/modules/home/components/widget/config/basic/button/action-button-basic-config.component.ts new file mode 100644 index 0000000000..4485966ac7 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/button/action-button-basic-config.component.ts @@ -0,0 +1,139 @@ +/// +/// Copyright © 2016-2024 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 { Component } from '@angular/core'; +import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms'; +import { Store } from '@ngrx/store'; +import { AppState } from '@core/core.state'; +import { BasicWidgetConfigComponent } from '@home/components/widget/config/widget-config.component.models'; +import { WidgetConfigComponentData } from '@home/models/widget-component.models'; +import { + actionDescriptorToAction, + Datasource, + defaultWidgetAction, + TargetDevice, + WidgetAction, + WidgetConfig, +} from '@shared/models/widget.models'; +import { WidgetConfigComponent } from '@home/components/widget/widget-config.component'; +import { guid } from '@core/utils'; +import { ValueType } from '@shared/models/constants'; +import { getTargetDeviceFromDatasources } from '@shared/models/widget-settings.models'; +import { + actionButtonDefaultSettings, + ActionButtonWidgetSettings +} from '@home/components/widget/lib/button/action-button-widget.models'; + +@Component({ + selector: 'tb-action-button-basic-config', + templateUrl: './action-button-basic-config.component.html', + styleUrls: ['../basic-config.scss'] +}) +export class ActionButtonBasicConfigComponent extends BasicWidgetConfigComponent { + + get targetDevice(): TargetDevice { + const datasources: Datasource[] = this.actionButtonWidgetConfigForm.get('datasources').value; + return getTargetDeviceFromDatasources(datasources); + } + + valueType = ValueType; + + actionButtonWidgetConfigForm: UntypedFormGroup; + + constructor(protected store: Store, + protected widgetConfigComponent: WidgetConfigComponent, + private fb: UntypedFormBuilder) { + super(store, widgetConfigComponent); + } + + protected configForm(): UntypedFormGroup { + return this.actionButtonWidgetConfigForm; + } + + protected onConfigSet(configData: WidgetConfigComponentData) { + const settings: ActionButtonWidgetSettings = {...actionButtonDefaultSettings, ...(configData.config.settings || {})}; + const onClickAction = this.getOnClickAction(configData.config); + this.actionButtonWidgetConfigForm = this.fb.group({ + datasources: [configData.config.datasources, []], + + onClickAction: [onClickAction, []], + activatedState: [settings.activatedState, []], + disabledState: [settings.disabledState, []], + + appearance: [settings.appearance, []], + + borderRadius: [configData.config.borderRadius, []] + }); + } + + protected prepareOutputConfig(config: any): WidgetConfigComponentData { + + this.widgetConfig.config.datasources = config.datasources; + this.setOnClickAction(this.widgetConfig.config, config.onClickAction); + + this.widgetConfig.config.settings = this.widgetConfig.config.settings || {}; + + this.widgetConfig.config.settings.activatedState = config.activatedState; + this.widgetConfig.config.settings.disabledState = config.disabledState; + + this.widgetConfig.config.settings.appearance = config.appearance; + + this.widgetConfig.config.borderRadius = config.borderRadius; + + return this.widgetConfig; + } + + private getOnClickAction(config: WidgetConfig): WidgetAction { + let clickAction: WidgetAction; + const actions = config.actions; + if (actions && actions.click) { + const descriptors = actions.click; + if (descriptors?.length) { + const descriptor = descriptors[0]; + clickAction = actionDescriptorToAction(descriptor); + } + } + if (!clickAction) { + clickAction = defaultWidgetAction(); + } + return clickAction; + } + + private setOnClickAction(config: WidgetConfig, clickAction: WidgetAction): void { + let actions = config.actions; + if (!actions) { + actions = {}; + config.actions = actions; + } + let descriptors = actions.click; + if (!descriptors) { + descriptors = []; + actions.click = descriptors; + } + let descriptor = descriptors[0]; + if (!descriptor) { + descriptor = { + id: guid(), + name: 'onClick', + icon: 'more_horiz', + ...clickAction + }; + descriptors[0] = descriptor; + } else { + descriptors[0] = {...descriptor, ...clickAction}; + } + } +} diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/rpc/single-switch-basic-config.component.html b/ui-ngx/src/app/modules/home/components/widget/config/basic/rpc/single-switch-basic-config.component.html index 4f030986f1..4ac5934e93 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/basic/rpc/single-switch-basic-config.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/rpc/single-switch-basic-config.component.html @@ -20,30 +20,36 @@
widgets.single-switch.behavior
-
widgets.value-action.initial-state
+
widgets.rpc-state.initial-state
-
widgets.value-action.turn-on
+
widgets.rpc-state.turn-on
-
widgets.value-action.turn-off
+
widgets.rpc-state.turn-off
diff --git a/ui-ngx/src/app/modules/home/components/widget/config/datasource.component.html b/ui-ngx/src/app/modules/home/components/widget/config/datasource.component.html index 7777c6fdf9..b72f9f0e5d 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/datasource.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/config/datasource.component.html @@ -42,14 +42,14 @@ style="height: 56px; margin-bottom: 22px;" formControlName="alarmFilterConfig"> diff --git a/ui-ngx/src/app/modules/home/components/widget/config/datasource.component.ts b/ui-ngx/src/app/modules/home/components/widget/config/datasource.component.ts index 11a871de08..1dd3aa3507 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/datasource.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/config/datasource.component.ts @@ -95,6 +95,10 @@ export class DatasourceComponent implements ControlValueAccessor, OnInit, Valida return this.widgetConfigComponent.modelValue?.typeParameters?.dataKeysOptional; } + public get datasourcesOptional(): boolean { + return this.widgetConfigComponent.modelValue?.typeParameters?.datasourcesOptional; + } + public get maxDataKeys(): number { return this.widgetConfigComponent.modelValue?.typeParameters?.maxDataKeys; } @@ -276,18 +280,20 @@ export class DatasourceComponent implements ControlValueAccessor, OnInit, Valida } private updateValidators() { - const type: DatasourceType = this.datasourceFormGroup.get('type').value; - this.datasourceFormGroup.get('deviceId').setValidators( - type === DatasourceType.device ? [Validators.required] : [] - ); - this.datasourceFormGroup.get('entityAliasId').setValidators( - (type === DatasourceType.entity || type === DatasourceType.entityCount) ? [Validators.required] : [] - ); - const newDataKeysRequired = !this.isDataKeysOptional(type); - this.datasourceFormGroup.get('dataKeys').setValidators(newDataKeysRequired ? [Validators.required] : []); - this.datasourceFormGroup.get('deviceId').updateValueAndValidity({emitEvent: false}); - this.datasourceFormGroup.get('entityAliasId').updateValueAndValidity({emitEvent: false}); - this.datasourceFormGroup.get('dataKeys').updateValueAndValidity({emitEvent: false}); + if (!this.datasourcesOptional) { + const type: DatasourceType = this.datasourceFormGroup.get('type').value; + this.datasourceFormGroup.get('deviceId').setValidators( + type === DatasourceType.device ? [Validators.required] : [] + ); + this.datasourceFormGroup.get('entityAliasId').setValidators( + (type === DatasourceType.entity || type === DatasourceType.entityCount) ? [Validators.required] : [] + ); + const newDataKeysRequired = !this.isDataKeysOptional(type); + this.datasourceFormGroup.get('dataKeys').setValidators(newDataKeysRequired ? [Validators.required] : []); + this.datasourceFormGroup.get('deviceId').updateValueAndValidity({emitEvent: false}); + this.datasourceFormGroup.get('entityAliasId').updateValueAndValidity({emitEvent: false}); + this.datasourceFormGroup.get('dataKeys').updateValueAndValidity({emitEvent: false}); + } } } diff --git a/ui-ngx/src/app/modules/home/components/widget/config/datasources.component.ts b/ui-ngx/src/app/modules/home/components/widget/config/datasources.component.ts index 4cb274c3ef..a83d58a25e 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/datasources.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/config/datasources.component.ts @@ -30,7 +30,7 @@ import { import { WidgetConfigComponent } from '@home/components/widget/widget-config.component'; import { Datasource, - DatasourceType, + DatasourceType, datasourceValid, JsonSettingsSchema, WidgetConfigMode, widgetType @@ -317,6 +317,9 @@ export class DatasourcesComponent implements ControlValueAccessor, OnInit, Valid } private datasourcesUpdated(datasources: Datasource[]) { + if (this.datasourcesOptional) { + datasources = datasources ? datasources.filter(d => datasourceValid(d)) : []; + } this.propagateChange(datasources); } diff --git a/ui-ngx/src/app/modules/home/components/widget/config/widget-config-components.module.ts b/ui-ngx/src/app/modules/home/components/widget/config/widget-config-components.module.ts index 7b80b4b088..4470fc1327 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/widget-config-components.module.ts +++ b/ui-ngx/src/app/modules/home/components/widget/config/widget-config-components.module.ts @@ -33,11 +33,6 @@ import { WidgetSettingsCommonModule } from '@home/components/widget/lib/settings import { TimewindowStyleComponent } from '@home/components/widget/config/timewindow-style.component'; import { TimewindowStylePanelComponent } from '@home/components/widget/config/timewindow-style-panel.component'; import { TargetDeviceComponent } from '@home/components/widget/config/target-device.component'; -import { WidgetActionComponent } from '@home/components/widget/config/action/widget-action.component'; -import { CustomActionPrettyResourcesTabsComponent } - from '@home/components/widget/config/action/custom-action-pretty-resources-tabs.component'; -import { CustomActionPrettyEditorComponent } from '@home/components/widget/config/action/custom-action-pretty-editor.component'; -import { MobileActionEditorComponent } from '@home/components/widget/config/action/mobile-action-editor.component'; @NgModule({ declarations: @@ -55,11 +50,7 @@ import { MobileActionEditorComponent } from '@home/components/widget/config/acti TimewindowStyleComponent, TimewindowStylePanelComponent, TimewindowConfigPanelComponent, - WidgetSettingsComponent, - WidgetActionComponent, - CustomActionPrettyResourcesTabsComponent, - CustomActionPrettyEditorComponent, - MobileActionEditorComponent + WidgetSettingsComponent ], imports: [ CommonModule, @@ -82,11 +73,7 @@ import { MobileActionEditorComponent } from '@home/components/widget/config/acti TimewindowStylePanelComponent, TimewindowConfigPanelComponent, WidgetSettingsComponent, - WidgetSettingsCommonModule, - WidgetActionComponent, - CustomActionPrettyResourcesTabsComponent, - CustomActionPrettyEditorComponent, - MobileActionEditorComponent + WidgetSettingsCommonModule ] }) export class WidgetConfigComponentsModule { } diff --git a/ui-ngx/src/app/modules/home/components/widget/config/widget-config.component.models.ts b/ui-ngx/src/app/modules/home/components/widget/config/widget-config.component.models.ts index 1132e8bf91..441983a2e3 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/widget-config.component.models.ts +++ b/ui-ngx/src/app/modules/home/components/widget/config/widget-config.component.models.ts @@ -23,7 +23,7 @@ import { PageComponent } from '@shared/components/page.component'; import { Store } from '@ngrx/store'; import { AppState } from '@core/core.state'; import { AbstractControl, UntypedFormGroup } from '@angular/forms'; -import { DataKey, DatasourceType, KeyInfo, WidgetConfigMode } from '@shared/models/widget.models'; +import { DataKey, DatasourceType, KeyInfo, WidgetConfigMode, widgetType } from '@shared/models/widget.models'; import { WidgetConfigComponent } from '@home/components/widget/widget-config.component'; import { DataKeyType } from '@shared/models/telemetry/telemetry.models'; import { isDefinedAndNotNull } from '@core/utils'; @@ -63,6 +63,18 @@ export abstract class BasicWidgetConfigComponent extends PageComponent implement return this.widgetConfigComponent.aliasController; } + get callbacks(): WidgetConfigCallbacks { + return this.widgetConfigComponent.widgetConfigCallbacks; + } + + get widgetType(): widgetType { + return this.widgetConfigComponent.widgetType; + } + + get widgetEditMode(): boolean { + return this.widgetConfigComponent.widgetEditMode; + } + widgetConfigChangedEmitter = new EventEmitter(); widgetConfigChanged = this.widgetConfigChangedEmitter.asObservable(); diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/action/action-widget.scss b/ui-ngx/src/app/modules/home/components/widget/lib/action/action-widget.scss new file mode 100644 index 0000000000..276fa725b8 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/lib/action/action-widget.scss @@ -0,0 +1,46 @@ +/** + * Copyright © 2016-2024 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +.tb-action-widget-error-container { + position: absolute; + bottom: 0; + left: 0; + right: 0; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + z-index: 1; + .tb-action-widget-error-panel { + display: flex; + padding: 4px 4px 4px 12px; + justify-content: center; + align-items: center; + gap: 4px; + border-radius: 4px; + background-color: #fff2f3; + box-shadow: -2px 2px 4px 0px rgba(0,0,0,0.2); + .tb-action-widget-error-text { + font-size: 12px; + font-style: normal; + font-weight: 400; + line-height: 16px; + color: rgba(209, 39, 48, 1); + } + .tb-action-widget-error-clear { + color: rgba(209, 39, 48, 1); + } + } +} diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/button/action-button-widget.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/button/action-button-widget.component.html new file mode 100644 index 0000000000..f667e63356 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/lib/button/action-button-widget.component.html @@ -0,0 +1,35 @@ + +
+
+ +
+ + +
+
+
+ +
+
+
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/button/action-button-widget.component.scss b/ui-ngx/src/app/modules/home/components/widget/lib/button/action-button-widget.component.scss new file mode 100644 index 0000000000..fcdc355ef9 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/lib/button/action-button-widget.component.scss @@ -0,0 +1,28 @@ +/** + * Copyright © 2016-2024 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +.tb-action-button-widget { + width: 100%; + height: 100%; + position: relative; + + > div.tb-action-button-widget-title-panel { + position: absolute; + top: 12px; + left: 12px; + right: 12px; + z-index: 2; + } +} diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/button/action-button-widget.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/button/action-button-widget.component.ts new file mode 100644 index 0000000000..21f50d0e9c --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/lib/button/action-button-widget.component.ts @@ -0,0 +1,100 @@ +/// +/// Copyright © 2016-2024 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 { AfterViewInit, ChangeDetectorRef, Component, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core'; +import { BasicActionWidgetComponent } from '@home/components/widget/lib/action/action-widget.models'; +import { ImagePipe } from '@shared/pipe/image.pipe'; +import { DomSanitizer } from '@angular/platform-browser'; +import { ValueType } from '@shared/models/constants'; +import { + actionButtonDefaultSettings, + ActionButtonWidgetSettings +} from '@home/components/widget/lib/button/action-button-widget.models'; +import { WidgetButtonAppearance } from '@shared/components/button/widget-button.models'; + +@Component({ + selector: 'tb-action-button-widget', + templateUrl: './action-button-widget.component.html', + styleUrls: ['../action/action-widget.scss', './action-button-widget.component.scss'], + encapsulation: ViewEncapsulation.None +}) +export class ActionButtonWidgetComponent extends + BasicActionWidgetComponent implements OnInit, AfterViewInit, OnDestroy { + + settings: ActionButtonWidgetSettings; + + disabled = false; + activated = false; + + appearance: WidgetButtonAppearance; + borderRadius = '4px'; + + constructor(protected imagePipe: ImagePipe, + protected sanitizer: DomSanitizer, + protected cd: ChangeDetectorRef) { + super(cd); + } + + ngOnInit(): void { + super.ngOnInit(); + this.settings = {...actionButtonDefaultSettings, ...this.ctx.settings}; + + this.appearance = this.settings.appearance; + + const activatedStateSettings = + {...this.settings.activatedState, actionLabel: this.ctx.translate.instant('widgets.button-state.activated-state')}; + this.createValueGetter(activatedStateSettings, ValueType.BOOLEAN, { + next: (value) => this.onActivated(value) + }); + + const disabledStateSettings = + {...this.settings.disabledState, actionLabel: this.ctx.translate.instant('widgets.button-state.disabled-state')}; + this.createValueGetter(disabledStateSettings, ValueType.BOOLEAN, { + next: (value) => this.onDisabled(value) + }); + } + + ngAfterViewInit(): void { + super.ngAfterViewInit(); + } + + ngOnDestroy() { + super.ngOnDestroy(); + } + + public onInit() { + super.onInit(); + this.borderRadius = this.ctx.$widgetElement.css('borderRadius'); + this.cd.detectChanges(); + } + + public onClick($event: MouseEvent) { + if (!this.ctx.isEdit && !this.ctx.isPreview) { + this.ctx.actionsApi.click($event); + } + } + + private onActivated(value: boolean): void { + this.activated = !!value; + this.cd.markForCheck(); + } + + private onDisabled(value: boolean): void { + this.disabled = !!value; + this.cd.markForCheck(); + } + +} diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/button/action-button-widget.models.ts b/ui-ngx/src/app/modules/home/components/widget/lib/button/action-button-widget.models.ts new file mode 100644 index 0000000000..f86ef73439 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/lib/button/action-button-widget.models.ts @@ -0,0 +1,67 @@ +/// +/// Copyright © 2016-2024 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 { + WidgetButtonAppearance, + widgetButtonDefaultAppearance +} from '@shared/components/button/widget-button.models'; +import { DataToValueType, GetValueAction, GetValueSettings } from '@shared/models/action-widget-settings.models'; + +export interface ActionButtonWidgetSettings { + appearance: WidgetButtonAppearance; + activatedState: GetValueSettings; + disabledState: GetValueSettings; +} + +export const actionButtonDefaultSettings: ActionButtonWidgetSettings = { + appearance: widgetButtonDefaultAppearance, + activatedState: { + action: GetValueAction.DO_NOTHING, + defaultValue: false, + getAttribute: { + key: 'state', + scope: null, + subscribeForUpdates: false + }, + getTimeSeries: { + key: 'state', + subscribeForUpdates: false + }, + dataToValue: { + type: DataToValueType.NONE, + compareToValue: true, + dataToValueFunction: '/* Should return boolean value */\nreturn data;' + } + }, + disabledState: { + action: GetValueAction.DO_NOTHING, + defaultValue: false, + getAttribute: { + key: 'state', + scope: null, + subscribeForUpdates: false + }, + getTimeSeries: { + key: 'state', + subscribeForUpdates: false + }, + dataToValue: { + type: DataToValueType.NONE, + compareToValue: true, + dataToValueFunction: '/* Should return boolean value */\nreturn data;' + } + } +}; diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/rpc/single-switch-widget.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/rpc/single-switch-widget.component.html index 04ec9f22ab..5f085ff7b5 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/rpc/single-switch-widget.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/rpc/single-switch-widget.component.html @@ -33,10 +33,10 @@
-
-
-
- +
+
+
+
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/rpc/single-switch-widget.component.scss b/ui-ngx/src/app/modules/home/components/widget/lib/rpc/single-switch-widget.component.scss index 884bea0e43..92c8f87f09 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/rpc/single-switch-widget.component.scss +++ b/ui-ngx/src/app/modules/home/components/widget/lib/rpc/single-switch-widget.component.scss @@ -45,36 +45,6 @@ $switchColorDisabled: var(--tb-single-switch-color-disabled, #D5D7E5); left: 0; right: 0; } - .tb-single-switch-error-container { - position: absolute; - bottom: 0; - left: 0; - right: 0; - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - .tb-single-switch-error-panel { - display: flex; - padding: 4px 4px 4px 12px; - justify-content: center; - align-items: center; - gap: 4px; - border-radius: 4px; - background-color: #fff2f3; - box-shadow: -2px 2px 4px 0px rgba(0,0,0,0.2); - .tb-single-switch-error-text { - font-size: 12px; - font-style: normal; - font-weight: 400; - line-height: 16px; - color: rgba(209, 39, 48, 1); - } - .tb-single-switch-error-clear { - color: rgba(209, 39, 48, 1); - } - } - } > div.tb-single-switch-title-panel { position: absolute; top: 12px; diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/rpc/single-switch-widget.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/rpc/single-switch-widget.component.ts index 61d4fb9322..1a7274c5b6 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/rpc/single-switch-widget.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/rpc/single-switch-widget.component.ts @@ -42,9 +42,8 @@ import { Observable } from 'rxjs'; import { ResizeObserver } from '@juggle/resize-observer'; import { ImagePipe } from '@shared/pipe/image.pipe'; import { DomSanitizer } from '@angular/platform-browser'; -import cssjs from '@core/css/css'; -import { hashCode } from '@core/utils'; import { ValueType } from '@shared/models/constants'; +import { UtilsService } from '@core/services/utils.service'; const horizontalLayoutPadding = 48; const verticalLayoutPadding = 36; @@ -52,7 +51,7 @@ const verticalLayoutPadding = 36; @Component({ selector: 'tb-single-switch-widget', templateUrl: './single-switch-widget.component.html', - styleUrls: ['./single-switch-widget.component.scss'], + styleUrls: ['../action/action-widget.scss', './single-switch-widget.component.scss'], encapsulation: ViewEncapsulation.None }) export class SingleSwitchWidgetComponent extends @@ -102,9 +101,12 @@ export class SingleSwitchWidgetComponent extends private onValueSetter: ValueSetter; private offValueSetter: ValueSetter; + private singleSwitchCssClass: string; + constructor(protected imagePipe: ImagePipe, protected sanitizer: DomSanitizer, private renderer: Renderer2, + private utils: UtilsService, protected cd: ChangeDetectorRef, private elementRef: ElementRef) { super(cd); @@ -148,25 +150,21 @@ export class SingleSwitchWidgetComponent extends `--tb-single-switch-color-off: ${this.settings.switchColorOff};\n`+ `--tb-single-switch-color-disabled: ${this.settings.switchColorDisabled};\n`+ `}`; - const cssParser = new cssjs(); - cssParser.testMode = false; - const namespace = 'single-switch-' + hashCode(switchVariablesCss); - cssParser.cssPreviewNamespace = namespace; - cssParser.createStyleElement(namespace, switchVariablesCss); - this.renderer.addClass(this.elementRef.nativeElement, namespace); + this.singleSwitchCssClass = + this.utils.applyCssToElement(this.renderer, this.elementRef.nativeElement, 'tb-single-switch', switchVariablesCss); const getInitialStateSettings = - {...this.settings.initialState, actionLabel: this.ctx.translate.instant('widgets.value-action.initial-state')}; + {...this.settings.initialState, actionLabel: this.ctx.translate.instant('widgets.rpc-state.initial-state')}; this.createValueGetter(getInitialStateSettings, ValueType.BOOLEAN, { next: (value) => this.onValue(value) }); const onUpdateStateSettings = {...this.settings.onUpdateState, - actionLabel: this.ctx.translate.instant('widgets.value-action.turn-on')}; + actionLabel: this.ctx.translate.instant('widgets.rpc-state.turn-on')}; this.onValueSetter = this.createValueSetter(onUpdateStateSettings); const offUpdateStateSettings = {...this.settings.offUpdateState, - actionLabel: this.ctx.translate.instant('widgets.value-action.turn-off')}; + actionLabel: this.ctx.translate.instant('widgets.rpc-state.turn-off')}; this.offValueSetter = this.createValueSetter(offUpdateStateSettings); } @@ -190,6 +188,9 @@ export class SingleSwitchWidgetComponent extends if (this.panelResize$) { this.panelResize$.disconnect(); } + if (this.singleSwitchCssClass) { + this.utils.clearCssElement(this.renderer, this.singleSwitchCssClass); + } super.ngOnDestroy(); } @@ -211,7 +212,6 @@ export class SingleSwitchWidgetComponent extends } private onValue(value: boolean): void { - console.log(`onValue: ${value}`); this.value = !!value; this.cd.markForCheck(); } diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/value-action-settings-button.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/action-settings-button.component.html similarity index 88% rename from ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/value-action-settings-button.component.html rename to ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/action-settings-button.component.html index 1e54dc3270..3290099ff9 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/value-action-settings-button.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/action-settings-button.component.html @@ -16,9 +16,9 @@ --> + +
+
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/widget-action-settings-panel.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/widget-action-settings-panel.component.ts new file mode 100644 index 0000000000..8ed53fd95e --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/widget-action-settings-panel.component.ts @@ -0,0 +1,88 @@ +/// +/// Copyright © 2016-2024 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 { Component, EventEmitter, Input, OnInit, Output, ViewEncapsulation } from '@angular/core'; +import { PageComponent } from '@shared/components/page.component'; +import { TbPopoverComponent } from '@shared/components/popover.component'; +import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms'; +import { Store } from '@ngrx/store'; +import { AppState } from '@core/core.state'; +import { merge } from 'rxjs'; +import { + DataToValueType, + GetValueAction, + getValueActions, + getValueActionTranslations, + GetValueSettings +} from '@shared/models/action-widget-settings.models'; +import { ValueType } from '@shared/models/constants'; +import { TargetDevice, WidgetAction, widgetType } from '@shared/models/widget.models'; +import { AttributeScope, DataKeyType, telemetryTypeTranslationsShort } from '@shared/models/telemetry/telemetry.models'; +import { IAliasController } from '@core/api/widget-api.models'; +import { WidgetService } from '@core/http/widget.service'; +import { WidgetActionCallbacks } from '@home/components/widget/action/manage-widget-actions.component.models'; + +@Component({ + selector: 'tb-widget-action-settings-panel', + templateUrl: './widget-action-settings-panel.component.html', + providers: [], + styleUrls: ['./action-settings-panel.component.scss'], + encapsulation: ViewEncapsulation.None +}) +export class WidgetActionSettingsPanelComponent extends PageComponent implements OnInit { + + @Input() + widgetAction: WidgetAction; + + @Input() + panelTitle: string; + + @Input() + widgetType: widgetType; + + @Input() + callbacks: WidgetActionCallbacks; + + @Input() + popover: TbPopoverComponent; + + @Output() + widgetActionApplied = new EventEmitter(); + + widgetActionFormGroup: UntypedFormGroup; + + constructor(private fb: UntypedFormBuilder, + protected store: Store) { + super(store); + } + + ngOnInit(): void { + this.widgetActionFormGroup = this.fb.group( + { + widgetAction: [this.widgetAction, []] + } + ); + } + + cancel() { + this.popover?.hide(); + } + + applyWidgetAction() { + const widgetAction: WidgetAction = this.widgetActionFormGroup.get('widgetAction').getRawValue(); + this.widgetActionApplied.emit(widgetAction); + } +} diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/widget-action-settings.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/widget-action-settings.component.ts new file mode 100644 index 0000000000..95ec0b1262 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/widget-action-settings.component.ts @@ -0,0 +1,136 @@ +/// +/// Copyright © 2016-2024 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 { + ChangeDetectorRef, + Component, + forwardRef, + HostBinding, + Input, + OnInit, + Renderer2, + ViewContainerRef, + ViewEncapsulation +} from '@angular/core'; +import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; +import { MatButton } from '@angular/material/button'; +import { TbPopoverService } from '@shared/components/popover.service'; +import { TranslateService } from '@ngx-translate/core'; +import { WidgetAction, widgetActionTypeTranslationMap, widgetType } from '@shared/models/widget.models'; +import { WidgetActionCallbacks } from '@home/components/widget/action/manage-widget-actions.component.models'; +import { + WidgetActionSettingsPanelComponent +} from '@home/components/widget/lib/settings/common/action/widget-action-settings-panel.component'; + +@Component({ + selector: 'tb-widget-action-settings', + templateUrl: './action-settings-button.component.html', + styleUrls: ['./action-settings-button.scss'], + providers: [ + { + provide: NG_VALUE_ACCESSOR, + useExisting: forwardRef(() => WidgetActionSettingsComponent), + multi: true + } + ], + encapsulation: ViewEncapsulation.None +}) +export class WidgetActionSettingsComponent implements OnInit, ControlValueAccessor { + + @HostBinding('style.overflow') + overflow = 'hidden'; + + @Input() + panelTitle: string; + + @Input() + widgetType: widgetType; + + @Input() + callbacks: WidgetActionCallbacks; + + @Input() + disabled = false; + + modelValue: WidgetAction; + + displayValue: string; + + private propagateChange = null; + + constructor(private translate: TranslateService, + private popoverService: TbPopoverService, + private renderer: Renderer2, + private viewContainerRef: ViewContainerRef, + private cd: ChangeDetectorRef) {} + + ngOnInit(): void { + } + + registerOnChange(fn: any): void { + this.propagateChange = fn; + } + + registerOnTouched(_fn: any): void { + } + + setDisabledState(isDisabled: boolean): void { + if (this.disabled !== isDisabled) { + this.disabled = isDisabled; + } + } + + writeValue(value: WidgetAction): void { + this.modelValue = value; + this.updateDisplayValue(); + } + + openActionSettingsPopup($event: Event, matButton: MatButton) { + if ($event) { + $event.stopPropagation(); + } + const trigger = matButton._elementRef.nativeElement; + if (this.popoverService.hasPopover(trigger)) { + this.popoverService.hidePopover(trigger); + } else { + const ctx: any = { + widgetAction: this.modelValue, + panelTitle: this.panelTitle, + widgetType: this.widgetType, + callbacks: this.callbacks + }; + const widgetActionSettingsPanelPopover = this.popoverService.displayPopover(trigger, this.renderer, + this.viewContainerRef, WidgetActionSettingsPanelComponent, + ['leftTopOnly', 'leftOnly', 'leftBottomOnly'], true, null, + ctx, + {}, + {}, {}, true); + widgetActionSettingsPanelPopover.tbComponentRef.instance.popover = widgetActionSettingsPanelPopover; + widgetActionSettingsPanelPopover.tbComponentRef.instance.widgetActionApplied.subscribe((widgetAction) => { + widgetActionSettingsPanelPopover.hide(); + this.modelValue = widgetAction; + this.updateDisplayValue(); + this.propagateChange(this.modelValue); + }); + } + } + + private updateDisplayValue() { + this.displayValue = this.translate.instant(widgetActionTypeTranslationMap.get(this.modelValue.type)); + this.cd.markForCheck(); + } + +} diff --git a/ui-ngx/src/app/modules/home/components/widget/config/action/widget-action.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/widget-action.component.html similarity index 100% rename from ui-ngx/src/app/modules/home/components/widget/config/action/widget-action.component.html rename to ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/widget-action.component.html diff --git a/ui-ngx/src/app/modules/home/components/widget/config/action/widget-action.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/widget-action.component.ts similarity index 99% rename from ui-ngx/src/app/modules/home/components/widget/config/action/widget-action.component.ts rename to ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/widget-action.component.ts index ed7690fe28..c93a05fafd 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/action/widget-action.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/widget-action.component.ts @@ -44,7 +44,7 @@ import { PopoverPlacement, PopoverPlacements } from '@shared/components/popover. import { CustomActionEditorCompleter, toCustomAction -} from '@home/components/widget/config/action/custom-action.models'; +} from '@home/components/widget/lib/settings/common/action/custom-action.models'; const stateDisplayTypes = ['normal', 'separateDialog', 'popover'] as const; type stateDisplayTypeTuple = typeof stateDisplayTypes; diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/button/widget-button-appearance.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/button/widget-button-appearance.component.html new file mode 100644 index 0000000000..b4ce9c8ce2 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/button/widget-button-appearance.component.html @@ -0,0 +1,97 @@ + +
+ + + {{ widgetButtonTypeTranslationMap.get(type) | translate }} + + +
+ + {{ 'widgets.button.auto-scale' | translate }} + +
+
+ + {{ 'widgets.button.label' | translate }} + + + + +
+
+ + {{ 'widgets.button.icon' | translate }} + +
+ + + + + + +
+
+
+
{{ 'widgets.button.color-palette' | translate }}
+
+
+
widgets.button.main
+ + +
+ +
+
widgets.button.background
+ + +
+
+
+
+ + + +
widgets.button.custom-styles
+
+
+ +
+
{{ widgetButtonStateTranslationMap.get(state) | translate }}
+ + +
+
+
+
+
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/button/widget-button-appearance.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/button/widget-button-appearance.component.ts new file mode 100644 index 0000000000..d8756e3e31 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/button/widget-button-appearance.component.ts @@ -0,0 +1,141 @@ +/// +/// Copyright © 2016-2024 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 { Component, forwardRef, Input, OnInit, ViewEncapsulation } from '@angular/core'; +import { ControlValueAccessor, NG_VALUE_ACCESSOR, UntypedFormBuilder, UntypedFormGroup } from '@angular/forms'; +import { + WidgetButtonAppearance, + widgetButtonStates, widgetButtonStatesTranslations, + widgetButtonTypeImages, + widgetButtonTypes, + widgetButtonTypeTranslations +} from '@shared/components/button/widget-button.models'; +import { merge } from 'rxjs'; + +@Component({ + selector: 'tb-widget-button-appearance', + templateUrl: './widget-button-appearance.component.html', + styleUrls: [], + providers: [ + { + provide: NG_VALUE_ACCESSOR, + useExisting: forwardRef(() => WidgetButtonAppearanceComponent), + multi: true + } + ], + encapsulation: ViewEncapsulation.None +}) +export class WidgetButtonAppearanceComponent implements OnInit, ControlValueAccessor { + + @Input() + disabled = false; + + @Input() + borderRadius: string; + + widgetButtonTypes = widgetButtonTypes; + + widgetButtonTypeTranslationMap = widgetButtonTypeTranslations; + widgetButtonTypeImageMap = widgetButtonTypeImages; + + widgetButtonStates = widgetButtonStates; + widgetButtonStateTranslationMap = widgetButtonStatesTranslations; + + modelValue: WidgetButtonAppearance; + + appearanceFormGroup: UntypedFormGroup; + + private propagateChange = (_val: any) => {}; + + constructor(private fb: UntypedFormBuilder) {} + + ngOnInit(): void { + this.appearanceFormGroup = this.fb.group({ + type: [null, []], + autoScale: [null, []], + showLabel: [null, []], + label: [null, []], + showIcon: [null, []], + icon: [null, []], + iconSize: [null, []], + iconSizeUnit: [null, []], + mainColor: [null, []], + backgroundColor: [null, []] + }); + const customStyle = this.fb.group({}); + for (const state of widgetButtonStates) { + customStyle.addControl(state, this.fb.control(null, [])); + } + this.appearanceFormGroup.addControl('customStyle', customStyle); + this.appearanceFormGroup.valueChanges.subscribe(() => { + this.updateModel(); + }); + merge(this.appearanceFormGroup.get('showLabel').valueChanges, + this.appearanceFormGroup.get('showIcon').valueChanges) + .subscribe(() => { + this.updateValidators(); + }); + } + + registerOnChange(fn: any): void { + this.propagateChange = fn; + } + + registerOnTouched(fn: any): void { + } + + setDisabledState(isDisabled: boolean): void { + this.disabled = isDisabled; + if (this.disabled) { + this.appearanceFormGroup.disable({emitEvent: false}); + } else { + this.appearanceFormGroup.enable({emitEvent: false}); + this.updateValidators(); + } + } + + writeValue(value: WidgetButtonAppearance): void { + this.modelValue = value; + this.appearanceFormGroup.patchValue( + value, {emitEvent: false} + ); + this.updateValidators(); + } + + private updateModel() { + this.modelValue = this.appearanceFormGroup.getRawValue(); + this.propagateChange(this.modelValue); + } + + private updateValidators(): void { + const showLabel: boolean = this.appearanceFormGroup.get('showLabel').value; + const showIcon: boolean = this.appearanceFormGroup.get('showIcon').value; + if (showLabel) { + this.appearanceFormGroup.get('label').enable(); + } else { + this.appearanceFormGroup.get('label').disable(); + } + if (showIcon) { + this.appearanceFormGroup.get('icon').enable(); + this.appearanceFormGroup.get('iconSize').enable(); + this.appearanceFormGroup.get('iconSizeUnit').enable(); + } else { + this.appearanceFormGroup.get('icon').disable(); + this.appearanceFormGroup.get('iconSize').disable(); + this.appearanceFormGroup.get('iconSizeUnit').disable(); + } + } +} diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/button/widget-button-custom-style-panel.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/button/widget-button-custom-style-panel.component.html new file mode 100644 index 0000000000..7e4a316eef --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/button/widget-button-custom-style-panel.component.html @@ -0,0 +1,93 @@ + +
+
{{ widgetButtonStateTranslationMap.get(state) | translate }}
+
+
+ + {{ 'widgets.button.main' | translate }} + + + +
+
+ + {{ 'widgets.button.background' | translate }} + + + +
+
+ + {{ 'widgets.button.shadow' | translate }} + + + {{ 'widgets.button.enabled' | translate }} + {{ 'widgets.button.disabled' | translate }} + +
+
+
+ widgets.button.preview +
+ + +
+
+
+ + + +
+ +
+
+
+ + + +
+
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/button/widget-button-custom-style-panel.component.scss b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/button/widget-button-custom-style-panel.component.scss new file mode 100644 index 0000000000..dfbbb91620 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/button/widget-button-custom-style-panel.component.scss @@ -0,0 +1,68 @@ +/** + * Copyright © 2016-2024 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 '../../../../../../../../../scss/constants'; + +.tb-widget-button-custom-style-panel { + width: 530px; + display: flex; + flex-direction: column; + gap: 16px; + @media #{$mat-lt-md} { + width: 90vw; + } + .tb-widget-button-custom-style-panel-content { + display: flex; + flex-direction: column; + gap: 16px; + overflow: auto; + } + .tb-widget-button-custom-style-title { + font-size: 16px; + font-weight: 500; + line-height: 24px; + letter-spacing: 0.25px; + color: rgba(0, 0, 0, 0.87); + } + .tb-widget-button-custom-style-preview { + flex: 1; + background: rgba(0, 0, 0, 0.04); + display: flex; + flex-direction: column; + padding: 12px 16px 24px 16px; + align-items: center; + gap: 12px; + .tb-widget-button-custom-style-preview-title { + align-self: stretch; + font-size: 16px; + font-style: normal; + font-weight: 500; + line-height: 24px; + color: rgba(0, 0, 0, 0.38); + } + tb-widget-button { + width: 200px; + height: 60px; + } + } + .tb-widget-button-custom-style-panel-buttons { + height: 40px; + display: flex; + flex-direction: row; + gap: 16px; + justify-content: flex-end; + align-items: flex-end; + } +} diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/button/widget-button-custom-style-panel.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/button/widget-button-custom-style-panel.component.ts new file mode 100644 index 0000000000..419ce7e4d4 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/button/widget-button-custom-style-panel.component.ts @@ -0,0 +1,171 @@ +/// +/// Copyright © 2016-2024 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 { ChangeDetectorRef, Component, EventEmitter, Input, OnInit, Output, ViewEncapsulation } from '@angular/core'; +import { PageComponent } from '@shared/components/page.component'; +import { TbPopoverComponent } from '@shared/components/popover.component'; +import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms'; +import { Store } from '@ngrx/store'; +import { AppState } from '@core/core.state'; +import { + defaultBackgroundColorDisabled, + defaultMainColorDisabled, + WidgetButtonAppearance, + WidgetButtonCustomStyle, + WidgetButtonState, + widgetButtonStates, + widgetButtonStatesTranslations, + WidgetButtonType +} from '@shared/components/button/widget-button.models'; +import { merge } from 'rxjs'; +import { deepClone } from '@core/utils'; + +@Component({ + selector: 'tb-widget-button-custom-style-panel', + templateUrl: './widget-button-custom-style-panel.component.html', + providers: [], + styleUrls: ['./widget-button-custom-style-panel.component.scss'], + encapsulation: ViewEncapsulation.None +}) +export class WidgetButtonCustomStylePanelComponent extends PageComponent implements OnInit { + + @Input() + appearance: WidgetButtonAppearance; + + @Input() + borderRadius: string; + + @Input() + state: WidgetButtonState; + + @Input() + customStyle: WidgetButtonCustomStyle; + + @Input() + popover: TbPopoverComponent; + + @Output() + customStyleApplied = new EventEmitter(); + + widgetButtonStateTranslationMap = widgetButtonStatesTranslations; + + widgetButtonState = WidgetButtonState; + + previewAppearance: WidgetButtonAppearance; + + copyFromStates: WidgetButtonState[]; + + customStyleFormGroup: UntypedFormGroup; + + constructor(private fb: UntypedFormBuilder, + protected store: Store, + private cd: ChangeDetectorRef) { + super(store); + } + + ngOnInit(): void { + this.copyFromStates = widgetButtonStates.filter(state => + state !== this.state && !!this.appearance.customStyle[state]); + this.customStyleFormGroup = this.fb.group( + { + overrideMainColor: [false, []], + mainColor: [null, []], + overrideBackgroundColor: [false, []], + backgroundColor: [null, []], + overrideDropShadow: [false, []], + dropShadow: [false, []] + } + ); + merge(this.customStyleFormGroup.get('overrideMainColor').valueChanges, + this.customStyleFormGroup.get('overrideBackgroundColor').valueChanges, + this.customStyleFormGroup.get('overrideDropShadow').valueChanges) + .subscribe(() => { + this.updateValidators(); + }); + this.customStyleFormGroup.valueChanges.subscribe(() => { + this.updatePreviewAppearance(); + }); + this.setStyle(this.customStyle); + } + + copyStyle(state: WidgetButtonState) { + this.customStyle = deepClone(this.appearance.customStyle[state]); + this.setStyle(this.customStyle); + this.customStyleFormGroup.markAsDirty(); + } + + cancel() { + this.popover?.hide(); + } + + applyCustomStyle() { + const customStyle: WidgetButtonCustomStyle = this.customStyleFormGroup.value; + this.customStyleApplied.emit(customStyle); + } + + private setStyle(customStyle?: WidgetButtonCustomStyle): void { + let mainColor = this.state === WidgetButtonState.disabled ? defaultMainColorDisabled : this.appearance.mainColor; + if (customStyle?.overrideMainColor) { + mainColor = customStyle?.mainColor; + } + let backgroundColor = this.state === WidgetButtonState.disabled ? defaultBackgroundColorDisabled : this.appearance.backgroundColor; + if (customStyle?.overrideBackgroundColor) { + backgroundColor = customStyle?.backgroundColor; + } + let dropShadow = this.appearance.type === WidgetButtonType.basic ? false : true; + if (customStyle?.overrideDropShadow) { + dropShadow = customStyle?.dropShadow; + } + this.customStyleFormGroup.patchValue({ + overrideMainColor: customStyle?.overrideMainColor, + mainColor, + overrideBackgroundColor: customStyle?.overrideBackgroundColor, + backgroundColor, + overrideDropShadow: customStyle?.overrideDropShadow, + dropShadow + }, {emitEvent: false}); + this.updateValidators(); + this.updatePreviewAppearance(); + } + + private updateValidators() { + const overrideMainColor: boolean = this.customStyleFormGroup.get('overrideMainColor').value; + const overrideBackgroundColor: boolean = this.customStyleFormGroup.get('overrideBackgroundColor').value; + const overrideDropShadow: boolean = this.customStyleFormGroup.get('overrideDropShadow').value; + + if (overrideMainColor) { + this.customStyleFormGroup.get('mainColor').enable({emitEvent: false}); + } else { + this.customStyleFormGroup.get('mainColor').disable({emitEvent: false}); + } + if (overrideBackgroundColor) { + this.customStyleFormGroup.get('backgroundColor').enable({emitEvent: false}); + } else { + this.customStyleFormGroup.get('backgroundColor').disable({emitEvent: false}); + } + if (overrideDropShadow) { + this.customStyleFormGroup.get('dropShadow').enable({emitEvent: false}); + } else { + this.customStyleFormGroup.get('dropShadow').disable({emitEvent: false}); + } + } + + private updatePreviewAppearance() { + this.previewAppearance = {...this.appearance}; + this.previewAppearance.customStyle[this.state] = this.customStyleFormGroup.value; + this.cd.markForCheck(); + } +} diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/button/widget-button-custom-style.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/button/widget-button-custom-style.component.html new file mode 100644 index 0000000000..3b78af6d5d --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/button/widget-button-custom-style.component.html @@ -0,0 +1,44 @@ + +
+
+ + + +
+ +
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/button/widget-button-custom-style.component.scss b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/button/widget-button-custom-style.component.scss new file mode 100644 index 0000000000..d7cdeffec5 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/button/widget-button-custom-style.component.scss @@ -0,0 +1,46 @@ +/** + * Copyright © 2016-2024 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 '../../../../../../../../../scss/constants'; + +.tb-widget-button-custom-style { + display: flex; + flex-direction: row; + align-items: center; + gap: 12px; + button.mat-mdc-icon-button { + color: rgba(0,0,0,0.56); + } + .tb-widget-button-preview-panel { + width: 148px; + height: 48px; + padding: 8px 12px; + border-radius: 4px; + display: flex; + flex-direction: row; + align-items: center; + justify-content: space-between; + tb-widget-button { + width: 84px; + height: 100%; + } + @media #{$mat-gt-xs} { + width: 168px; + tb-widget-button { + width: 104px; + } + } + } +} diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/button/widget-button-custom-style.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/button/widget-button-custom-style.component.ts new file mode 100644 index 0000000000..b9a1605b19 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/button/widget-button-custom-style.component.ts @@ -0,0 +1,157 @@ +/// +/// Copyright © 2016-2024 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 { + ChangeDetectorRef, + Component, + forwardRef, + Input, + OnChanges, + OnInit, + Renderer2, + SimpleChanges, + ViewContainerRef, + ViewEncapsulation +} from '@angular/core'; +import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; +import { + WidgetButtonAppearance, + WidgetButtonCustomStyle, + WidgetButtonState +} from '@shared/components/button/widget-button.models'; +import { TbPopoverService } from '@shared/components/popover.service'; +import { MatIconButton } from '@angular/material/button'; +import { + WidgetButtonCustomStylePanelComponent +} from '@home/components/widget/lib/settings/common/button/widget-button-custom-style-panel.component'; + +@Component({ + selector: 'tb-widget-button-custom-style', + templateUrl: './widget-button-custom-style.component.html', + styleUrls: ['./widget-button-custom-style.component.scss'], + providers: [ + { + provide: NG_VALUE_ACCESSOR, + useExisting: forwardRef(() => WidgetButtonCustomStyleComponent), + multi: true + } + ], + encapsulation: ViewEncapsulation.None +}) +export class WidgetButtonCustomStyleComponent implements OnInit, OnChanges, ControlValueAccessor { + + @Input() + disabled = false; + + @Input() + appearance: WidgetButtonAppearance; + + @Input() + borderRadius: string; + + @Input() + state: WidgetButtonState; + + widgetButtonState = WidgetButtonState; + + modelValue: WidgetButtonCustomStyle; + + previewAppearance: WidgetButtonAppearance; + + private propagateChange = (_val: any) => {}; + + constructor(private popoverService: TbPopoverService, + private renderer: Renderer2, + private viewContainerRef: ViewContainerRef, + private cd: ChangeDetectorRef) {} + + ngOnInit(): void { + this.updatePreviewAppearance(); + } + + ngOnChanges(changes: SimpleChanges): void { + for (const propName of Object.keys(changes)) { + const change = changes[propName]; + if (!change.firstChange) { + if (propName === 'appearance') { + this.updatePreviewAppearance(); + } + } + } + } + + registerOnChange(fn: any): void { + this.propagateChange = fn; + } + + registerOnTouched(fn: any): void { + } + + setDisabledState(_isDisabled: boolean): void { + } + + writeValue(value: WidgetButtonCustomStyle): void { + this.modelValue = value; + this.updatePreviewAppearance(); + } + + clearStyle() { + this.updateModel(null); + } + + openButtonCustomStylePopup($event: Event, matButton: MatIconButton) { + if ($event) { + $event.stopPropagation(); + } + const trigger = matButton._elementRef.nativeElement; + if (this.popoverService.hasPopover(trigger)) { + this.popoverService.hidePopover(trigger); + } else { + const ctx: any = { + appearance: this.appearance, + borderRadius: this.borderRadius, + state: this.state, + customStyle: this.modelValue + }; + const widgetButtonCustomStylePanelPopover = this.popoverService.displayPopover(trigger, this.renderer, + this.viewContainerRef, WidgetButtonCustomStylePanelComponent, + ['leftTopOnly', 'leftOnly', 'leftBottomOnly'], true, null, + ctx, + {}, + {}, {}, true); + widgetButtonCustomStylePanelPopover.tbComponentRef.instance.popover = widgetButtonCustomStylePanelPopover; + widgetButtonCustomStylePanelPopover.tbComponentRef.instance.customStyleApplied.subscribe((customStyle) => { + widgetButtonCustomStylePanelPopover.hide(); + this.updateModel(customStyle); + }); + } + } + + private updateModel(value: WidgetButtonCustomStyle): void { + this.modelValue = value; + this.updatePreviewAppearance(); + this.propagateChange(this.modelValue); + } + + private updatePreviewAppearance() { + this.previewAppearance = {...this.appearance}; + if (this.modelValue) { + this.previewAppearance.customStyle[this.state] = this.modelValue; + } + this.cd.markForCheck(); + } + +} diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/widget-settings-common.module.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/widget-settings-common.module.ts index a0405d3254..e39c079f75 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/widget-settings-common.module.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/widget-settings-common.module.ts @@ -67,6 +67,31 @@ import { SetValueActionSettingsPanelComponent } from '@home/components/widget/lib/settings/common/action/set-value-action-settings-panel.component'; import { CssSizeInputComponent } from '@home/components/widget/lib/settings/common/css-size-input.component'; +import { WidgetActionComponent } from '@home/components/widget/lib/settings/common/action/widget-action.component'; +import { + CustomActionPrettyResourcesTabsComponent +} from '@home/components/widget/lib/settings/common/action/custom-action-pretty-resources-tabs.component'; +import { + CustomActionPrettyEditorComponent +} from '@home/components/widget/lib/settings/common/action/custom-action-pretty-editor.component'; +import { + MobileActionEditorComponent +} from '@home/components/widget/lib/settings/common/action/mobile-action-editor.component'; +import { + WidgetActionSettingsComponent +} from '@home/components/widget/lib/settings/common/action/widget-action-settings.component'; +import { + WidgetActionSettingsPanelComponent +} from '@home/components/widget/lib/settings/common/action/widget-action-settings-panel.component'; +import { + WidgetButtonAppearanceComponent +} from '@home/components/widget/lib/settings/common/button/widget-button-appearance.component'; +import { + WidgetButtonCustomStyleComponent +} from '@home/components/widget/lib/settings/common/button/widget-button-custom-style.component'; +import { + WidgetButtonCustomStylePanelComponent +} from '@home/components/widget/lib/settings/common/button/widget-button-custom-style-panel.component'; @NgModule({ declarations: [ @@ -93,7 +118,16 @@ import { CssSizeInputComponent } from '@home/components/widget/lib/settings/comm GetValueActionSettingsPanelComponent, DeviceKeyAutocompleteComponent, SetValueActionSettingsComponent, - SetValueActionSettingsPanelComponent + SetValueActionSettingsPanelComponent, + WidgetActionComponent, + CustomActionPrettyResourcesTabsComponent, + CustomActionPrettyEditorComponent, + MobileActionEditorComponent, + WidgetActionSettingsComponent, + WidgetActionSettingsPanelComponent, + WidgetButtonAppearanceComponent, + WidgetButtonCustomStyleComponent, + WidgetButtonCustomStylePanelComponent ], imports: [ CommonModule, @@ -124,7 +158,16 @@ import { CssSizeInputComponent } from '@home/components/widget/lib/settings/comm GetValueActionSettingsPanelComponent, DeviceKeyAutocompleteComponent, SetValueActionSettingsComponent, - SetValueActionSettingsPanelComponent + SetValueActionSettingsPanelComponent, + WidgetActionComponent, + CustomActionPrettyResourcesTabsComponent, + CustomActionPrettyEditorComponent, + MobileActionEditorComponent, + WidgetActionSettingsComponent, + WidgetActionSettingsPanelComponent, + WidgetButtonAppearanceComponent, + WidgetButtonCustomStyleComponent, + WidgetButtonCustomStylePanelComponent ], providers: [ ColorSettingsComponentService, diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/single-switch-widget-settings.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/single-switch-widget-settings.component.html index 4cdb0be38e..9bdca64bbd 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/single-switch-widget-settings.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/single-switch-widget-settings.component.html @@ -19,30 +19,36 @@
widgets.single-switch.behavior
-
widgets.value-action.initial-state
+
widgets.rpc-state.initial-state
-
widgets.value-action.turn-on
+
widgets.rpc-state.turn-on
-
widgets.value-action.turn-off
+
widgets.rpc-state.turn-off
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/single-switch-widget-settings.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/single-switch-widget-settings.component.ts index 7e4f1d1d96..f4bd08a20c 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/single-switch-widget-settings.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/single-switch-widget-settings.component.ts @@ -15,7 +15,7 @@ /// import { Component } from '@angular/core'; -import { TargetDevice, WidgetSettings, WidgetSettingsComponent } from '@shared/models/widget.models'; +import { TargetDevice, WidgetSettings, WidgetSettingsComponent, widgetType } from '@shared/models/widget.models'; import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms'; import { Store } from '@ngrx/store'; import { AppState } from '@core/core.state'; @@ -37,6 +37,10 @@ export class SingleSwitchWidgetSettingsComponent extends WidgetSettingsComponent return this.widget?.config?.targetDevice; } + get widgetType(): widgetType { + return this.widget?.type; + } + singleSwitchLayouts = singleSwitchLayouts; singleSwitchLayoutTranslationMap = singleSwitchLayoutTranslations; diff --git a/ui-ngx/src/app/modules/home/components/widget/widget-component.service.ts b/ui-ngx/src/app/modules/home/components/widget/widget-component.service.ts index 377ab8b6ea..6037a4ea43 100644 --- a/ui-ngx/src/app/modules/home/components/widget/widget-component.service.ts +++ b/ui-ngx/src/app/modules/home/components/widget/widget-component.service.ts @@ -565,6 +565,9 @@ export class WidgetComponentService { if (isUndefined(result.typeParameters.embedTitlePanel)) { result.typeParameters.embedTitlePanel = false; } + if (isUndefined(result.typeParameters.overflowVisible)) { + result.typeParameters.overflowVisible = false; + } if (isUndefined(result.typeParameters.hideDataSettings)) { result.typeParameters.hideDataSettings = false; } diff --git a/ui-ngx/src/app/modules/home/components/widget/widget-components.module.ts b/ui-ngx/src/app/modules/home/components/widget/widget-components.module.ts index 82a4856f4a..11bf6871f8 100644 --- a/ui-ngx/src/app/modules/home/components/widget/widget-components.module.ts +++ b/ui-ngx/src/app/modules/home/components/widget/widget-components.module.ts @@ -71,6 +71,7 @@ import { BarChartWithLabelsWidgetComponent } from '@home/components/widget/lib/chart/bar-chart-with-labels-widget.component'; import { SingleSwitchWidgetComponent } from '@home/components/widget/lib/rpc/single-switch-widget.component'; +import { ActionButtonWidgetComponent } from '@home/components/widget/lib/button/action-button-widget.component'; @NgModule({ declarations: @@ -114,7 +115,8 @@ import { SingleSwitchWidgetComponent } from '@home/components/widget/lib/rpc/sin DoughnutWidgetComponent, RangeChartWidgetComponent, BarChartWithLabelsWidgetComponent, - SingleSwitchWidgetComponent + SingleSwitchWidgetComponent, + ActionButtonWidgetComponent ], imports: [ CommonModule, @@ -162,7 +164,8 @@ import { SingleSwitchWidgetComponent } from '@home/components/widget/lib/rpc/sin DoughnutWidgetComponent, RangeChartWidgetComponent, BarChartWithLabelsWidgetComponent, - SingleSwitchWidgetComponent + SingleSwitchWidgetComponent, + ActionButtonWidgetComponent ], providers: [ {provide: WIDGET_COMPONENTS_MODULE_TOKEN, useValue: WidgetComponentsModule } diff --git a/ui-ngx/src/app/modules/home/components/widget/widget-container.component.html b/ui-ngx/src/app/modules/home/components/widget/widget-container.component.html index 4f428dd983..7235b300bc 100644 --- a/ui-ngx/src/app/modules/home/components/widget/widget-container.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/widget-container.component.html @@ -24,6 +24,7 @@ 'tb-highlighted': isHighlighted(widget), 'tb-not-highlighted': isNotHighlighted(widget), 'mat-elevation-z4': widget.dropShadow, + 'tb-overflow-visible': widgetComponent.widgetContext?.overflowVisible, 'tb-has-timewindow': widget.hasTimewindow, 'tb-edit': isEdit }" @@ -88,6 +89,7 @@ diff --git a/ui-ngx/src/app/modules/home/components/widget/widget-container.component.scss b/ui-ngx/src/app/modules/home/components/widget/widget-container.component.scss index 124b6c4d99..3143ab1ee2 100644 --- a/ui-ngx/src/app/modules/home/components/widget/widget-container.component.scss +++ b/ui-ngx/src/app/modules/home/components/widget/widget-container.component.scss @@ -26,6 +26,13 @@ outline: none; transition: all .2s ease-in-out; + + &.tb-overflow-visible { + overflow: visible; + .tb-widget { + overflow: visible; + } + } } div.tb-widget { diff --git a/ui-ngx/src/app/modules/home/components/widget/widget-container.component.ts b/ui-ngx/src/app/modules/home/components/widget/widget-container.component.ts index f4b54a395d..81c206391a 100644 --- a/ui-ngx/src/app/modules/home/components/widget/widget-container.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/widget-container.component.ts @@ -22,7 +22,6 @@ import { ElementRef, EventEmitter, HostBinding, - Inject, Input, OnDestroy, OnInit, @@ -36,10 +35,9 @@ import { DashboardWidget, DashboardWidgets } from '@home/models/dashboard-compon import { Store } from '@ngrx/store'; import { AppState } from '@core/core.state'; import { SafeStyle } from '@angular/platform-browser'; -import { guid, isNotEmptyStr } from '@core/utils'; -import cssjs from '@core/css/css'; -import { DOCUMENT } from '@angular/common'; +import { isNotEmptyStr } from '@core/utils'; import { GridsterItemComponent } from 'angular-gridster2'; +import { UtilsService } from '@core/services/utils.service'; export enum WidgetComponentActionType { MOUSE_DOWN, @@ -86,6 +84,9 @@ export class WidgetContainerComponent extends PageComponent implements OnInit, A @Input() isEdit: boolean; + @Input() + isPreview: boolean; + @Input() isMobile: boolean; @@ -115,7 +116,7 @@ export class WidgetContainerComponent extends PageComponent implements OnInit, A constructor(protected store: Store, private cd: ChangeDetectorRef, private renderer: Renderer2, - @Inject(DOCUMENT) private document: Document) { + private utils: UtilsService) { super(store); } @@ -123,12 +124,8 @@ export class WidgetContainerComponent extends PageComponent implements OnInit, A this.widget.widgetContext.containerChangeDetector = this.cd; const cssString = this.widget.widget.config.widgetCss; if (isNotEmptyStr(cssString)) { - const cssParser = new cssjs(); - cssParser.testMode = false; - this.cssClass = 'tb-widget-css-' + guid(); - this.renderer.addClass(this.gridsterItem.el, this.cssClass); - cssParser.cssPreviewNamespace = this.cssClass; - cssParser.createStyleElement(this.cssClass, cssString); + this.cssClass = + this.utils.applyCssToElement(this.renderer, this.gridsterItem.el, 'tb-widget-css', cssString); } } @@ -138,10 +135,7 @@ export class WidgetContainerComponent extends PageComponent implements OnInit, A ngOnDestroy(): void { if (this.cssClass) { - const el = this.document.getElementById(this.cssClass); - if (el) { - el.parentNode.removeChild(el); - } + this.utils.clearCssElement(this.renderer, this.cssClass); } } diff --git a/ui-ngx/src/app/modules/home/components/widget/widget-preview.component.html b/ui-ngx/src/app/modules/home/components/widget/widget-preview.component.html index 38c4527074..3a9ced83de 100644 --- a/ui-ngx/src/app/modules/home/components/widget/widget-preview.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/widget-preview.component.html @@ -25,6 +25,7 @@ [autofillHeight]="true" [columns]="24" [isEdit]="false" + [isPreview]="true" [isMobileDisabled]="true" [isEditActionEnabled]="false" [isRemoveActionEnabled]="false"> diff --git a/ui-ngx/src/app/modules/home/components/widget/widget.component.ts b/ui-ngx/src/app/modules/home/components/widget/widget.component.ts index 1c029b6524..15e982c060 100644 --- a/ui-ngx/src/app/modules/home/components/widget/widget.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/widget.component.ts @@ -131,6 +131,9 @@ export class WidgetComponent extends PageComponent implements OnInit, AfterViewI @Input() isEdit: boolean; + @Input() + isPreview: boolean; + @Input() isMobile: boolean; @@ -231,6 +234,7 @@ export class WidgetComponent extends PageComponent implements OnInit, AfterViewI this.widgetContext.store = this.store; this.widgetContext.servicesMap = ServicesMap; this.widgetContext.isEdit = this.isEdit; + this.widgetContext.isPreview = this.isPreview; this.widgetContext.isMobile = this.isMobile; this.widgetContext.toastTargetId = this.toastTargetId; @@ -252,6 +256,7 @@ export class WidgetComponent extends PageComponent implements OnInit, AfterViewI handleWidgetAction: this.handleWidgetAction.bind(this), elementClick: this.elementClick.bind(this), cardClick: this.cardClick.bind(this), + click: this.click.bind(this), getActiveEntityInfo: this.getActiveEntityInfo.bind(this), openDashboardStateInSeparateDialog: this.openDashboardStateInSeparateDialog.bind(this), openDashboardStateInPopover: this.openDashboardStateInPopover.bind(this) @@ -411,6 +416,7 @@ export class WidgetComponent extends PageComponent implements OnInit, AfterViewI this.widgetType = this.widgetInfo.widgetTypeFunction; this.typeParameters = this.widgetInfo.typeParameters; this.widgetContext.embedTitlePanel = this.typeParameters.embedTitlePanel; + this.widgetContext.overflowVisible = this.typeParameters.overflowVisible; if (!this.widgetType) { this.widgetTypeInstance = {}; @@ -1423,7 +1429,15 @@ export class WidgetComponent extends PageComponent implements OnInit, AfterViewI } private cardClick($event: Event) { - const descriptors = this.getActionDescriptors('cardClick'); + this.onClick($event, 'cardClick'); + } + + private click($event: Event) { + this.onClick($event, 'click'); + } + + private onClick($event: Event, sourceId: string) { + const descriptors = this.getActionDescriptors(sourceId); if (descriptors.length) { $event.stopPropagation(); const descriptor = descriptors[0]; diff --git a/ui-ngx/src/app/modules/home/models/widget-component.models.ts b/ui-ngx/src/app/modules/home/models/widget-component.models.ts index 4a7fc32502..a834120dc6 100644 --- a/ui-ngx/src/app/modules/home/models/widget-component.models.ts +++ b/ui-ngx/src/app/modules/home/models/widget-component.models.ts @@ -263,6 +263,7 @@ export class WidgetContext { height: number; $scope: IDynamicWidgetComponent; isEdit: boolean; + isPreview: boolean; isMobile: boolean; toastTargetId: string; @@ -279,6 +280,7 @@ export class WidgetContext { timeWindow?: WidgetTimewindow; embedTitlePanel?: boolean; + overflowVisible?: boolean; hideTitlePanel = false; diff --git a/ui-ngx/src/app/shared/components/button/widget-button.component.html b/ui-ngx/src/app/shared/components/button/widget-button.component.html new file mode 100644 index 0000000000..9b239db068 --- /dev/null +++ b/ui-ngx/src/app/shared/components/button/widget-button.component.html @@ -0,0 +1,39 @@ + + diff --git a/ui-ngx/src/app/shared/components/button/widget-button.component.scss b/ui-ngx/src/app/shared/components/button/widget-button.component.scss new file mode 100644 index 0000000000..06c875de7f --- /dev/null +++ b/ui-ngx/src/app/shared/components/button/widget-button.component.scss @@ -0,0 +1,189 @@ +/** + * Copyright © 2016-2024 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. + */ +$defaultMainColor: #3F52DD; +$defaultBackgroundColor: #FFFFFF; +$defaultBoxShadowColor: rgba(0, 0, 0, 0.08); +$defaultDisabledBoxShadowColor: rgba(0, 0, 0, 0); + +$defaultMainColorDisabled: rgba(0, 0, 0, 0.38); +$defaultBackgroundColorDisabled: rgba(0, 0, 0, 0.03); + +$mainColorEnabled: var(--tb-widget-button-main-color-enabled, $defaultMainColor); +$backgroundColorEnabled: var(--tb-widget-button-background-color-enabled, $defaultBackgroundColor); +$boxShadowColorEnabled: var(--tb-widget-button-box-shadow-color-enabled, $defaultBoxShadowColor); + +$mainColorHovered: var(--tb-widget-button-main-color-hovered, $defaultMainColor); +$backgroundColorHovered: var(--tb-widget-button-background-color-hovered, $defaultBackgroundColor); +$boxShadowColorHovered: var(--tb-widget-button-box-shadow-color-hovered, $defaultBoxShadowColor); +$mainColorHoveredFilled: var(--tb-widget-button-main-color-hovered-filled, #263BD7); // main.darken(6) + +$mainColorPressed: var(--tb-widget-button-main-color-pressed, $defaultMainColor); +$backgroundColorPressed: var(--tb-widget-button-background-color-pressed, $defaultBackgroundColor); +$boxShadowColorPressed: var(--tb-widget-button-box-shadow-color-pressed, $defaultBoxShadowColor); +$mainColorPressedFilled: var(--tb-widget-button-main-color-pressed-filled, #2234BD); // main.darken(12) +$mainColorPressedRipple: var(--tb-widget-button-main-color-pressed-ripple, rgba(63, 82, 221, 0.1)); // Alpha(Main, 0.1) +$mainColorPressedRippleFilled: var(--tb-widget-button-main-color-pressed-ripple-filled, #1D2DA3); // main.darken(18) + +$mainColorActivated: var(--tb-widget-button-main-color-activated, $defaultMainColor); +$backgroundColorActivated: var(--tb-widget-button-background-color-activated, $defaultBackgroundColor); +$boxShadowColorActivated: var(--tb-widget-button-box-shadow-color-activated, $defaultBoxShadowColor); +$mainColorActivatedFilled: var(--tb-widget-button-main-color-activated-filled, #2234BD); // main.darken(12) + +$mainColorDisabled: var(--tb-widget-button-main-color-disabled, $defaultMainColorDisabled); +$backgroundColorDisabled: var(--tb-widget-button-background-color-disabled, $defaultBackgroundColorDisabled); +$boxShadowColorDisabled: var(--tb-widget-button-box-shadow-color-activated, $defaultBoxShadowColor); + + +@mixin _tb-widget-button-styles($main, $background, $boxShadow) { + color: $main; + background-color: $background; + box-shadow: 0 4px 8px 0 $boxShadow; + &.tb-outlined { + border: 1px solid $main; + } + &.tb-filled { + color: $background; + background-color: $main; + } + &.tb-underlined { + border-bottom: 2px solid $main; + } + &.tb-basic { + background-color: transparent; + } +} + + +.mat-mdc-button.mat-mdc-button-base.tb-widget-button { + width: 100%; + height: 100%; + padding: 8px 12px; + .mdc-button__label { + width: 100%; + height: 100%; + display: flex; + align-items: center; + justify-content: center; + } + .tb-widget-button-content { + width: 100%; + display: flex; + flex-direction: row; + gap: 4px; + justify-content: center; + align-items: center; + .mat-icon { + margin: 0; + } + span.tb-widget-button-label { + line-height: normal; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + } + + .mat-mdc-button-persistent-ripple::before { + opacity: 0; + } + + @include _tb-widget-button-styles($mainColorEnabled, $backgroundColorEnabled, $boxShadowColorEnabled); + + &:not(:disabled):not(.tb-disabled-state) { + &:hover, &.tb-hover-state { + &:not(:active):not(.tb-active-state) { + &:not(.tb-filled) { + .mat-mdc-button-persistent-ripple::before { + opacity: 0.04; + background-color: $mainColorHovered; + } + } + &.tb-filled { + .mat-mdc-button-persistent-ripple::before { + opacity: 1; + background-color: $mainColorHoveredFilled; + } + } + @include _tb-widget-button-styles($mainColorHovered, $backgroundColorHovered, $boxShadowColorHovered); + } + } + &.tb-pressed-state { + &:not(.tb-filled) { + .mat-mdc-button-ripple { + background-color: $mainColorPressedRipple; + } + } + &.tb-filled { + .mat-mdc-button-ripple { + background-color: $mainColorPressedRippleFilled; + } + } + } + &.tb-pressed { + &:not(.tb-filled) { + .mat-ripple-element { + background-color: $mainColorPressedRipple; + } + } + &.tb-filled { + .mat-ripple-element { + background-color: $mainColorPressedRippleFilled; + } + } + } + &.tb-pressed, &.tb-pressed-state { + &:not(.tb-filled) { + .mat-mdc-button-persistent-ripple::before { + opacity: 0.12; + background-color: $mainColorPressed; + } + } + &.tb-filled { + .mat-mdc-button-persistent-ripple::before { + opacity: 1; + background-color: $mainColorPressedFilled; + } + } + @include _tb-widget-button-styles($mainColorPressed, $backgroundColorPressed, $boxShadowColorPressed); + } + &:active, &.tb-active-state { + &:not(.tb-pressed):not(.tb-pressed-state) { + &:not(.tb-filled) { + .mat-mdc-button-persistent-ripple::before { + opacity: 0.12; + background-color: $mainColorActivated; + } + } + &.tb-filled { + .mat-mdc-button-persistent-ripple::before { + opacity: 1; + background-color: $mainColorActivatedFilled; + } + } + @include _tb-widget-button-styles($mainColorActivated, $backgroundColorActivated, $boxShadowColorActivated); + } + } + } + + &:disabled, &.tb-disabled-state { + &:not(.tb-filled) { + @include _tb-widget-button-styles($mainColorDisabled, $backgroundColorDisabled, $boxShadowColorDisabled); + } + &.tb-filled { + @include _tb-widget-button-styles($backgroundColorDisabled, $mainColorDisabled, $boxShadowColorDisabled); + } + } +} diff --git a/ui-ngx/src/app/shared/components/button/widget-button.component.ts b/ui-ngx/src/app/shared/components/button/widget-button.component.ts new file mode 100644 index 0000000000..d8fe88b48e --- /dev/null +++ b/ui-ngx/src/app/shared/components/button/widget-button.component.ts @@ -0,0 +1,178 @@ +/// +/// Copyright © 2016-2024 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 { + AfterViewInit, + Component, + ElementRef, + EventEmitter, + Input, + OnChanges, + OnDestroy, + OnInit, + Output, + Renderer2, + SimpleChanges, ViewChild, + ViewEncapsulation +} from '@angular/core'; +import { + generateWidgetButtonAppearanceCss, + widgetButtonDefaultAppearance +} from '@shared/components/button/widget-button.models'; +import { coerceBoolean } from '@shared/decorators/coercion'; +import { ComponentStyle, iconStyle } from '@shared/models/widget-settings.models'; +import { UtilsService } from '@core/services/utils.service'; +import { ResizeObserver } from '@juggle/resize-observer'; + +const initialButtonHeight = 60; +const horizontalLayoutPadding = 24; +const verticalLayoutPadding = 16; + +@Component({ + selector: 'tb-widget-button', + templateUrl: './widget-button.component.html', + styleUrls: ['./widget-button.component.scss'], + encapsulation: ViewEncapsulation.None +}) +export class WidgetButtonComponent implements OnInit, AfterViewInit, OnDestroy, OnChanges { + + @ViewChild('widgetButton', {read: ElementRef}) + widgetButton: ElementRef; + + @ViewChild('widgetButtonContent', {static: false}) + widgetButtonContent: ElementRef; + + @Input() + appearance = widgetButtonDefaultAppearance; + + @Input() + borderRadius = '4px'; + + @Input() + @coerceBoolean() + disabled = false; + + @Input() + @coerceBoolean() + activated = false; + + @Input() + @coerceBoolean() + hovered = false; + + @Input() + @coerceBoolean() + pressed = false; + + @Input() + @coerceBoolean() + disableEvents = false; + + @Output() + clicked = new EventEmitter(); + + iconStyle: ComponentStyle = {}; + + mousePressed = false; + + private buttonResize$: ResizeObserver; + + private appearanceCssClass: string; + + constructor(private renderer: Renderer2, + private elementRef: ElementRef, + private utils: UtilsService) {} + + ngOnInit(): void { + this.updateAppearance(); + } + + ngOnChanges(changes: SimpleChanges): void { + for (const propName of Object.keys(changes)) { + const change = changes[propName]; + if (!change.firstChange) { + if (propName === 'appearance') { + this.updateAppearance(); + } + } + } + } + + ngAfterViewInit(): void { + this.updateAutoScale(); + } + + ngOnDestroy(): void { + if (this.buttonResize$) { + this.buttonResize$.disconnect(); + } + this.clearAppearanceCss(); + } + + private updateAppearance(): void { + this.clearAppearanceCss(); + if (this.appearance.showIcon) { + this.iconStyle = iconStyle(this.appearance.iconSize, this.appearance.iconSizeUnit); + } + const appearanceCss = generateWidgetButtonAppearanceCss(this.appearance); + this.appearanceCssClass = this.utils.applyCssToElement(this.renderer, this.elementRef.nativeElement, + 'tb-widget-button', appearanceCss); + this.updateAutoScale(); + } + + private clearAppearanceCss(): void { + if (this.appearanceCssClass) { + this.utils.clearCssElement(this.renderer, this.appearanceCssClass, this.elementRef?.nativeElement); + this.appearanceCssClass = null; + } + } + + private updateAutoScale() { + if (this.buttonResize$) { + this.buttonResize$.disconnect(); + } + if (this.widgetButton && this.widgetButtonContent) { + if (this.appearance.autoScale) { + this.buttonResize$ = new ResizeObserver(() => { + this.onResize(); + }); + this.buttonResize$.observe(this.widgetButton.nativeElement); + this.onResize(); + } else { + this.renderer.setStyle(this.widgetButtonContent.nativeElement, 'transform', 'none'); + this.renderer.setStyle(this.widgetButtonContent.nativeElement, 'width', '100%'); + } + } + } + + private onResize() { + const height = this.widgetButton.nativeElement.getBoundingClientRect().height; + const buttonScale = height / initialButtonHeight; + const paddingScale = Math.min(buttonScale, 1); + const buttonWidth = this.widgetButton.nativeElement.getBoundingClientRect().width - (horizontalLayoutPadding * paddingScale); + const buttonHeight = this.widgetButton.nativeElement.getBoundingClientRect().height - (verticalLayoutPadding * paddingScale); + this.renderer.setStyle(this.widgetButtonContent.nativeElement, 'transform', `scale(1)`); + this.renderer.setStyle(this.widgetButtonContent.nativeElement, 'width', 'auto'); + const contentWidth = this.widgetButtonContent.nativeElement.getBoundingClientRect().width; + const contentHeight = this.widgetButtonContent.nativeElement.getBoundingClientRect().height; + const maxScale = Math.max(1, buttonScale); + const scale = Math.min(Math.min(buttonWidth / contentWidth, buttonHeight / contentHeight), maxScale); + const targetWidth = buttonWidth / scale; + this.renderer.setStyle(this.widgetButtonContent.nativeElement, 'width', targetWidth + 'px'); + this.renderer.setStyle(this.widgetButtonContent.nativeElement, 'transform', `scale(${scale})`); + } + +} diff --git a/ui-ngx/src/app/shared/components/button/widget-button.models.ts b/ui-ngx/src/app/shared/components/button/widget-button.models.ts new file mode 100644 index 0000000000..616af28588 --- /dev/null +++ b/ui-ngx/src/app/shared/components/button/widget-button.models.ts @@ -0,0 +1,259 @@ +/// +/// Copyright © 2016-2024 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 { cssUnit } from '@shared/models/widget-settings.models'; +import tinycolor from 'tinycolor2'; + +const defaultMainColor = '#3F52DD'; +const defaultBackgroundColor = '#FFFFFF'; + +export const defaultMainColorDisabled = 'rgba(0, 0, 0, 0.38)'; +export const defaultBackgroundColorDisabled = 'rgba(0, 0, 0, 0.03)'; + +const defaultBoxShadowColor = 'rgba(0, 0, 0, 0.08)'; +const defaultDisabledBoxShadowColor = 'rgba(0, 0, 0, 0)'; + +export enum WidgetButtonType { + outlined = 'outlined', + filled = 'filled', + underlined = 'underlined', + basic = 'basic' +} + +export const widgetButtonTypes = Object.keys(WidgetButtonType) as WidgetButtonType[]; + +export const widgetButtonTypeTranslations = new Map( + [ + [WidgetButtonType.outlined, 'widgets.button.outlined'], + [WidgetButtonType.filled, 'widgets.button.filled'], + [WidgetButtonType.underlined, 'widgets.button.underlined'], + [WidgetButtonType.basic, 'widgets.button.basic'] + ] +); + +export const widgetButtonTypeImages = new Map( + [ + [WidgetButtonType.outlined, 'assets/widget/button/outlined.svg'], + [WidgetButtonType.filled, 'assets/widget/button/filled.svg'], + [WidgetButtonType.underlined, 'assets/widget/button/underlined.svg'], + [WidgetButtonType.basic, 'assets/widget/button/basic.svg'] + ] +); + +export enum WidgetButtonState { + enabled = 'enabled', + hovered = 'hovered', + pressed = 'pressed', + activated = 'activated', + disabled = 'disabled' +} + +export const widgetButtonStates = Object.keys(WidgetButtonState) as WidgetButtonState[]; + +export const widgetButtonStatesTranslations = new Map( + [ + [WidgetButtonState.enabled, 'widgets.button-state.enabled'], + [WidgetButtonState.hovered, 'widgets.button-state.hovered'], + [WidgetButtonState.pressed, 'widgets.button-state.pressed'], + [WidgetButtonState.activated, 'widgets.button-state.activated'], + [WidgetButtonState.disabled, 'widgets.button-state.disabled'] + ] +); + +export interface WidgetButtonCustomStyle { + overrideMainColor?: boolean; + mainColor?: string; + overrideBackgroundColor?: boolean; + backgroundColor?: string; + overrideDropShadow?: boolean; + dropShadow?: boolean; +} + +export type WidgetButtonCustomStyles = Record; + +export interface WidgetButtonAppearance { + type: WidgetButtonType; + autoScale: boolean; + showLabel: boolean; + label: string; + showIcon: boolean; + icon: string; + iconSize: number; + iconSizeUnit: cssUnit; + mainColor: string; + backgroundColor: string; + customStyle: WidgetButtonCustomStyles; +} + +export const widgetButtonDefaultAppearance: WidgetButtonAppearance = { + type: WidgetButtonType.outlined, + autoScale: true, + showLabel: true, + label: 'Button', + showIcon: true, + icon: 'home', + iconSize: 24, + iconSizeUnit: 'px', + mainColor: defaultMainColor, + backgroundColor: defaultBackgroundColor, + customStyle: { + enabled: null, + hovered: null, + pressed: null, + activated: null, + disabled: null + } +}; + +const mainColorVarPrefix = '--tb-widget-button-main-color-'; +const backgroundColorVarPrefix = '--tb-widget-button-background-color-'; +const boxShadowColorVarPrefix = '--tb-widget-button-box-shadow-color-'; + +abstract class ButtonStateCssGenerator { + + constructor() {} + + public generateStateCss(appearance: WidgetButtonAppearance): string { + let mainColor = this.getMainColor(appearance); + let backgroundColor = this.getBackgroundColor(appearance); + const shadowEnabledByDefault = appearance.type !== WidgetButtonType.basic; + let shadowColor = shadowEnabledByDefault ? defaultBoxShadowColor : defaultDisabledBoxShadowColor; + const stateCustomStyle = appearance.customStyle[this.state]; + if (stateCustomStyle?.overrideMainColor && stateCustomStyle?.mainColor) { + mainColor = stateCustomStyle.mainColor; + } + if (stateCustomStyle?.overrideBackgroundColor && stateCustomStyle?.backgroundColor) { + backgroundColor = stateCustomStyle.backgroundColor; + } + if (stateCustomStyle?.overrideDropShadow) { + shadowColor = !!stateCustomStyle.dropShadow ? defaultBoxShadowColor : defaultDisabledBoxShadowColor; + } + + let css = `${mainColorVarPrefix}${this.state}: ${mainColor};\n`+ + `${backgroundColorVarPrefix}${this.state}: ${backgroundColor};\n`+ + `${boxShadowColorVarPrefix}${this.state}: ${shadowColor};`; + const additionalCss = this.generateAdditionalStateCss(mainColor, backgroundColor); + if (additionalCss) { + css += `\n${additionalCss}`; + } + return css; + } + + protected abstract get state(): WidgetButtonState; + + protected getMainColor(appearance: WidgetButtonAppearance): string { + return appearance.mainColor || defaultMainColor; + } + + protected getBackgroundColor(appearance: WidgetButtonAppearance): string { + return appearance.backgroundColor || defaultBackgroundColor; + } + + protected generateAdditionalStateCss(_mainColor: string, _backgroundColor: string): string { + return null; + } +} + +class EnabledButtonStateCssGenerator extends ButtonStateCssGenerator { + + protected get state(): WidgetButtonState { + return WidgetButtonState.enabled; + } +} + +class HoveredButtonStateCssGenerator extends ButtonStateCssGenerator { + + protected get state(): WidgetButtonState { + return WidgetButtonState.hovered; + } + + protected generateAdditionalStateCss(mainColor: string): string { + const mainColorHoveredFilled = darkenColor(mainColor, 6); + return `--tb-widget-button-main-color-hovered-filled: ${mainColorHoveredFilled};`; + } +} + +class PressedButtonStateCssGenerator extends ButtonStateCssGenerator { + + protected get state(): WidgetButtonState { + return WidgetButtonState.pressed; + } + + protected generateAdditionalStateCss(mainColor: string): string { + const mainColorPressedFilled = darkenColor(mainColor, 12); + const mainColorInstance = tinycolor(mainColor); + const mainColorPressedRipple = mainColorInstance.setAlpha(mainColorInstance.getAlpha() * 0.1).toRgbString(); + const mainColorPressedRippleFilled = darkenColor(mainColor, 18); + return `--tb-widget-button-main-color-pressed-filled: ${mainColorPressedFilled};\n`+ + `--tb-widget-button-main-color-pressed-ripple: ${mainColorPressedRipple};\n`+ + `--tb-widget-button-main-color-pressed-ripple-filled: ${mainColorPressedRippleFilled};`; + } +} + +class ActivatedButtonStateCssGenerator extends ButtonStateCssGenerator { + + protected get state(): WidgetButtonState { + return WidgetButtonState.activated; + } + + protected generateAdditionalStateCss(mainColor: string): string { + const mainColorActivatedFilled = darkenColor(mainColor, 12); + return `--tb-widget-button-main-color-activated-filled: ${mainColorActivatedFilled};`; + } +} + +class DisabledButtonStateCssGenerator extends ButtonStateCssGenerator { + + protected get state(): WidgetButtonState { + return WidgetButtonState.disabled; + } + + protected getMainColor(): string { + return defaultMainColorDisabled; + } + + protected getBackgroundColor(): string { + return defaultBackgroundColorDisabled; + } +} + +const buttonStateCssGeneratorsMap = new Map( + [ + [WidgetButtonState.enabled, new EnabledButtonStateCssGenerator()], + [WidgetButtonState.hovered, new HoveredButtonStateCssGenerator()], + [WidgetButtonState.pressed, new PressedButtonStateCssGenerator()], + [WidgetButtonState.activated, new ActivatedButtonStateCssGenerator()], + [WidgetButtonState.disabled, new DisabledButtonStateCssGenerator()] + ] +); + +const widgetButtonCssSelector = '.mat-mdc-button.mat-mdc-button-base.tb-widget-button'; + +export const generateWidgetButtonAppearanceCss = (appearance: WidgetButtonAppearance): string => { + let statesCss = ''; + for (const state of widgetButtonStates) { + const generator = buttonStateCssGeneratorsMap.get(state); + statesCss += `\n${generator.generateStateCss(appearance)}`; + } + return `${widgetButtonCssSelector} {\n`+ + `${statesCss}\n`+ + `}`; +}; + +const darkenColor = (inputColor: string, amount: number): string => { + const input = tinycolor(inputColor); + return input.darken(amount).toRgbString(); +}; diff --git a/ui-ngx/src/app/shared/models/action-widget-settings.models.ts b/ui-ngx/src/app/shared/models/action-widget-settings.models.ts index d1442c09c5..c9a61c5ad0 100644 --- a/ui-ngx/src/app/shared/models/action-widget-settings.models.ts +++ b/ui-ngx/src/app/shared/models/action-widget-settings.models.ts @@ -15,6 +15,7 @@ /// import { AttributeScope } from '@shared/models/telemetry/telemetry.models'; +import { widgetType } from '@shared/models/widget.models'; export enum GetValueAction { DO_NOTHING = 'DO_NOTHING', @@ -25,6 +26,14 @@ export enum GetValueAction { export const getValueActions = Object.keys(GetValueAction) as GetValueAction[]; +export const getValueActionsByWidgetType = (type: widgetType): GetValueAction[] => { + if (type !== widgetType.rpc) { + return getValueActions.filter(action => action !== GetValueAction.EXECUTE_RPC); + } else { + return getValueActions; + } +}; + export const getValueActionTranslations = new Map( [ [GetValueAction.DO_NOTHING, 'widgets.value-action.do-nothing'], @@ -75,7 +84,7 @@ export interface ValueActionSettings { export interface GetValueSettings extends ValueActionSettings { action: GetValueAction; defaultValue: V; - executeRpc: RpcSettings; + executeRpc?: RpcSettings; getAttribute: GetAttributeValueSettings; getTimeSeries: GetTelemetryValueSettings; dataToValue: DataToValueSettings; @@ -89,6 +98,14 @@ export enum SetValueAction { export const setValueActions = Object.keys(SetValueAction) as SetValueAction[]; +export const setValueActionsByWidgetType = (type: widgetType): SetValueAction[] => { + if (type !== widgetType.rpc) { + return setValueActions.filter(action => action !== SetValueAction.EXECUTE_RPC); + } else { + return setValueActions; + } +}; + export const setValueActionTranslations = new Map( [ [SetValueAction.EXECUTE_RPC, 'widgets.value-action.execute-rpc'], diff --git a/ui-ngx/src/app/shared/models/widget-settings.models.ts b/ui-ngx/src/app/shared/models/widget-settings.models.ts index cf72e20025..5bd9e26f13 100644 --- a/ui-ngx/src/app/shared/models/widget-settings.models.ts +++ b/ui-ngx/src/app/shared/models/widget-settings.models.ts @@ -15,7 +15,14 @@ /// import { isDefinedAndNotNull, isNumber, isNumeric, isUndefinedOrNull, parseFunction } from '@core/utils'; -import { DataEntry, DataKey, Datasource, DatasourceData } from '@shared/models/widget.models'; +import { + DataEntry, + DataKey, + Datasource, + DatasourceData, + DatasourceType, + TargetDevice, TargetDeviceType +} from '@shared/models/widget.models'; import { Injector } from '@angular/core'; import { DatePipe } from '@angular/common'; import { DateAgoPipe } from '@shared/pipe/date-ago.pipe'; @@ -600,6 +607,24 @@ export const updateDataKeyByLabel = (datasources: Datasource[], dataKey: DataKey } }; +export const getTargetDeviceFromDatasources = (datasources?: Datasource[]): TargetDevice => { + if (datasources && datasources.length) { + const datasource = datasources[0]; + if (datasource?.type === DatasourceType.device) { + return { + type: TargetDeviceType.device, + deviceId: datasource?.deviceId + }; + } else if (datasource?.type === DatasourceType.entity) { + return { + type: TargetDeviceType.entity, + entityAliasId: datasource?.entityAliasId + }; + } + } + return null; +}; + export const getAlarmFilterConfig = (datasources?: Datasource[]): AlarmFilterConfig => { if (datasources && datasources.length) { const config = datasources[0].alarmFilterConfig; diff --git a/ui-ngx/src/app/shared/models/widget.models.ts b/ui-ngx/src/app/shared/models/widget.models.ts index 3a13f51b24..625d957cff 100644 --- a/ui-ngx/src/app/shared/models/widget.models.ts +++ b/ui-ngx/src/app/shared/models/widget.models.ts @@ -180,6 +180,7 @@ export interface WidgetTypeParameters { previewWidth?: string; previewHeight?: string; embedTitlePanel?: boolean; + overflowVisible?: boolean; hideDataSettings?: boolean; defaultDataKeysFunction?: (configComponent: any, configData: any) => DataKey[]; defaultLatestDataKeysFunction?: (configComponent: any, configData: any) => DataKey[]; @@ -410,6 +411,23 @@ export interface Datasource { [key: string]: any; } +export const datasourceValid = (datasource: Datasource): boolean => { + const type: DatasourceType = datasource?.type; + if (type) { + switch (type) { + case DatasourceType.function: + case DatasourceType.alarmCount: + return true; + case DatasourceType.device: + return !!datasource.deviceId; + case DatasourceType.entity: + case DatasourceType.entityCount: + return !!datasource.entityAliasId; + } + } + return false; +}; + export enum TargetDeviceType { device = 'device', entity = 'entity' @@ -675,6 +693,14 @@ export const actionDescriptorToAction = (descriptor: WidgetActionDescriptor): Wi return result; }; +export const defaultWidgetAction = (setEntityId = true): WidgetAction => ({ + type: WidgetActionType.updateDashboardState, + targetDashboardStateId: null, + openRightLayout: false, + setEntityId, + stateEntityParamName: null + }); + export interface WidgetComparisonSettings { comparisonEnabled?: boolean; timeForComparison?: moment_.unitOfTime.DurationConstructor; diff --git a/ui-ngx/src/app/shared/shared.module.ts b/ui-ngx/src/app/shared/shared.module.ts index 0abf2167f6..71f121ab17 100644 --- a/ui-ngx/src/app/shared/shared.module.ts +++ b/ui-ngx/src/app/shared/shared.module.ts @@ -217,6 +217,7 @@ import { MultipleGalleryImageInputComponent } from '@shared/components/image/mul import { EmbedImageDialogComponent } from '@shared/components/image/embed-image-dialog.component'; import { ImageGalleryDialogComponent } from '@shared/components/image/image-gallery-dialog.component'; import { RuleChainSelectPanelComponent } from '@shared/components/rule-chain/rule-chain-select-panel.component'; +import { WidgetButtonComponent } from '@shared/components/button/widget-button.component'; export function MarkedOptionsFactory(markedOptionsService: MarkedOptionsService) { return markedOptionsService; @@ -414,7 +415,8 @@ export function MarkedOptionsFactory(markedOptionsService: MarkedOptionsService) GalleryImageInputComponent, MultipleGalleryImageInputComponent, EmbedImageDialogComponent, - ImageGalleryDialogComponent + ImageGalleryDialogComponent, + WidgetButtonComponent ], imports: [ CommonModule, @@ -666,7 +668,8 @@ export function MarkedOptionsFactory(markedOptionsService: MarkedOptionsService) GalleryImageInputComponent, MultipleGalleryImageInputComponent, EmbedImageDialogComponent, - ImageGalleryDialogComponent + ImageGalleryDialogComponent, + WidgetButtonComponent ] }) export class SharedModule { } diff --git a/ui-ngx/src/assets/locale/locale.constant-en_US.json b/ui-ngx/src/assets/locale/locale.constant-en_US.json index e18d21f609..fa9945dd50 100644 --- a/ui-ngx/src/assets/locale/locale.constant-en_US.json +++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json @@ -5182,6 +5182,42 @@ "invalid-widget-file-error": "Unable to import widget: Invalid widget data structure." }, "widgets": { + "action-button": { + "behavior": "Behavior", + "on-click": "On click", + "on-click-hint": "Action performed when the button is clicked." + }, + "button": { + "layout": "Layout", + "outlined": "Outlined", + "filled": "Filled", + "underlined": "Underlined", + "basic": "Basic", + "auto-scale": "Auto scale", + "label": "Label", + "icon": "Icon", + "color-palette": "Color palette", + "main": "Main", + "background": "Background", + "custom-styles": "Custom styles", + "clear-style": "Clear style", + "shadow": "Shadow", + "enabled": "Enabled", + "disabled": "Disabled", + "preview": "Preview", + "copy-style-from": "Copy style from" + }, + "button-state": { + "activated-state": "Activated state", + "activated-state-hint": "Condition under which the button is active.", + "disabled-state": "Disabled state", + "disabled-state-hint": "Condition under which the button is disabled.", + "enabled": "Enabled", + "hovered": "Hovered", + "pressed": "Pressed", + "activated": "Activated", + "disabled": "Disabled" + }, "background": { "background": "Background", "background-settings": "Background settings", @@ -6483,7 +6519,7 @@ "source-entity-alias": "Source entity alias", "source-entity-attribute": "Source entity attribute" }, - "value-action": { + "rpc-state": { "initial-state": "Initial state", "initial-state-hint": "Action to get the initial value of the component.", "turn-on": "Turn 'On'", @@ -6491,7 +6527,9 @@ "turn-off": "Turn 'Off'", "turn-off-hint": "Action performed to turn OFF the component.", "on": "On", - "off": "Off", + "off": "Off" + }, + "value-action": { "do-nothing": "Do nothing", "execute-rpc": "Execute RPC", "get-attribute": "Get attribute", @@ -6530,7 +6568,7 @@ "converter-function": "Function", "converter-constant": "Constant", "parse-value-function": "Parse value function", - "on-when-result-is": "'On' when result is", + "state-when-result-is": "'{{state}}' when result is", "parameters": "Parameters", "convert-value-function": "Convert value function", "error": { @@ -6785,7 +6823,8 @@ "element-click": "On HTML element click", "pie-slice-click": "On slice click", "row-double-click": "On row double click", - "card-click": "On card click" + "card-click": "On card click", + "click": "On click" } }, "paginator" : { diff --git a/ui-ngx/src/assets/widget/button/basic.svg b/ui-ngx/src/assets/widget/button/basic.svg new file mode 100644 index 0000000000..6b005e345e --- /dev/null +++ b/ui-ngx/src/assets/widget/button/basic.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/ui-ngx/src/assets/widget/button/filled.svg b/ui-ngx/src/assets/widget/button/filled.svg new file mode 100644 index 0000000000..c17871583a --- /dev/null +++ b/ui-ngx/src/assets/widget/button/filled.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/ui-ngx/src/assets/widget/button/outlined.svg b/ui-ngx/src/assets/widget/button/outlined.svg new file mode 100644 index 0000000000..63b2232060 --- /dev/null +++ b/ui-ngx/src/assets/widget/button/outlined.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/ui-ngx/src/assets/widget/button/underlined.svg b/ui-ngx/src/assets/widget/button/underlined.svg new file mode 100644 index 0000000000..6638662a21 --- /dev/null +++ b/ui-ngx/src/assets/widget/button/underlined.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ui-ngx/src/form.scss b/ui-ngx/src/form.scss index d6fceb20f7..635d330572 100644 --- a/ui-ngx/src/form.scss +++ b/ui-ngx/src/form.scss @@ -607,6 +607,14 @@ } } + button.mat-mdc-button-base.tb-nowrap { + .mdc-button__label { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } + } + .mat-mdc-chip-listbox.center-stretch { .mat-mdc-standard-chip { flex: 1; From d287d410abf74f13b866885cf774d6402f23dbf5 Mon Sep 17 00:00:00 2001 From: Sergey Matvienko Date: Wed, 31 Jan 2024 15:47:07 +0100 Subject: [PATCH 156/179] GitHub workflow license-header-format --- .github/workflows/license-header-format.yml | 54 +++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 .github/workflows/license-header-format.yml diff --git a/.github/workflows/license-header-format.yml b/.github/workflows/license-header-format.yml new file mode 100644 index 0000000000..20b5e7f063 --- /dev/null +++ b/.github/workflows/license-header-format.yml @@ -0,0 +1,54 @@ +# +# Copyright © 2016-2024 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. +# + +name: License header format + +on: + push: + branches: + - 'master' + - 'develop/3*' + - 'hotfix/3*' + +jobs: + license-format: + runs-on: ubuntu-latest + + steps: + - name: Checkout Repository + uses: actions/checkout@v4 + + - name: Set up JDK + uses: actions/setup-java@v4 + with: + distribution: 'corretto' # https://github.com/actions/setup-java?tab=readme-ov-file#supported-distributions + java-version: '21' + cache: 'maven' # https://github.com/actions/setup-java?tab=readme-ov-file#caching-sbt-dependencies + + - name: License header format + run: mvn -T 1C license:format + + - name: License header format (msa/black-box-tests/) + run: mvn -T 1C license:format -f msa/black-box-tests/ + + - name: Set Git user information + run: | + git config user.name "ThingsBoard Bot" + git config user.email "noreply@thingsboard.io" + + - name: Check and push changes + run: | + git diff --exit-code || git commit -am "License header format" && git push From 42edd481e7795b8f5401db70b09697472b83b020 Mon Sep 17 00:00:00 2001 From: Igor Kulikov Date: Fri, 2 Feb 2024 13:53:41 +0200 Subject: [PATCH 157/179] UI: Add advanced settings for action button. Update Get attribute/time-series value action to always subscribe for updates. --- .../system/widget_types/action_button.json | 4 +- .../widget/lib/action/action-widget.models.ts | 42 ++--------- .../lib/button/action-button-widget.models.ts | 12 ++-- .../lib/rpc/single-switch-widget.models.ts | 6 +- ...tion-button-widget-settings.component.html | 51 ++++++++++++++ ...action-button-widget-settings.component.ts | 70 +++++++++++++++++++ ...value-action-settings-panel.component.html | 10 --- ...t-value-action-settings-panel.component.ts | 8 +-- ...led-indicator-widget-settings.component.ts | 2 +- .../round-switch-widget-settings.component.ts | 2 +- ...single-switch-widget-settings.component.ts | 9 ++- .../slide-toggle-widget-settings.component.ts | 2 +- ...witch-control-widget-settings.component.ts | 2 +- .../lib/settings/widget-settings.module.ts | 20 ++++-- .../models/action-widget-settings.models.ts | 18 +---- .../assets/locale/locale.constant-en_US.json | 2 - 16 files changed, 161 insertions(+), 99 deletions(-) create mode 100644 ui-ngx/src/app/modules/home/components/widget/lib/settings/button/action-button-widget-settings.component.html create mode 100644 ui-ngx/src/app/modules/home/components/widget/lib/settings/button/action-button-widget-settings.component.ts diff --git a/application/src/main/data/json/system/widget_types/action_button.json b/application/src/main/data/json/system/widget_types/action_button.json index 3ad518ce23..e6ffa8084e 100644 --- a/application/src/main/data/json/system/widget_types/action_button.json +++ b/application/src/main/data/json/system/widget_types/action_button.json @@ -11,10 +11,10 @@ "resources": [], "templateHtml": "\n", "templateCss": "#container tb-markdown-widget {\n height: 100%;\n display: block;\n}\n\n#container tb-markdown-widget .tb-markdown-view {\n height: 100%;\n overflow: auto;\n}\n", - "controllerScript": "self.onInit = function() {\n self.ctx.$scope.actionWidget.onInit();\n}\n\nself.actionSources = function() {\n return {\n 'click': {\n name: 'widget-action.click',\n multiple: false\n }\n };\n}\n\nself.typeParameters = function() {\n return {\n dataKeysOptional: true,\n datasourcesOptional: true,\n maxDatasources: 1,\n maxDataKeys: 0,\n singleEntity: true,\n previewWidth: '200px',\n previewHeight: '80px',\n embedTitlePanel: true,\n overflowVisible: true\n };\n}\n\nself.onDestroy = function() {\n}\n\n", + "controllerScript": "self.onInit = function() {\n self.ctx.$scope.actionWidget.onInit();\n}\n\nself.actionSources = function() {\n return {\n 'click': {\n name: 'widget-action.click',\n multiple: false\n }\n };\n}\n\nself.typeParameters = function() {\n return {\n dataKeysOptional: true,\n datasourcesOptional: true,\n maxDatasources: 1,\n maxDataKeys: 0,\n singleEntity: true,\n previewWidth: '200px',\n previewHeight: '80px',\n embedTitlePanel: true,\n overflowVisible: true,\n hideDataSettings: true\n };\n}\n\nself.onDestroy = function() {\n}\n\n", "settingsSchema": "", "dataKeySettingsSchema": "", - "settingsDirective": "", + "settingsDirective": "tb-action-button-widget-settings", "hasBasicMode": true, "basicModeDirective": "tb-action-button-basic-config", "defaultConfig": "{\"datasources\":[],\"timewindow\":{\"realtime\":{\"timewindowMs\":60000}},\"showTitle\":false,\"backgroundColor\":\"#FFFFFF01\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"0px\",\"settings\":{},\"title\":\"Action button\",\"showTitleIcon\":false,\"iconColor\":\"rgba(0, 0, 0, 0.87)\",\"iconSize\":\"24px\",\"titleTooltip\":\"\",\"dropShadow\":false,\"enableFullscreen\":false,\"widgetStyle\":{},\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"showLegend\":false,\"useDashboardTimewindow\":true,\"displayTimewindow\":true,\"widgetCss\":\"\",\"pageSize\":1024,\"noDataDisplayMessage\":\"\",\"borderRadius\":\"4px\",\"configMode\":\"basic\"}" diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/action/action-widget.models.ts b/ui-ngx/src/app/modules/home/components/widget/lib/action/action-widget.models.ts index 8557c9cbd3..26dc76866a 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/action/action-widget.models.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/action/action-widget.models.ts @@ -31,7 +31,6 @@ import { DataToValueSettings, DataToValueType, GetAttributeValueSettings, - GetTelemetryValueSettings, GetValueAction, GetValueSettings, RpcSettings, @@ -405,7 +404,7 @@ export class ExecuteRpcValueGetter extends ValueGetter { } } -export abstract class TelemetryValueGetter extends ValueGetter { +export abstract class TelemetryValueGetter extends ValueGetter { protected targetEntityId: EntityId; private telemetrySubscriber: TelemetrySubscriber; @@ -428,11 +427,7 @@ export abstract class TelemetryValueGetter err); } - if (this.getTelemetryValueSettings().subscribeForUpdates) { - return this.subscribeForTelemetryValue(); - } else { - return this.doGetTelemetryValue(); - } + return this.subscribeForTelemetryValue(); } else { return of(null); } @@ -464,8 +459,6 @@ export abstract class TelemetryValueGetter; - destroy() { if (this.telemetrySubscriber) { this.telemetrySubscriber.unsubscribe(); @@ -492,17 +485,9 @@ export class AttributeValueGetter extends TelemetryValueGetter { - const getAttributeValueSettings = this.getTelemetryValueSettings(); - return this.ctx.attributeService.getEntityAttributes(this.targetEntityId, - getAttributeValueSettings.scope, [getAttributeValueSettings.key], {ignoreLoading: true, ignoreErrors: true}).pipe( - map((data) => data.find(attr => attr.key === getAttributeValueSettings.key)?.value) - ); - } - } -export class TimeSeriesValueGetter extends TelemetryValueGetter { +export class TimeSeriesValueGetter extends TelemetryValueGetter { constructor(protected ctx: WidgetContext, protected settings: GetValueSettings, @@ -511,28 +496,9 @@ export class TimeSeriesValueGetter extends TelemetryValueGetter { - const getTelemetryValueSettings = this.getTelemetryValueSettings(); - return this.ctx.attributeService.getEntityTimeseriesLatest(this.targetEntityId, - [getTelemetryValueSettings.key], true, {ignoreLoading: true, ignoreErrors: true}) - .pipe( - map((data) => { - let value: any = null; - if (data[getTelemetryValueSettings.key]) { - const dataSet = data[getTelemetryValueSettings.key]; - if (dataSet.length) { - value = dataSet[0].value; - } - } - return value; - }) - ); - } - } export class ExecuteRpcValueSetter extends ValueSetter { diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/button/action-button-widget.models.ts b/ui-ngx/src/app/modules/home/components/widget/lib/button/action-button-widget.models.ts index f86ef73439..4b3fafa55c 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/button/action-button-widget.models.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/button/action-button-widget.models.ts @@ -33,12 +33,10 @@ export const actionButtonDefaultSettings: ActionButtonWidgetSettings = { defaultValue: false, getAttribute: { key: 'state', - scope: null, - subscribeForUpdates: false + scope: null }, getTimeSeries: { - key: 'state', - subscribeForUpdates: false + key: 'state' }, dataToValue: { type: DataToValueType.NONE, @@ -51,12 +49,10 @@ export const actionButtonDefaultSettings: ActionButtonWidgetSettings = { defaultValue: false, getAttribute: { key: 'state', - scope: null, - subscribeForUpdates: false + scope: null }, getTimeSeries: { - key: 'state', - subscribeForUpdates: false + key: 'state' }, dataToValue: { type: DataToValueType.NONE, diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/rpc/single-switch-widget.models.ts b/ui-ngx/src/app/modules/home/components/widget/lib/rpc/single-switch-widget.models.ts index 23510e174a..4f0401b3bd 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/rpc/single-switch-widget.models.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/rpc/single-switch-widget.models.ts @@ -93,12 +93,10 @@ export const singleSwitchDefaultSettings: SingleSwitchWidgetSettings = { }, getAttribute: { key: 'state', - scope: null, - subscribeForUpdates: false + scope: null }, getTimeSeries: { - key: 'state', - subscribeForUpdates: false + key: 'state' }, dataToValue: { type: DataToValueType.NONE, diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/button/action-button-widget-settings.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/button/action-button-widget-settings.component.html new file mode 100644 index 0000000000..265a9c2501 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/button/action-button-widget-settings.component.html @@ -0,0 +1,51 @@ + + +
+
widgets.action-button.behavior
+
+
widgets.button-state.activated-state
+ +
+
+
widgets.button-state.disabled-state
+ +
+
+
+
widget-config.appearance
+ + +
+
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/button/action-button-widget-settings.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/button/action-button-widget-settings.component.ts new file mode 100644 index 0000000000..26f785fac9 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/button/action-button-widget-settings.component.ts @@ -0,0 +1,70 @@ +/// +/// Copyright © 2016-2024 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 { Component } from '@angular/core'; +import { TargetDevice, WidgetSettings, WidgetSettingsComponent, widgetType } from '@shared/models/widget.models'; +import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms'; +import { Store } from '@ngrx/store'; +import { AppState } from '@core/core.state'; +import { ValueType } from '@shared/models/constants'; +import { getTargetDeviceFromDatasources } from '@shared/models/widget-settings.models'; +import { actionButtonDefaultSettings } from '@home/components/widget/lib/button/action-button-widget.models'; + +@Component({ + selector: 'tb-action-button-widget-settings', + templateUrl: './action-button-widget-settings.component.html', + styleUrls: ['./../widget-settings.scss'] +}) +export class ActionButtonWidgetSettingsComponent extends WidgetSettingsComponent { + + get targetDevice(): TargetDevice { + const datasources = this.widgetConfig?.config?.datasources; + return getTargetDeviceFromDatasources(datasources); + } + + get widgetType(): widgetType { + return this.widgetConfig?.widgetType; + } + get borderRadius(): string { + return this.widgetConfig?.config?.borderRadius; + } + + valueType = ValueType; + + actionButtonWidgetSettingsForm: UntypedFormGroup; + + constructor(protected store: Store, + private fb: UntypedFormBuilder) { + super(store); + } + + protected settingsForm(): UntypedFormGroup { + return this.actionButtonWidgetSettingsForm; + } + + protected defaultSettings(): WidgetSettings { + return {...actionButtonDefaultSettings}; + } + + protected onSettingsSet(settings: WidgetSettings) { + this.actionButtonWidgetSettingsForm = this.fb.group({ + activatedState: [settings.activatedState, []], + disabledState: [settings.disabledState, []], + + appearance: [settings.appearance, []] + }); + } +} diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/get-value-action-settings-panel.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/get-value-action-settings-panel.component.html index 9684be6fd3..faad403e9b 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/get-value-action-settings-panel.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/get-value-action-settings-panel.component.html @@ -84,11 +84,6 @@ [attributeScope]="getValueSettingsFormGroup.get('getAttribute').get('scope').value">
-
- - {{ 'widgets.value-action.subscribe-for-updates' | translate }} - -
@@ -106,11 +101,6 @@ [keyType]="dataKeyType.timeseries">
-
- - {{ 'widgets.value-action.subscribe-for-updates' | translate }} - -
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/get-value-action-settings-panel.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/get-value-action-settings-panel.component.ts index 4b9eb98ae2..f9202b982f 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/get-value-action-settings-panel.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/get-value-action-settings-panel.component.ts @@ -24,7 +24,7 @@ import { merge } from 'rxjs'; import { DataToValueType, GetValueAction, - getValueActions, getValueActionsByWidgetType, + getValueActionsByWidgetType, getValueActionTranslations, GetValueSettings } from '@shared/models/action-widget-settings.models'; @@ -117,12 +117,10 @@ export class GetValueActionSettingsPanelComponent extends PageComponent implemen }), getAttribute: this.fb.group({ scope: [this.getValueSettings?.getAttribute?.scope, []], - key: [this.getValueSettings?.getAttribute?.key, [Validators.required]], - subscribeForUpdates: [this.getValueSettings?.getAttribute?.subscribeForUpdates, []] + key: [this.getValueSettings?.getAttribute?.key, [Validators.required]] }), getTimeSeries: this.fb.group({ - key: [this.getValueSettings?.getTimeSeries?.key, [Validators.required]], - subscribeForUpdates: [this.getValueSettings?.getTimeSeries?.subscribeForUpdates, []] + key: [this.getValueSettings?.getTimeSeries?.key, [Validators.required]] }), dataToValue: this.fb.group({ type: [this.getValueSettings?.dataToValue?.type, [Validators.required]], diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/led-indicator-widget-settings.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/led-indicator-widget-settings.component.ts index 22af44f2b4..70f4846b78 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/led-indicator-widget-settings.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/led-indicator-widget-settings.component.ts @@ -32,7 +32,7 @@ export class LedIndicatorWidgetSettingsComponent extends WidgetSettingsComponent functionScopeVariables = this.widgetService.getWidgetScopeVariables(); get targetDevice(): TargetDevice { - return this.widget?.config?.targetDevice; + return this.widgetConfig?.config?.targetDevice; } dataKeyType = DataKeyType; diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/round-switch-widget-settings.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/round-switch-widget-settings.component.ts index 8bf58a9b22..a8d4d70015 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/round-switch-widget-settings.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/round-switch-widget-settings.component.ts @@ -37,7 +37,7 @@ export class RoundSwitchWidgetSettingsComponent extends WidgetSettingsComponent } get targetDevice(): TargetDevice { - return this.widget?.config?.targetDevice; + return this.widgetConfig?.config?.targetDevice; } protected settingsForm(): UntypedFormGroup { diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/single-switch-widget-settings.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/single-switch-widget-settings.component.ts index f4bd08a20c..8c7282e32b 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/single-switch-widget-settings.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/single-switch-widget-settings.component.ts @@ -20,7 +20,8 @@ import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms import { Store } from '@ngrx/store'; import { AppState } from '@core/core.state'; import { - singleSwitchDefaultSettings, singleSwitchLayoutImages, + singleSwitchDefaultSettings, + singleSwitchLayoutImages, singleSwitchLayouts, singleSwitchLayoutTranslations } from '@home/components/widget/lib/rpc/single-switch-widget.models'; @@ -34,11 +35,11 @@ import { ValueType } from '@shared/models/constants'; export class SingleSwitchWidgetSettingsComponent extends WidgetSettingsComponent { get targetDevice(): TargetDevice { - return this.widget?.config?.targetDevice; + return this.widgetConfig?.config?.targetDevice; } get widgetType(): widgetType { - return this.widget?.type; + return this.widgetConfig?.widgetType; } singleSwitchLayouts = singleSwitchLayouts; @@ -156,6 +157,4 @@ export class SingleSwitchWidgetSettingsComponent extends WidgetSettingsComponent this.singleSwitchWidgetSettingsForm.get('offLabelColor').disable(); } } - - protected readonly ValueType = ValueType; } diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/slide-toggle-widget-settings.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/slide-toggle-widget-settings.component.ts index d14d0fd594..43098a011b 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/slide-toggle-widget-settings.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/slide-toggle-widget-settings.component.ts @@ -37,7 +37,7 @@ export class SlideToggleWidgetSettingsComponent extends WidgetSettingsComponent } get targetDevice(): TargetDevice { - return this.widget?.config?.targetDevice; + return this.widgetConfig?.config?.targetDevice; } protected settingsForm(): UntypedFormGroup { diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/switch-control-widget-settings.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/switch-control-widget-settings.component.ts index 197fc2d229..e74275b659 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/switch-control-widget-settings.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/switch-control-widget-settings.component.ts @@ -37,7 +37,7 @@ export class SwitchControlWidgetSettingsComponent extends WidgetSettingsComponen } get targetDevice(): TargetDevice { - return this.widget?.config?.targetDevice; + return this.widgetConfig?.config?.targetDevice; } protected settingsForm(): UntypedFormGroup { diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/widget-settings.module.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/widget-settings.module.ts index 30c1b748de..607cb91318 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/widget-settings.module.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/widget-settings.module.ts @@ -15,7 +15,9 @@ /// import { NgModule, Type } from '@angular/core'; -import { QrCodeWidgetSettingsComponent } from '@home/components/widget/lib/settings/cards/qrcode-widget-settings.component'; +import { + QrCodeWidgetSettingsComponent +} from '@home/components/widget/lib/settings/cards/qrcode-widget-settings.component'; import { CommonModule } from '@angular/common'; import { SharedModule } from '@shared/shared.module'; import { SharedHomeComponentsModule } from '@home/components/shared-home-components.module'; @@ -33,7 +35,9 @@ import { MarkdownWidgetSettingsComponent } from '@home/components/widget/lib/settings/cards/markdown-widget-settings.component'; import { LabelWidgetLabelComponent } from '@home/components/widget/lib/settings/cards/label-widget-label.component'; -import { LabelWidgetSettingsComponent } from '@home/components/widget/lib/settings/cards/label-widget-settings.component'; +import { + LabelWidgetSettingsComponent +} from '@home/components/widget/lib/settings/cards/label-widget-settings.component'; import { SimpleCardWidgetSettingsComponent } from '@home/components/widget/lib/settings/cards/simple-card-widget-settings.component'; @@ -311,6 +315,9 @@ import { import { SingleSwitchWidgetSettingsComponent } from '@home/components/widget/lib/settings/control/single-switch-widget-settings.component'; +import { + ActionButtonWidgetSettingsComponent +} from '@home/components/widget/lib/settings/button/action-button-widget-settings.component'; @NgModule({ declarations: [ @@ -424,7 +431,8 @@ import { DoughnutWidgetSettingsComponent, RangeChartWidgetSettingsComponent, BarChartWithLabelsWidgetSettingsComponent, - SingleSwitchWidgetSettingsComponent + SingleSwitchWidgetSettingsComponent, + ActionButtonWidgetSettingsComponent ], imports: [ CommonModule, @@ -543,7 +551,8 @@ import { DoughnutWidgetSettingsComponent, RangeChartWidgetSettingsComponent, BarChartWithLabelsWidgetSettingsComponent, - SingleSwitchWidgetSettingsComponent + SingleSwitchWidgetSettingsComponent, + ActionButtonWidgetSettingsComponent ] }) export class WidgetSettingsModule { @@ -629,5 +638,6 @@ export const widgetSettingsComponentsMap: {[key: string]: Type extends ValueActionSettings { defaultValue: V; executeRpc?: RpcSettings; getAttribute: GetAttributeValueSettings; - getTimeSeries: GetTelemetryValueSettings; + getTimeSeries: TelemetryValueSettings; dataToValue: DataToValueSettings; } @@ -133,13 +129,3 @@ export interface SetValueSettings extends ValueActionSettings { putTimeSeries: TelemetryValueSettings; valueToData: ValueToDataSettings; } - -/*export interface RpcStateBehaviourSettings { - initialState: RpcInitialStateSettings; - updateStateByValue: (value: V) => RpcUpdateStateSettings; -} - -export interface RpcStateWidgetSettings { - initialState: RpcInitialStateSettings; - background: BackgroundSettings; -}*/ diff --git a/ui-ngx/src/assets/locale/locale.constant-en_US.json b/ui-ngx/src/assets/locale/locale.constant-en_US.json index fa9945dd50..c9108e9bac 100644 --- a/ui-ngx/src/assets/locale/locale.constant-en_US.json +++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json @@ -6561,8 +6561,6 @@ "attribute-key-required": "Attribute key is required.", "time-series-key": "Time-series key", "time-series-key-required": "Time-series key is required.", - "subscribe-for-updates": "Subscribe for updates", - "subscribe-for-updates-hint": "Subscribe for updates", "action-result-converter": "Action result converter", "converter-none": "None", "converter-function": "Function", From 53b57b1351143ed6f23422e7f983e563b3860fb1 Mon Sep 17 00:00:00 2001 From: dashevchenko Date: Fri, 2 Feb 2024 14:45:28 +0200 Subject: [PATCH 158/179] updated CassandraBaseTimeseriesDao to do one db insert instead of 5 when setNullValuesEnabled=true --- .../CassandraBaseTimeseriesDao.java | 142 ++++++++++-------- .../timeseries/BaseTimeseriesServiceTest.java | 35 ++++- ...eseriesServiceNoSqlSetNullEnabledTest.java | 72 +++++++++ .../nosql/TimeseriesServiceNoSqlTest.java | 96 ++++++++++++ 4 files changed, 281 insertions(+), 64 deletions(-) create mode 100644 dao/src/test/java/org/thingsboard/server/dao/service/timeseries/nosql/TimeseriesServiceNoSqlSetNullEnabledTest.java diff --git a/dao/src/main/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDao.java b/dao/src/main/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDao.java index 31e29434e8..8d96dd293b 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDao.java @@ -65,6 +65,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Optional; +import java.util.UUID; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; @@ -117,6 +118,8 @@ public class CassandraBaseTimeseriesDao extends AbstractCassandraBaseTimeseriesD private PreparedStatement[] fetchStmtsAsc; private PreparedStatement[] fetchStmtsDesc; private PreparedStatement deleteStmt; + private PreparedStatement saveWithNullStmt; + private PreparedStatement saveWithNullWithTtlStmt; private final Lock stmtCreationLock = new ReentrantLock(); private boolean isInstall() { @@ -159,19 +162,36 @@ public class CassandraBaseTimeseriesDao extends AbstractCassandraBaseTimeseriesD ttl = computeTtl(ttl); int dataPointDays = tsKvEntry.getDataPoints() * Math.max(1, (int) (ttl / SECONDS_IN_DAY)); long partition = toPartitionTs(tsKvEntry.getTs()); + String entityType = entityId.getEntityType().name(); + UUID entityIdId = entityId.getId(); + String entryKey = tsKvEntry.getKey(); + long ts = tsKvEntry.getTs(); DataType type = tsKvEntry.getDataType(); + BoundStatementBuilder stmtBuilder; if (setNullValuesEnabled) { - processSetNullValues(tenantId, entityId, tsKvEntry, ttl, futures, partition, type); - } - BoundStatementBuilder stmtBuilder = new BoundStatementBuilder((ttl == 0 ? getSaveStmt(type) : getSaveTtlStmt(type)).bind()); - stmtBuilder.setString(0, entityId.getEntityType().name()) - .setUuid(1, entityId.getId()) - .setString(2, tsKvEntry.getKey()) - .setLong(3, partition) - .setLong(4, tsKvEntry.getTs()); - addValue(tsKvEntry, stmtBuilder, 5); - if (ttl > 0) { - stmtBuilder.setInt(6, (int) ttl); + Boolean booleanValue = tsKvEntry.getBooleanValue().orElse(null); + String strValue = tsKvEntry.getStrValue().orElse(null); + Long longValue = tsKvEntry.getLongValue().orElse(null); + Double doubleValue = tsKvEntry.getDoubleValue().orElse(null); + String jsonValue = tsKvEntry.getJsonValue().orElse(null); + if (ttl == 0) { + stmtBuilder = new BoundStatementBuilder(getSaveWithNullStmt() + .bind(entityType, entityIdId, entryKey, partition, ts, booleanValue, strValue, longValue, doubleValue, jsonValue)); + } else { + stmtBuilder = new BoundStatementBuilder(getSaveWithNullWithTtlStmt() + .bind(entityType, entityIdId, entryKey, partition, ts, booleanValue, strValue, longValue, doubleValue, jsonValue, (int) ttl)); + } + } else { + stmtBuilder = new BoundStatementBuilder((ttl == 0 ? getSaveStmt(type) : getSaveTtlStmt(type)).bind()); + stmtBuilder.setString(0, entityType) + .setUuid(1, entityIdId) + .setString(2, entryKey) + .setLong(3, partition) + .setLong(4, ts); + addValue(tsKvEntry, stmtBuilder, 5); + if (ttl > 0) { + stmtBuilder.setInt(6, (int) ttl); + } } BoundStatement stmt = stmtBuilder.build(); futures.add(getFuture(executeAsyncWrite(tenantId, stmt), rs -> null)); @@ -449,56 +469,6 @@ public class CassandraBaseTimeseriesDao extends AbstractCassandraBaseTimeseriesD return tsFormat.getTruncateUnit().equals(ChronoUnit.FOREVER); } - private void processSetNullValues(TenantId tenantId, EntityId entityId, TsKvEntry tsKvEntry, long ttl, List> futures, long partition, DataType type) { - switch (type) { - case LONG: - futures.add(saveNull(tenantId, entityId, tsKvEntry, ttl, partition, DataType.BOOLEAN)); - futures.add(saveNull(tenantId, entityId, tsKvEntry, ttl, partition, DataType.DOUBLE)); - futures.add(saveNull(tenantId, entityId, tsKvEntry, ttl, partition, DataType.STRING)); - futures.add(saveNull(tenantId, entityId, tsKvEntry, ttl, partition, DataType.JSON)); - break; - case BOOLEAN: - futures.add(saveNull(tenantId, entityId, tsKvEntry, ttl, partition, DataType.DOUBLE)); - futures.add(saveNull(tenantId, entityId, tsKvEntry, ttl, partition, DataType.LONG)); - futures.add(saveNull(tenantId, entityId, tsKvEntry, ttl, partition, DataType.STRING)); - futures.add(saveNull(tenantId, entityId, tsKvEntry, ttl, partition, DataType.JSON)); - break; - case DOUBLE: - futures.add(saveNull(tenantId, entityId, tsKvEntry, ttl, partition, DataType.BOOLEAN)); - futures.add(saveNull(tenantId, entityId, tsKvEntry, ttl, partition, DataType.LONG)); - futures.add(saveNull(tenantId, entityId, tsKvEntry, ttl, partition, DataType.STRING)); - futures.add(saveNull(tenantId, entityId, tsKvEntry, ttl, partition, DataType.JSON)); - break; - case STRING: - futures.add(saveNull(tenantId, entityId, tsKvEntry, ttl, partition, DataType.BOOLEAN)); - futures.add(saveNull(tenantId, entityId, tsKvEntry, ttl, partition, DataType.DOUBLE)); - futures.add(saveNull(tenantId, entityId, tsKvEntry, ttl, partition, DataType.LONG)); - futures.add(saveNull(tenantId, entityId, tsKvEntry, ttl, partition, DataType.JSON)); - break; - case JSON: - futures.add(saveNull(tenantId, entityId, tsKvEntry, ttl, partition, DataType.BOOLEAN)); - futures.add(saveNull(tenantId, entityId, tsKvEntry, ttl, partition, DataType.DOUBLE)); - futures.add(saveNull(tenantId, entityId, tsKvEntry, ttl, partition, DataType.LONG)); - futures.add(saveNull(tenantId, entityId, tsKvEntry, ttl, partition, DataType.STRING)); - break; - } - } - - private ListenableFuture saveNull(TenantId tenantId, EntityId entityId, TsKvEntry tsKvEntry, long ttl, long partition, DataType type) { - BoundStatementBuilder stmtBuilder = new BoundStatementBuilder((ttl == 0 ? getSaveStmt(type) : getSaveTtlStmt(type)).bind()); - stmtBuilder.setString(0, entityId.getEntityType().name()) - .setUuid(1, entityId.getId()) - .setString(2, tsKvEntry.getKey()) - .setLong(3, partition) - .setLong(4, tsKvEntry.getTs()); - stmtBuilder.setToNull(getColumnName(type)); - if (ttl > 0) { - stmtBuilder.setInt(6, (int) ttl); - } - BoundStatement stmt = stmtBuilder.build(); - return getFuture(executeAsyncWrite(tenantId, stmt), rs -> null); - } - private ListenableFuture doSavePartition(TenantId tenantId, EntityId entityId, String key, long ttl, long partition) { log.debug("Saving partition {} for the entity [{}-{}] and key {}", partition, entityId.getEntityType(), entityId.getId(), key); PreparedStatement preparedStatement = ttl == 0 ? getPartitionInsertStmt() : getPartitionInsertTtlStmt(); @@ -591,6 +561,56 @@ public class CassandraBaseTimeseriesDao extends AbstractCassandraBaseTimeseriesD return deleteStmt; } + private PreparedStatement getSaveWithNullStmt() { + if (saveWithNullStmt == null) { + stmtCreationLock.lock(); + try { + if (saveWithNullStmt == null) { + saveWithNullStmt = prepare(INSERT_INTO + ModelConstants.TS_KV_CF + + "(" + ModelConstants.ENTITY_TYPE_COLUMN + + "," + ModelConstants.ENTITY_ID_COLUMN + + "," + ModelConstants.KEY_COLUMN + + "," + ModelConstants.PARTITION_COLUMN + + "," + ModelConstants.TS_COLUMN + + "," + ModelConstants.BOOLEAN_VALUE_COLUMN + + "," + ModelConstants.STRING_VALUE_COLUMN + + "," + ModelConstants.LONG_VALUE_COLUMN + + "," + ModelConstants.DOUBLE_VALUE_COLUMN + + "," + ModelConstants.JSON_VALUE_COLUMN + ")" + + " VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"); + } + } finally { + stmtCreationLock.unlock(); + } + } + return saveWithNullStmt; + } + + private PreparedStatement getSaveWithNullWithTtlStmt() { + if (saveWithNullWithTtlStmt == null) { + stmtCreationLock.lock(); + try { + if (saveWithNullWithTtlStmt == null) { + saveWithNullWithTtlStmt = prepare(INSERT_INTO + ModelConstants.TS_KV_CF + + "(" + ModelConstants.ENTITY_TYPE_COLUMN + + "," + ModelConstants.ENTITY_ID_COLUMN + + "," + ModelConstants.KEY_COLUMN + + "," + ModelConstants.PARTITION_COLUMN + + "," + ModelConstants.TS_COLUMN + + "," + ModelConstants.BOOLEAN_VALUE_COLUMN + + "," + ModelConstants.STRING_VALUE_COLUMN + + "," + ModelConstants.LONG_VALUE_COLUMN + + "," + ModelConstants.DOUBLE_VALUE_COLUMN + + "," + ModelConstants.JSON_VALUE_COLUMN + ")" + + " VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?) USING TTL ?"); + } + } finally { + stmtCreationLock.unlock(); + } + } + return saveWithNullWithTtlStmt; + } + private PreparedStatement getSaveStmt(DataType dataType) { if (saveStmts == null) { stmtCreationLock.lock(); diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/timeseries/BaseTimeseriesServiceTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/timeseries/BaseTimeseriesServiceTest.java index ad351bb9f2..b06394e8d2 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/timeseries/BaseTimeseriesServiceTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/timeseries/BaseTimeseriesServiceTest.java @@ -33,6 +33,7 @@ import org.thingsboard.server.common.data.kv.BaseReadTsKvQuery; import org.thingsboard.server.common.data.kv.BasicTsKvEntry; import org.thingsboard.server.common.data.kv.BooleanDataEntry; import org.thingsboard.server.common.data.kv.DoubleDataEntry; +import org.thingsboard.server.common.data.kv.JsonDataEntry; import org.thingsboard.server.common.data.kv.KvEntry; import org.thingsboard.server.common.data.kv.LongDataEntry; import org.thingsboard.server.common.data.kv.ReadTsKvQuery; @@ -54,7 +55,9 @@ import java.util.concurrent.TimeoutException; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; /** * @author Andrew Shvayka @@ -64,12 +67,12 @@ import static org.junit.Assert.assertNotNull; public abstract class BaseTimeseriesServiceTest extends AbstractServiceTest { @Autowired - TimeseriesService tsService; + protected TimeseriesService tsService; @Autowired EntityViewService entityViewService; - static final int MAX_TIMEOUT = 30; + protected static final int MAX_TIMEOUT = 30; private static final String STRING_KEY = "stringKey"; private static final String LONG_KEY = "longKey"; @@ -84,7 +87,7 @@ public abstract class BaseTimeseriesServiceTest extends AbstractServiceTest { KvEntry doubleKvEntry = new DoubleDataEntry(DOUBLE_KEY, Double.MAX_VALUE); KvEntry booleanKvEntry = new BooleanDataEntry(BOOLEAN_KEY, Boolean.TRUE); - private TenantId tenantId; + protected TenantId tenantId; @Before public void before() { @@ -673,6 +676,29 @@ public abstract class BaseTimeseriesServiceTest extends AbstractServiceTest { assertEquals(3, list.size()); } + @Test + public void shouldSaveEntryOfEachType() throws Exception { + List timeseries = List.of( + new BasicTsKvEntry(TimeUnit.MINUTES.toMillis(1), new BooleanDataEntry("test", true)), + new BasicTsKvEntry(TimeUnit.MINUTES.toMillis(2), new StringDataEntry("test", "text")), + new BasicTsKvEntry(TimeUnit.MINUTES.toMillis(3), new LongDataEntry("test", 15L)), + new BasicTsKvEntry(TimeUnit.MINUTES.toMillis(4), new DoubleDataEntry("test", 10.5)), + new BasicTsKvEntry(TimeUnit.MINUTES.toMillis(5), new JsonDataEntry("test", "{\"test\":\"testValue\"}"))); + + DeviceId deviceId = new DeviceId(Uuids.timeBased()); + for (TsKvEntry tsKvEntry : timeseries) { + save(tenantId, deviceId, tsKvEntry); + } + + List listUntil3Minutes = tsService.findAll(tenantId, deviceId, Collections.singletonList(new BaseReadTsKvQuery("test", 0L, + TimeUnit.MINUTES.toMillis(3), 1000, 10, Aggregation.NONE))).get(MAX_TIMEOUT, TimeUnit.SECONDS); + assertEquals(2, listUntil3Minutes.size()); + + List fullList = tsService.findAll(tenantId, deviceId, Collections.singletonList(new BaseReadTsKvQuery("test", 0L, + TimeUnit.MINUTES.toMillis(6), 1000, 10, Aggregation.NONE))).get(MAX_TIMEOUT, TimeUnit.SECONDS); + assertEquals(5, fullList.size()); + } + private TsKvEntry save(DeviceId deviceId, long ts, long value) throws Exception { TsKvEntry entry = new BasicTsKvEntry(ts, new LongDataEntry(LONG_KEY, value)); tsService.save(tenantId, deviceId, entry).get(MAX_TIMEOUT, TimeUnit.SECONDS); @@ -691,6 +717,9 @@ public abstract class BaseTimeseriesServiceTest extends AbstractServiceTest { return entry; } + private void save(TenantId tenantId, DeviceId deviceId, TsKvEntry tsKvEntry) throws Exception { + tsService.save(tenantId, deviceId, tsKvEntry).get(MAX_TIMEOUT, TimeUnit.SECONDS); + } private void saveEntries(DeviceId deviceId, long ts) throws ExecutionException, InterruptedException, TimeoutException { tsService.save(tenantId, deviceId, toTsEntry(ts, stringKvEntry)).get(MAX_TIMEOUT, TimeUnit.SECONDS); diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/timeseries/nosql/TimeseriesServiceNoSqlSetNullEnabledTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/timeseries/nosql/TimeseriesServiceNoSqlSetNullEnabledTest.java new file mode 100644 index 0000000000..1bbb37659c --- /dev/null +++ b/dao/src/test/java/org/thingsboard/server/dao/service/timeseries/nosql/TimeseriesServiceNoSqlSetNullEnabledTest.java @@ -0,0 +1,72 @@ +/** + * Copyright © 2016-2024 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.server.dao.service.timeseries.nosql; + +import com.datastax.oss.driver.api.core.uuid.Uuids; +import org.junit.Test; +import org.springframework.test.context.TestPropertySource; +import org.thingsboard.server.common.data.id.DeviceId; +import org.thingsboard.server.common.data.kv.Aggregation; +import org.thingsboard.server.common.data.kv.BaseReadTsKvQuery; +import org.thingsboard.server.common.data.kv.BasicTsKvEntry; +import org.thingsboard.server.common.data.kv.DoubleDataEntry; +import org.thingsboard.server.common.data.kv.LongDataEntry; +import org.thingsboard.server.common.data.kv.TsKvEntry; +import org.thingsboard.server.dao.service.DaoNoSqlTest; + +import java.util.Collections; +import java.util.List; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +@DaoNoSqlTest +@TestPropertySource(properties = { + "cassandra.query.set_null_values_enabled=true", +}) +public class TimeseriesServiceNoSqlSetNullEnabledTest extends TimeseriesServiceNoSqlTest { + + @Override + @Test + public void testNullValuesOfNoneTargetColumn() throws ExecutionException, InterruptedException, TimeoutException { + long ts = TimeUnit.MINUTES.toMillis(1); + TsKvEntry longEntry = new BasicTsKvEntry(ts, new LongDataEntry("temp", 0L)); + double doubleValue = 20.6; + TsKvEntry doubleEntry = new BasicTsKvEntry(ts, new DoubleDataEntry("temp", doubleValue)); + DeviceId deviceId = new DeviceId(Uuids.timeBased()); + tsService.save(tenantId, deviceId, longEntry).get(MAX_TIMEOUT, TimeUnit.SECONDS); + tsService.save(tenantId, deviceId, doubleEntry).get(MAX_TIMEOUT, TimeUnit.SECONDS); + + List listWithoutAgg = tsService.findAll(tenantId, deviceId, Collections.singletonList(new BaseReadTsKvQuery("temp", 0L, + ts + 1 , 1000, 3, Aggregation.NONE))).get(MAX_TIMEOUT, TimeUnit.SECONDS); + assertEquals(1, listWithoutAgg.size()); + assertFalse(listWithoutAgg.get(0).getLongValue().isPresent()); + assertTrue(listWithoutAgg.get(0).getDoubleValue().isPresent()); + assertThat(listWithoutAgg.get(0).getDoubleValue().get()).isEqualTo(doubleValue); + + // long value should be set to null after second insert, so avg = doubleValue + List listWithAgg = tsService.findAll(tenantId, deviceId, Collections.singletonList(new BaseReadTsKvQuery("temp", 0L, + ts + 1 , 1000, 3, Aggregation.AVG))).get(MAX_TIMEOUT, TimeUnit.SECONDS); + assertEquals(1, listWithAgg.size()); + assertTrue(listWithAgg.get(0).getDoubleValue().isPresent()); + assertThat(listWithAgg.get(0).getDoubleValue().get()).isEqualTo(doubleValue); + } +} diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/timeseries/nosql/TimeseriesServiceNoSqlTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/timeseries/nosql/TimeseriesServiceNoSqlTest.java index 229d5f5842..82916aad1c 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/timeseries/nosql/TimeseriesServiceNoSqlTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/timeseries/nosql/TimeseriesServiceNoSqlTest.java @@ -15,9 +15,105 @@ */ package org.thingsboard.server.dao.service.timeseries.nosql; +import com.datastax.oss.driver.api.core.uuid.Uuids; +import org.junit.Test; +import org.thingsboard.server.common.data.id.DeviceId; +import org.thingsboard.server.common.data.kv.Aggregation; +import org.thingsboard.server.common.data.kv.BaseReadTsKvQuery; +import org.thingsboard.server.common.data.kv.BasicTsKvEntry; +import org.thingsboard.server.common.data.kv.BooleanDataEntry; +import org.thingsboard.server.common.data.kv.DoubleDataEntry; +import org.thingsboard.server.common.data.kv.JsonDataEntry; +import org.thingsboard.server.common.data.kv.LongDataEntry; +import org.thingsboard.server.common.data.kv.StringDataEntry; +import org.thingsboard.server.common.data.kv.TsKvEntry; import org.thingsboard.server.dao.service.DaoNoSqlTest; import org.thingsboard.server.dao.service.timeseries.BaseTimeseriesServiceTest; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + @DaoNoSqlTest public class TimeseriesServiceNoSqlTest extends BaseTimeseriesServiceTest { + + @Test + public void shouldSaveEntryOfEachTypeWithTtl() throws ExecutionException, InterruptedException, TimeoutException { + long ttlInSec = TimeUnit.SECONDS.toSeconds(3); + List timeseries = List.of( + new BasicTsKvEntry(TimeUnit.MINUTES.toMillis(1), new BooleanDataEntry("test", true)), + new BasicTsKvEntry(TimeUnit.MINUTES.toMillis(2), new StringDataEntry("test", "text")), + new BasicTsKvEntry(TimeUnit.MINUTES.toMillis(3), new LongDataEntry("test", 15L)), + new BasicTsKvEntry(TimeUnit.MINUTES.toMillis(4), new DoubleDataEntry("test", 10.5)), + new BasicTsKvEntry(TimeUnit.MINUTES.toMillis(5), new JsonDataEntry("test", "{\"test\":\"testValue\"}"))); + + DeviceId deviceId = new DeviceId(Uuids.timeBased()); + tsService.save(tenantId, deviceId, timeseries, ttlInSec); + + List fullList = tsService.findAll(tenantId, deviceId, Collections.singletonList(new BaseReadTsKvQuery("test", 0L, + TimeUnit.MINUTES.toMillis(6), 1000, 10, Aggregation.NONE))).get(MAX_TIMEOUT, TimeUnit.SECONDS); + assertEquals(5, fullList.size()); + + // check entries after ttl + Thread.sleep(TimeUnit.SECONDS.toMillis(ttlInSec)); + List listAfterTtl = tsService.findAll(tenantId, deviceId, Collections.singletonList(new BaseReadTsKvQuery("test", 0L, + TimeUnit.MINUTES.toMillis(6), 1000, 10, Aggregation.NONE))).get(MAX_TIMEOUT, TimeUnit.SECONDS); + assertEquals(0, listAfterTtl.size()); + } + + @Test + public void shouldDeleteValueAfterTtl() throws ExecutionException, InterruptedException, TimeoutException { + long longEntryTs = TimeUnit.MINUTES.toMillis(2); + long doubleEntryTs = TimeUnit.MINUTES.toMillis(3); + long ttlInSec = TimeUnit.SECONDS.toSeconds(3); + long longValue = 0L; + TsKvEntry longEntry = new BasicTsKvEntry(longEntryTs, new LongDataEntry("temp", longValue)); + double doubleValue = 20.6; + TsKvEntry doubleEntry = new BasicTsKvEntry(doubleEntryTs, new DoubleDataEntry("temp", doubleValue)); + DeviceId deviceId = new DeviceId(Uuids.timeBased()); + tsService.save(tenantId, deviceId, longEntry).get(MAX_TIMEOUT, TimeUnit.SECONDS); + tsService.save(tenantId, deviceId, Collections.singletonList(doubleEntry), ttlInSec).get(MAX_TIMEOUT, TimeUnit.SECONDS); + + Thread.sleep(TimeUnit.SECONDS.toMillis(ttlInSec)); + List listAfterTtl = tsService.findAll(tenantId, deviceId, Collections.singletonList(new BaseReadTsKvQuery("temp", 0L, + doubleEntryTs + 1 , 1000, 3, Aggregation.NONE))).get(MAX_TIMEOUT, TimeUnit.SECONDS); + assertEquals(1, listAfterTtl.size()); + assertTrue(listAfterTtl.get(0).getLongValue().isPresent()); + assertThat(listAfterTtl.get(0).getLongValue().get()).isEqualTo(longValue); + assertFalse(listAfterTtl.get(0).getDoubleValue().isPresent()); + } + + @Test + public void testNullValuesOfNoneTargetColumn() throws ExecutionException, InterruptedException, TimeoutException { + long ts = TimeUnit.MINUTES.toMillis(1); + long longValue = 10L; + TsKvEntry longEntry = new BasicTsKvEntry(ts, new LongDataEntry("temp", longValue)); + double doubleValue = 20.6; + TsKvEntry doubleEntry = new BasicTsKvEntry(ts, new DoubleDataEntry("temp", doubleValue)); + DeviceId deviceId = new DeviceId(Uuids.timeBased()); + tsService.save(tenantId, deviceId, longEntry).get(MAX_TIMEOUT, TimeUnit.SECONDS); + tsService.save(tenantId, deviceId, doubleEntry).get(MAX_TIMEOUT, TimeUnit.SECONDS); + + List listWithoutAgg = tsService.findAll(tenantId, deviceId, Collections.singletonList(new BaseReadTsKvQuery("temp", 0L, + ts + 1 , 1000, 3, Aggregation.NONE))).get(MAX_TIMEOUT, TimeUnit.SECONDS); + assertEquals(1, listWithoutAgg.size()); + assertTrue(listWithoutAgg.get(0).getLongValue().isPresent()); + assertFalse(listWithoutAgg.get(0).getDoubleValue().isPresent()); + assertThat(listWithoutAgg.get(0).getLongValue().get()).isEqualTo(longValue); + + // long value should not be reset to null, so avg = (doubleValue + longValue)/ 2 + List listWithAgg = tsService.findAll(tenantId, deviceId, Collections.singletonList(new BaseReadTsKvQuery("temp", 0L, + ts + 1, 200000, 3, Aggregation.AVG))).get(MAX_TIMEOUT, TimeUnit.SECONDS); + assertEquals(1, listWithAgg.size()); + assertTrue(listWithAgg.get(0).getDoubleValue().isPresent()); + double expectedValue = (doubleValue + longValue)/ 2; + assertThat(listWithAgg.get(0).getDoubleValue().get()).isEqualTo(expectedValue); + } } From 9fa357735a7a327082e32dd883e79f63220453c5 Mon Sep 17 00:00:00 2001 From: dashevchenko Date: Fri, 2 Feb 2024 15:55:18 +0200 Subject: [PATCH 159/179] timeseries test improvements --- .../timeseries/BaseTimeseriesServiceTest.java | 15 +++++++----- .../nosql/TimeseriesServiceNoSqlTest.java | 24 +------------------ 2 files changed, 10 insertions(+), 29 deletions(-) diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/timeseries/BaseTimeseriesServiceTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/timeseries/BaseTimeseriesServiceTest.java index b06394e8d2..a624a2b6e5 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/timeseries/BaseTimeseriesServiceTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/timeseries/BaseTimeseriesServiceTest.java @@ -678,12 +678,12 @@ public abstract class BaseTimeseriesServiceTest extends AbstractServiceTest { @Test public void shouldSaveEntryOfEachType() throws Exception { - List timeseries = List.of( - new BasicTsKvEntry(TimeUnit.MINUTES.toMillis(1), new BooleanDataEntry("test", true)), - new BasicTsKvEntry(TimeUnit.MINUTES.toMillis(2), new StringDataEntry("test", "text")), - new BasicTsKvEntry(TimeUnit.MINUTES.toMillis(3), new LongDataEntry("test", 15L)), - new BasicTsKvEntry(TimeUnit.MINUTES.toMillis(4), new DoubleDataEntry("test", 10.5)), - new BasicTsKvEntry(TimeUnit.MINUTES.toMillis(5), new JsonDataEntry("test", "{\"test\":\"testValue\"}"))); + BasicTsKvEntry booleanEntry = new BasicTsKvEntry(TimeUnit.MINUTES.toMillis(1), new BooleanDataEntry("test", true)); + BasicTsKvEntry stringEntry = new BasicTsKvEntry(TimeUnit.MINUTES.toMillis(2), new StringDataEntry("test", "text")); + BasicTsKvEntry longEntry = new BasicTsKvEntry(TimeUnit.MINUTES.toMillis(3), new LongDataEntry("test", 15L)); + BasicTsKvEntry doubleEntry = new BasicTsKvEntry(TimeUnit.MINUTES.toMillis(4), new DoubleDataEntry("test", 10.5)); + BasicTsKvEntry jsonEntry = new BasicTsKvEntry(TimeUnit.MINUTES.toMillis(5), new JsonDataEntry("test", "{\"test\":\"testValue\"}")); + List timeseries = List.of(booleanEntry, stringEntry, longEntry, doubleEntry, jsonEntry); DeviceId deviceId = new DeviceId(Uuids.timeBased()); for (TsKvEntry tsKvEntry : timeseries) { @@ -693,10 +693,13 @@ public abstract class BaseTimeseriesServiceTest extends AbstractServiceTest { List listUntil3Minutes = tsService.findAll(tenantId, deviceId, Collections.singletonList(new BaseReadTsKvQuery("test", 0L, TimeUnit.MINUTES.toMillis(3), 1000, 10, Aggregation.NONE))).get(MAX_TIMEOUT, TimeUnit.SECONDS); assertEquals(2, listUntil3Minutes.size()); + assertThat(listUntil3Minutes).containsOnlyOnceElementsOf(List.of( + booleanEntry, stringEntry)); List fullList = tsService.findAll(tenantId, deviceId, Collections.singletonList(new BaseReadTsKvQuery("test", 0L, TimeUnit.MINUTES.toMillis(6), 1000, 10, Aggregation.NONE))).get(MAX_TIMEOUT, TimeUnit.SECONDS); assertEquals(5, fullList.size()); + assertThat(fullList).containsOnlyOnceElementsOf(timeseries); } private TsKvEntry save(DeviceId deviceId, long ts, long value) throws Exception { diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/timeseries/nosql/TimeseriesServiceNoSqlTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/timeseries/nosql/TimeseriesServiceNoSqlTest.java index 82916aad1c..b8970feca3 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/timeseries/nosql/TimeseriesServiceNoSqlTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/timeseries/nosql/TimeseriesServiceNoSqlTest.java @@ -62,34 +62,12 @@ public class TimeseriesServiceNoSqlTest extends BaseTimeseriesServiceTest { assertEquals(5, fullList.size()); // check entries after ttl - Thread.sleep(TimeUnit.SECONDS.toMillis(ttlInSec)); + Thread.sleep(TimeUnit.SECONDS.toMillis(ttlInSec + 1)); List listAfterTtl = tsService.findAll(tenantId, deviceId, Collections.singletonList(new BaseReadTsKvQuery("test", 0L, TimeUnit.MINUTES.toMillis(6), 1000, 10, Aggregation.NONE))).get(MAX_TIMEOUT, TimeUnit.SECONDS); assertEquals(0, listAfterTtl.size()); } - @Test - public void shouldDeleteValueAfterTtl() throws ExecutionException, InterruptedException, TimeoutException { - long longEntryTs = TimeUnit.MINUTES.toMillis(2); - long doubleEntryTs = TimeUnit.MINUTES.toMillis(3); - long ttlInSec = TimeUnit.SECONDS.toSeconds(3); - long longValue = 0L; - TsKvEntry longEntry = new BasicTsKvEntry(longEntryTs, new LongDataEntry("temp", longValue)); - double doubleValue = 20.6; - TsKvEntry doubleEntry = new BasicTsKvEntry(doubleEntryTs, new DoubleDataEntry("temp", doubleValue)); - DeviceId deviceId = new DeviceId(Uuids.timeBased()); - tsService.save(tenantId, deviceId, longEntry).get(MAX_TIMEOUT, TimeUnit.SECONDS); - tsService.save(tenantId, deviceId, Collections.singletonList(doubleEntry), ttlInSec).get(MAX_TIMEOUT, TimeUnit.SECONDS); - - Thread.sleep(TimeUnit.SECONDS.toMillis(ttlInSec)); - List listAfterTtl = tsService.findAll(tenantId, deviceId, Collections.singletonList(new BaseReadTsKvQuery("temp", 0L, - doubleEntryTs + 1 , 1000, 3, Aggregation.NONE))).get(MAX_TIMEOUT, TimeUnit.SECONDS); - assertEquals(1, listAfterTtl.size()); - assertTrue(listAfterTtl.get(0).getLongValue().isPresent()); - assertThat(listAfterTtl.get(0).getLongValue().get()).isEqualTo(longValue); - assertFalse(listAfterTtl.get(0).getDoubleValue().isPresent()); - } - @Test public void testNullValuesOfNoneTargetColumn() throws ExecutionException, InterruptedException, TimeoutException { long ts = TimeUnit.MINUTES.toMillis(1); From ba600a8bd88d2ad3fdef71a0065497573909f781 Mon Sep 17 00:00:00 2001 From: Igor Kulikov Date: Fri, 2 Feb 2024 18:27:54 +0200 Subject: [PATCH 160/179] UI: Widget button color calculations improvements. Improve color picker panel overflow. --- .../widget/config/data-keys.component.ts | 2 +- .../button/widget-button.component.scss | 8 +++---- .../components/button/widget-button.models.ts | 22 ++++++++++++++----- .../components/color-input.component.ts | 2 +- .../color-picker/color-picker.component.scss | 2 ++ 5 files changed, 25 insertions(+), 11 deletions(-) diff --git a/ui-ngx/src/app/modules/home/components/widget/config/data-keys.component.ts b/ui-ngx/src/app/modules/home/components/widget/config/data-keys.component.ts index 63647fc604..800c831b67 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/data-keys.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/config/data-keys.component.ts @@ -521,7 +521,7 @@ export class DataKeysComponent implements ControlValueAccessor, OnInit, OnChange this.popoverService.hidePopover(trigger); } else { const colorPickerPopover = this.popoverService.displayPopover(trigger, this.renderer, - this.viewContainerRef, ColorPickerPanelComponent, 'left', true, null, + this.viewContainerRef, ColorPickerPanelComponent, ['leftTopOnly', 'leftOnly', 'leftBottomOnly'], true, null, { color: key.color }, diff --git a/ui-ngx/src/app/shared/components/button/widget-button.component.scss b/ui-ngx/src/app/shared/components/button/widget-button.component.scss index 06c875de7f..546a3bed19 100644 --- a/ui-ngx/src/app/shared/components/button/widget-button.component.scss +++ b/ui-ngx/src/app/shared/components/button/widget-button.component.scss @@ -28,19 +28,19 @@ $boxShadowColorEnabled: var(--tb-widget-button-box-shadow-color-enabled, $defaul $mainColorHovered: var(--tb-widget-button-main-color-hovered, $defaultMainColor); $backgroundColorHovered: var(--tb-widget-button-background-color-hovered, $defaultBackgroundColor); $boxShadowColorHovered: var(--tb-widget-button-box-shadow-color-hovered, $defaultBoxShadowColor); -$mainColorHoveredFilled: var(--tb-widget-button-main-color-hovered-filled, #263BD7); // main.darken(6) +$mainColorHoveredFilled: var(--tb-widget-button-main-color-hovered-filled, #3347db); // main.darken(6) $mainColorPressed: var(--tb-widget-button-main-color-pressed, $defaultMainColor); $backgroundColorPressed: var(--tb-widget-button-background-color-pressed, $defaultBackgroundColor); $boxShadowColorPressed: var(--tb-widget-button-box-shadow-color-pressed, $defaultBoxShadowColor); -$mainColorPressedFilled: var(--tb-widget-button-main-color-pressed-filled, #2234BD); // main.darken(12) +$mainColorPressedFilled: var(--tb-widget-button-main-color-pressed-filled, #273cd9); // main.darken(12) $mainColorPressedRipple: var(--tb-widget-button-main-color-pressed-ripple, rgba(63, 82, 221, 0.1)); // Alpha(Main, 0.1) -$mainColorPressedRippleFilled: var(--tb-widget-button-main-color-pressed-ripple-filled, #1D2DA3); // main.darken(18) +$mainColorPressedRippleFilled: var(--tb-widget-button-main-color-pressed-ripple-filled, #2439cd); // main.darken(18) $mainColorActivated: var(--tb-widget-button-main-color-activated, $defaultMainColor); $backgroundColorActivated: var(--tb-widget-button-background-color-activated, $defaultBackgroundColor); $boxShadowColorActivated: var(--tb-widget-button-box-shadow-color-activated, $defaultBoxShadowColor); -$mainColorActivatedFilled: var(--tb-widget-button-main-color-activated-filled, #2234BD); // main.darken(12) +$mainColorActivatedFilled: var(--tb-widget-button-main-color-activated-filled, #273cd9); // main.darken(12) $mainColorDisabled: var(--tb-widget-button-main-color-disabled, $defaultMainColorDisabled); $backgroundColorDisabled: var(--tb-widget-button-background-color-disabled, $defaultBackgroundColorDisabled); diff --git a/ui-ngx/src/app/shared/components/button/widget-button.models.ts b/ui-ngx/src/app/shared/components/button/widget-button.models.ts index 616af28588..34f13864a9 100644 --- a/ui-ngx/src/app/shared/components/button/widget-button.models.ts +++ b/ui-ngx/src/app/shared/components/button/widget-button.models.ts @@ -20,6 +20,11 @@ import tinycolor from 'tinycolor2'; const defaultMainColor = '#3F52DD'; const defaultBackgroundColor = '#FFFFFF'; +const hoveredFilledDarkenAmount = 6; +const pressedFilledDarkenAmount = 12; +const activatedFilledDarkenAmount = 12; +const pressedRippleFilledDarkenAmount = 18; + export const defaultMainColorDisabled = 'rgba(0, 0, 0, 0.38)'; export const defaultBackgroundColorDisabled = 'rgba(0, 0, 0, 0.03)'; @@ -181,7 +186,7 @@ class HoveredButtonStateCssGenerator extends ButtonStateCssGenerator { } protected generateAdditionalStateCss(mainColor: string): string { - const mainColorHoveredFilled = darkenColor(mainColor, 6); + const mainColorHoveredFilled = darkenColor(mainColor, hoveredFilledDarkenAmount); return `--tb-widget-button-main-color-hovered-filled: ${mainColorHoveredFilled};`; } } @@ -193,10 +198,10 @@ class PressedButtonStateCssGenerator extends ButtonStateCssGenerator { } protected generateAdditionalStateCss(mainColor: string): string { - const mainColorPressedFilled = darkenColor(mainColor, 12); + const mainColorPressedFilled = darkenColor(mainColor, pressedFilledDarkenAmount); const mainColorInstance = tinycolor(mainColor); const mainColorPressedRipple = mainColorInstance.setAlpha(mainColorInstance.getAlpha() * 0.1).toRgbString(); - const mainColorPressedRippleFilled = darkenColor(mainColor, 18); + const mainColorPressedRippleFilled = darkenColor(mainColor, pressedRippleFilledDarkenAmount); return `--tb-widget-button-main-color-pressed-filled: ${mainColorPressedFilled};\n`+ `--tb-widget-button-main-color-pressed-ripple: ${mainColorPressedRipple};\n`+ `--tb-widget-button-main-color-pressed-ripple-filled: ${mainColorPressedRippleFilled};`; @@ -210,7 +215,7 @@ class ActivatedButtonStateCssGenerator extends ButtonStateCssGenerator { } protected generateAdditionalStateCss(mainColor: string): string { - const mainColorActivatedFilled = darkenColor(mainColor, 12); + const mainColorActivatedFilled = darkenColor(mainColor, activatedFilledDarkenAmount); return `--tb-widget-button-main-color-activated-filled: ${mainColorActivatedFilled};`; } } @@ -255,5 +260,12 @@ export const generateWidgetButtonAppearanceCss = (appearance: WidgetButtonAppear const darkenColor = (inputColor: string, amount: number): string => { const input = tinycolor(inputColor); - return input.darken(amount).toRgbString(); + const brightness = input.getBrightness() / 255; + let ratio: number; + if (brightness >= 0.4 && brightness <= 0.5) { + ratio = brightness + 0.2; + } else { + ratio = Math.max(0.1, Math.log10(brightness * 8)); + } + return input.darken(ratio * amount).toRgbString(); }; diff --git a/ui-ngx/src/app/shared/components/color-input.component.ts b/ui-ngx/src/app/shared/components/color-input.component.ts index 171e8bf7d8..ad772ba861 100644 --- a/ui-ngx/src/app/shared/components/color-input.component.ts +++ b/ui-ngx/src/app/shared/components/color-input.component.ts @@ -189,7 +189,7 @@ export class ColorInputComponent extends PageComponent implements OnInit, Contro this.popoverService.hidePopover(trigger); } else { const colorPickerPopover = this.popoverService.displayPopover(trigger, this.renderer, - this.viewContainerRef, ColorPickerPanelComponent, 'left', true, null, + this.viewContainerRef, ColorPickerPanelComponent, ['leftTopOnly', 'leftOnly', 'leftBottomOnly'], true, null, { color: this.colorFormGroup.get('color').value, colorClearButton: this.colorClearButton diff --git a/ui-ngx/src/app/shared/components/color-picker/color-picker.component.scss b/ui-ngx/src/app/shared/components/color-picker/color-picker.component.scss index c55222a7d2..9aca580994 100644 --- a/ui-ngx/src/app/shared/components/color-picker/color-picker.component.scss +++ b/ui-ngx/src/app/shared/components/color-picker/color-picker.component.scss @@ -18,9 +18,11 @@ display: flex; flex-direction: column; gap: 32px; + overflow: auto; .saturation-component { height: 238px; + min-height: 80px; border-radius: 8px; } From 8262be6e6451673e4ebd35988585193a82dcb871 Mon Sep 17 00:00:00 2001 From: Igor Kulikov Date: Mon, 5 Feb 2024 15:10:37 +0200 Subject: [PATCH 161/179] UI: Single switch widget improvements: Implement disabled state. Improve auto-scale. --- .../single-switch-basic-config.component.html | 11 ++++ .../single-switch-basic-config.component.ts | 2 + .../rpc/single-switch-widget.component.html | 6 +-- .../rpc/single-switch-widget.component.scss | 8 +-- .../lib/rpc/single-switch-widget.component.ts | 54 +++++++++++++++++-- .../lib/rpc/single-switch-widget.models.ts | 17 ++++++ ...ngle-switch-widget-settings.component.html | 11 ++++ ...single-switch-widget-settings.component.ts | 3 +- .../assets/locale/locale.constant-en_US.json | 5 +- 9 files changed, 105 insertions(+), 12 deletions(-) diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/rpc/single-switch-basic-config.component.html b/ui-ngx/src/app/modules/home/components/widget/config/basic/rpc/single-switch-basic-config.component.html index 4ac5934e93..df495e32df 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/basic/rpc/single-switch-basic-config.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/rpc/single-switch-basic-config.component.html @@ -52,6 +52,17 @@ [widgetType]="widgetType" formControlName="offUpdateState">
+
+
widgets.rpc-state.disabled-state
+ +
widget-config.appearance
diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/rpc/single-switch-basic-config.component.ts b/ui-ngx/src/app/modules/home/components/widget/config/basic/rpc/single-switch-basic-config.component.ts index 82c2766a23..75c93bc852 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/basic/rpc/single-switch-basic-config.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/rpc/single-switch-basic-config.component.ts @@ -70,6 +70,7 @@ export class SingleSwitchBasicConfigComponent extends BasicWidgetConfigComponent initialState: [settings.initialState, []], onUpdateState: [settings.onUpdateState, []], offUpdateState: [settings.offUpdateState, []], + disabledState: [settings.disabledState, []], layout: [settings.layout, []], autoScale: [settings.autoScale, []], @@ -120,6 +121,7 @@ export class SingleSwitchBasicConfigComponent extends BasicWidgetConfigComponent this.widgetConfig.config.settings.initialState = config.initialState; this.widgetConfig.config.settings.onUpdateState = config.onUpdateState; this.widgetConfig.config.settings.offUpdateState = config.offUpdateState; + this.widgetConfig.config.settings.disabledState = config.disabledState; this.widgetConfig.config.settings.layout = config.layout; this.widgetConfig.config.settings.autoScale = config.autoScale; diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/rpc/single-switch-widget.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/rpc/single-switch-widget.component.html index 5f085ff7b5..879902a3ef 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/rpc/single-switch-widget.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/rpc/single-switch-widget.component.html @@ -15,8 +15,8 @@ limitations under the License. --> -
-
+
+
@@ -27,7 +27,7 @@
{{ offLabel }}
- +
{{ onLabel }}
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/rpc/single-switch-widget.component.scss b/ui-ngx/src/app/modules/home/components/widget/lib/rpc/single-switch-widget.component.scss index 92c8f87f09..bb5648a16d 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/rpc/single-switch-widget.component.scss +++ b/ui-ngx/src/app/modules/home/components/widget/lib/rpc/single-switch-widget.component.scss @@ -29,15 +29,15 @@ $switchColorDisabled: var(--tb-single-switch-color-disabled, #D5D7E5); align-items: center; justify-content: center; padding: 18px 24px; + &.auto-scale { + padding: 0; + } > div:not(.tb-single-switch-overlay), > tb-icon { z-index: 1; } .tb-single-switch-overlay { position: absolute; - top: 12px; - left: 12px; - bottom: 12px; - right: 12px; + inset: 12px; } .tb-single-switch-progress { position: absolute; diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/rpc/single-switch-widget.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/rpc/single-switch-widget.component.ts index 1a7274c5b6..1103afde39 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/rpc/single-switch-widget.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/rpc/single-switch-widget.component.ts @@ -45,6 +45,7 @@ import { DomSanitizer } from '@angular/platform-browser'; import { ValueType } from '@shared/models/constants'; import { UtilsService } from '@core/services/utils.service'; +const initialSwitchHeight = 60; const horizontalLayoutPadding = 48; const verticalLayoutPadding = 36; @@ -73,8 +74,10 @@ export class SingleSwitchWidgetComponent extends backgroundStyle$: Observable; overlayStyle: ComponentStyle = {}; + overlayInset = '12px'; value = false; + disabled = false; layout: SingleSwitchLayout; @@ -159,6 +162,12 @@ export class SingleSwitchWidgetComponent extends next: (value) => this.onValue(value) }); + const disabledStateSettings = + {...this.settings.disabledState, actionLabel: this.ctx.translate.instant('widgets.rpc-state.disabled-state')}; + this.createValueGetter(disabledStateSettings, ValueType.BOOLEAN, { + next: (value) => this.onDisabled(value) + }); + const onUpdateStateSettings = {...this.settings.onUpdateState, actionLabel: this.ctx.translate.instant('widgets.rpc-state.turn-on')}; this.onValueSetter = this.createValueSetter(onUpdateStateSettings); @@ -216,20 +225,59 @@ export class SingleSwitchWidgetComponent extends this.cd.markForCheck(); } + private onDisabled(value: boolean): void { + this.disabled = !!value; + if (this.disabled) { + if (this.showLabel) { + this.labelStyle = {...this.labelStyle, color: 'rgba(0, 0, 0, 0.38)'}; + } + if (this.showIcon) { + this.iconStyle = {...this.iconStyle, color: 'rgba(0, 0, 0, 0.38)'}; + } + if (this.showOnLabel) { + this.onLabelStyle = {...this.onLabelStyle, color: 'rgba(0, 0, 0, 0.38)'}; + } + if (this.showOffLabel) { + this.offLabelStyle = {...this.offLabelStyle, color: 'rgba(0, 0, 0, 0.38)'}; + } + } else { + if (this.showLabel) { + this.labelStyle = {...this.labelStyle, color: this.settings.labelColor}; + } + if (this.showIcon) { + this.iconStyle = {...this.iconStyle, color: this.settings.iconColor}; + } + if (this.showOnLabel) { + this.onLabelStyle = {...this.onLabelStyle, color: this.settings.onLabelColor}; + } + if (this.showOffLabel) { + this.offLabelStyle = {...this.offLabelStyle, color: this.settings.offLabelColor}; + } + } + this.cd.markForCheck(); + } + private onResize() { - const panelWidth = this.singleSwitchPanel.nativeElement.getBoundingClientRect().width - horizontalLayoutPadding; - const panelHeight = this.singleSwitchPanel.nativeElement.getBoundingClientRect().height - verticalLayoutPadding; + const height = this.singleSwitchPanel.nativeElement.getBoundingClientRect().height; + const switchScale = height / initialSwitchHeight; + const paddingScale = Math.min(switchScale, 1); + const panelWidth = this.singleSwitchPanel.nativeElement.getBoundingClientRect().width - (horizontalLayoutPadding * paddingScale); + const panelHeight = this.singleSwitchPanel.nativeElement.getBoundingClientRect().height - (verticalLayoutPadding * paddingScale); this.renderer.setStyle(this.singleSwitchContent.nativeElement, 'transform', `scale(1)`); + this.renderer.setStyle(this.singleSwitchContent.nativeElement, 'width', 'auto'); let contentWidth = this.singleSwitchToggleRow.nativeElement.getBoundingClientRect().width; let contentHeight = this.singleSwitchToggleRow.nativeElement.getBoundingClientRect().height; if (this.showIcon || this.showLabel) { contentWidth += (8 + this.singleSwitchLabelRow.nativeElement.getBoundingClientRect().width); contentHeight = Math.max(contentHeight, this.singleSwitchLabelRow.nativeElement.getBoundingClientRect().height); } - const scale = Math.min(panelWidth / contentWidth, panelHeight / contentHeight); + const maxScale = Math.max(1, switchScale); + const scale = Math.min(Math.min(panelWidth / contentWidth, panelHeight / contentHeight), maxScale); const width = panelWidth / scale; this.renderer.setStyle(this.singleSwitchContent.nativeElement, 'width', width + 'px'); this.renderer.setStyle(this.singleSwitchContent.nativeElement, 'transform', `scale(${scale})`); + this.overlayInset = (Math.floor(12 * paddingScale * 100) / 100) + 'px'; + this.cd.markForCheck(); } } diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/rpc/single-switch-widget.models.ts b/ui-ngx/src/app/modules/home/components/widget/lib/rpc/single-switch-widget.models.ts index 4f0401b3bd..7897574cac 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/rpc/single-switch-widget.models.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/rpc/single-switch-widget.models.ts @@ -51,6 +51,7 @@ export const singleSwitchLayoutImages = new Map( export interface SingleSwitchWidgetSettings { initialState: GetValueSettings; + disabledState: GetValueSettings; onUpdateState: SetValueSettings; offUpdateState: SetValueSettings; layout: SingleSwitchLayout; @@ -104,6 +105,22 @@ export const singleSwitchDefaultSettings: SingleSwitchWidgetSettings = { dataToValueFunction: '/* Should return boolean value */\nreturn data;' } }, + disabledState: { + action: GetValueAction.DO_NOTHING, + defaultValue: false, + getAttribute: { + key: 'state', + scope: null + }, + getTimeSeries: { + key: 'state' + }, + dataToValue: { + type: DataToValueType.NONE, + compareToValue: true, + dataToValueFunction: '/* Should return boolean value */\nreturn data;' + } + }, onUpdateState: { action: SetValueAction.EXECUTE_RPC, executeRpc: { diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/single-switch-widget-settings.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/single-switch-widget-settings.component.html index 9bdca64bbd..b498116317 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/single-switch-widget-settings.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/single-switch-widget-settings.component.html @@ -51,6 +51,17 @@ [widgetType]="widgetType" formControlName="offUpdateState">
+
+
widgets.rpc-state.disabled-state
+ +
widget-config.card-style
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/single-switch-widget-settings.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/single-switch-widget-settings.component.ts index 8c7282e32b..a1a3e951f2 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/single-switch-widget-settings.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/single-switch-widget-settings.component.ts @@ -69,6 +69,7 @@ export class SingleSwitchWidgetSettingsComponent extends WidgetSettingsComponent initialState: [settings.initialState, []], onUpdateState: [settings.onUpdateState, []], offUpdateState: [settings.offUpdateState, []], + disabledState: [settings.disabledState, []], layout: [settings.layout, []], autoScale: [settings.autoScale, []], @@ -109,7 +110,7 @@ export class SingleSwitchWidgetSettingsComponent extends WidgetSettingsComponent return ['showLabel', 'showIcon', 'showOnLabel', 'showOffLabel']; } - protected updateValidators(emitEvent: boolean): void { + protected updateValidators(_emitEvent: boolean): void { const showLabel: boolean = this.singleSwitchWidgetSettingsForm.get('showLabel').value; const showIcon: boolean = this.singleSwitchWidgetSettingsForm.get('showIcon').value; const showOnLabel: boolean = this.singleSwitchWidgetSettingsForm.get('showOnLabel').value; diff --git a/ui-ngx/src/assets/locale/locale.constant-en_US.json b/ui-ngx/src/assets/locale/locale.constant-en_US.json index c9108e9bac..ae3bc28c31 100644 --- a/ui-ngx/src/assets/locale/locale.constant-en_US.json +++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json @@ -6522,12 +6522,15 @@ "rpc-state": { "initial-state": "Initial state", "initial-state-hint": "Action to get the initial value of the component.", + "disabled-state": "Disabled state", + "disabled-state-hint": "Condition under which the component is disabled.", "turn-on": "Turn 'On'", "turn-on-hint": "Action performed to turn ON the component.", "turn-off": "Turn 'Off'", "turn-off-hint": "Action performed to turn OFF the component.", "on": "On", - "off": "Off" + "off": "Off", + "disabled": "Disabled" }, "value-action": { "do-nothing": "Do nothing", From 599911546b422355d92de1b2f03e4f7a35e2dafe Mon Sep 17 00:00:00 2001 From: Igor Kulikov Date: Mon, 5 Feb 2024 15:23:30 +0200 Subject: [PATCH 162/179] UI: Widget button style fixes. --- .../button/widget-button-custom-style-panel.component.ts | 2 +- .../common/button/widget-button-custom-style.component.ts | 3 ++- .../app/shared/components/button/widget-button.component.scss | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/button/widget-button-custom-style-panel.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/button/widget-button-custom-style-panel.component.ts index 419ce7e4d4..e6af6f2ab9 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/button/widget-button-custom-style-panel.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/button/widget-button-custom-style-panel.component.ts @@ -164,7 +164,7 @@ export class WidgetButtonCustomStylePanelComponent extends PageComponent impleme } private updatePreviewAppearance() { - this.previewAppearance = {...this.appearance}; + this.previewAppearance = deepClone(this.appearance); this.previewAppearance.customStyle[this.state] = this.customStyleFormGroup.value; this.cd.markForCheck(); } diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/button/widget-button-custom-style.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/button/widget-button-custom-style.component.ts index b9a1605b19..a67f9a45ab 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/button/widget-button-custom-style.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/button/widget-button-custom-style.component.ts @@ -37,6 +37,7 @@ import { MatIconButton } from '@angular/material/button'; import { WidgetButtonCustomStylePanelComponent } from '@home/components/widget/lib/settings/common/button/widget-button-custom-style-panel.component'; +import { deepClone } from '@core/utils'; @Component({ selector: 'tb-widget-button-custom-style', @@ -147,7 +148,7 @@ export class WidgetButtonCustomStyleComponent implements OnInit, OnChanges, Cont } private updatePreviewAppearance() { - this.previewAppearance = {...this.appearance}; + this.previewAppearance = deepClone(this.appearance); if (this.modelValue) { this.previewAppearance.customStyle[this.state] = this.modelValue; } diff --git a/ui-ngx/src/app/shared/components/button/widget-button.component.scss b/ui-ngx/src/app/shared/components/button/widget-button.component.scss index 546a3bed19..a0abc95731 100644 --- a/ui-ngx/src/app/shared/components/button/widget-button.component.scss +++ b/ui-ngx/src/app/shared/components/button/widget-button.component.scss @@ -44,7 +44,7 @@ $mainColorActivatedFilled: var(--tb-widget-button-main-color-activated-filled, # $mainColorDisabled: var(--tb-widget-button-main-color-disabled, $defaultMainColorDisabled); $backgroundColorDisabled: var(--tb-widget-button-background-color-disabled, $defaultBackgroundColorDisabled); -$boxShadowColorDisabled: var(--tb-widget-button-box-shadow-color-activated, $defaultBoxShadowColor); +$boxShadowColorDisabled: var(--tb-widget-button-box-shadow-color-disabled, $defaultBoxShadowColor); @mixin _tb-widget-button-styles($main, $background, $boxShadow) { From a8a10fefda0043e789e542c29b81b3bda6e244d9 Mon Sep 17 00:00:00 2001 From: Igor Kulikov Date: Mon, 5 Feb 2024 16:45:26 +0200 Subject: [PATCH 163/179] UI: Update buttons widget bundle image. Update single switch widget preview image. --- .../src/main/data/json/system/widget_bundles/buttons.json | 2 +- .../src/main/data/json/system/widget_types/single_switch.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/application/src/main/data/json/system/widget_bundles/buttons.json b/application/src/main/data/json/system/widget_bundles/buttons.json index 046e16dd7e..b5f728dc25 100644 --- a/application/src/main/data/json/system/widget_bundles/buttons.json +++ b/application/src/main/data/json/system/widget_bundles/buttons.json @@ -2,7 +2,7 @@ "widgetsBundle": { "alias": "buttons", "title": "Buttons", - "image": null, + "image": "tb-image:YnV0dG9ucy5zdmc=:IkJ1dHRvbnMiIHN5c3RlbSBidW5kbGUgaW1hZ2U=;data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAwIiBoZWlnaHQ9IjE2MCIgdmlld0JveD0iMCAwIDIwMCAxNjAiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHg9IjAuNzUiIHk9IjEyLjc1IiB3aWR0aD0iMTk4LjUiIGhlaWdodD0iNTguNSIgcng9IjMuMjUiIGZpbGw9IndoaXRlIi8+CjxyZWN0IHg9IjAuNzUiIHk9IjEyLjc1IiB3aWR0aD0iMTk4LjUiIGhlaWdodD0iNTguNSIgcng9IjMuMjUiIHN0cm9rZT0iIzNGNTJERCIgc3Ryb2tlLXdpZHRoPSIxLjUiLz4KPHBhdGggZD0iTTYyLjE2NjMgNTEuMzMzM1Y0NC4zMzMzSDY2LjgzM1Y1MS4zMzMzSDcyLjY2NjNWNDJINzYuMTY2M0w2NC40OTk3IDMxLjVMNTIuODMzIDQySDU2LjMzM1Y1MS4zMzMzSDYyLjE2NjNaIiBmaWxsPSIjM0Y1MkREIi8+CjxwYXRoIGQ9Ik05MC4xOTUzIDQyLjkzMTZIODYuMjFMODYuMTg4NSA0MC45NjU4SDg5LjY2ODlDOTAuMjU2MiA0MC45NjU4IDkwLjc1MzkgNDAuODc5OSA5MS4xNjIxIDQwLjcwOEM5MS41Nzc1IDQwLjUyOSA5MS44OTI2IDQwLjI3NDcgOTIuMTA3NCAzOS45NDUzQzkyLjMyMjMgMzkuNjA4NyA5Mi40Mjk3IDM5LjIwNDEgOTIuNDI5NyAzOC43MzE0QzkyLjQyOTcgMzguMjA4NyA5Mi4zMjk0IDM3Ljc4MjYgOTIuMTI4OSAzNy40NTMxQzkxLjkyODQgMzcuMTIzNyA5MS42MjA0IDM2Ljg4MzggOTEuMjA1MSAzNi43MzM0QzkwLjc5NjkgMzYuNTgzIDkwLjI3NDEgMzYuNTA3OCA4OS42MzY3IDM2LjUwNzhIODcuMDI2NFY1MEg4NC4zMzAxVjM0LjM1OTRIODkuNjM2N0M5MC40OTYxIDM0LjM1OTQgOTEuMjYyNCAzNC40NDE3IDkxLjkzNTUgMzQuNjA2NEM5Mi42MTU5IDM0Ljc3MTIgOTMuMTkyNCAzNS4wMjkgOTMuNjY1IDM1LjM3OTlDOTQuMTQ0OSAzNS43MjM2IDk0LjUwNjUgMzYuMTYwNSA5NC43NSAzNi42OTA0Qzk1LjAwMDcgMzcuMjIwNCA5NS4xMjYgMzcuODUwNiA5NS4xMjYgMzguNTgxMUM5NS4xMjYgMzkuMjI1NiA5NC45NzIgMzkuODE2NCA5NC42NjQxIDQwLjM1MzVDOTQuMzU2MSA0MC44ODM1IDkzLjkwMTQgNDEuMzE2NyA5My4yOTk4IDQxLjY1MzNDOTIuNjk4MiA0MS45ODk5IDkxLjk0OTkgNDIuMTkwNCA5MS4wNTQ3IDQyLjI1NDlMOTAuMTk1MyA0Mi45MzE2Wk05MC4wNzcxIDUwSDg1LjM2MTNMODYuNTc1MiA0Ny44NjIzSDkwLjA3NzFDOTAuNjg1OSA0Ny44NjIzIDkxLjE5NDMgNDcuNzYyIDkxLjYwMjUgNDcuNTYxNUM5Mi4wMTA3IDQ3LjM1MzggOTIuMzE1MSA0Ny4wNzEgOTIuNTE1NiA0Ni43MTI5QzkyLjcyMzMgNDYuMzQ3NyA5Mi44MjcxIDQ1LjkyMTUgOTIuODI3MSA0NS40MzQ2QzkyLjgyNzEgNDQuOTI2MSA5Mi43Mzc2IDQ0LjQ4NTcgOTIuNTU4NiA0NC4xMTMzQzkyLjM3OTYgNDMuNzMzNyA5Mi4wOTY3IDQzLjQ0MzcgOTEuNzEgNDMuMjQzMkM5MS4zMjMyIDQzLjAzNTUgOTAuODE4NCA0Mi45MzE2IDkwLjE5NTMgNDIuOTMxNkg4Ny4xNjZMODcuMTg3NSA0MC45NjU4SDkxLjEyOTlMOTEuNzQyMiA0MS43MDdDOTIuNjAxNiA0MS43MzU3IDkzLjMwNyA0MS45MjU1IDkzLjg1ODQgNDIuMjc2NEM5NC40MTcgNDIuNjI3MyA5NC44MzI0IDQzLjA4MiA5NS4xMDQ1IDQzLjY0MDZDOTUuMzc2NiA0NC4xOTkyIDk1LjUxMjcgNDQuODAwOCA5NS41MTI3IDQ1LjQ0NTNDOTUuNTEyNyA0Ni40NDA4IDk1LjI5NDMgNDcuMjc1MSA5NC44NTc0IDQ3Ljk0ODJDOTQuNDI3NyA0OC42MjE0IDkzLjgwODMgNDkuMTMzNSA5Mi45OTkgNDkuNDg0NEM5Mi4xODk4IDQ5LjgyODEgOTEuMjE1OCA1MCA5MC4wNzcxIDUwWk0xMDUuMjE2IDQ3LjI2MDdWMzguMzc3SDEwNy44MTVWNTBIMTA1LjM2NkwxMDUuMjE2IDQ3LjI2MDdaTTEwNS41ODEgNDQuODQzOEwxMDYuNDUxIDQ0LjgyMjNDMTA2LjQ1MSA0NS42MDI5IDEwNi4zNjUgNDYuMzIyNiAxMDYuMTkzIDQ2Ljk4MTRDMTA2LjAyMSA0Ny42MzMxIDEwNS43NTcgNDguMjAyNSAxMDUuMzk4IDQ4LjY4OTVDMTA1LjA0IDQ5LjE2OTMgMTA0LjU4MiA0OS41NDUyIDEwNC4wMjMgNDkuODE3NEMxMDMuNDY1IDUwLjA4MjQgMTAyLjc5NSA1MC4yMTQ4IDEwMi4wMTUgNTAuMjE0OEMxMDEuNDQ5IDUwLjIxNDggMTAwLjkzIDUwLjEzMjUgMTAwLjQ1NyA0OS45Njc4Qzk5Ljk4NDQgNDkuODAzMSA5OS41NzYyIDQ5LjU0ODggOTkuMjMyNCA0OS4yMDUxQzk4Ljg5NTggNDguODYxMyA5OC42MzQ0IDQ4LjQxMzcgOTguNDQ4MiA0Ny44NjIzQzk4LjI2MiA0Ny4zMTA5IDk4LjE2ODkgNDYuNjUyIDk4LjE2ODkgNDUuODg1N1YzOC4zNzdIMTAwLjc1OFY0NS45MDcyQzEwMC43NTggNDYuMzI5OCAxMDAuODA4IDQ2LjY4NDIgMTAwLjkwOCA0Ni45NzA3QzEwMS4wMDggNDcuMjUgMTAxLjE0NSA0Ny40NzU2IDEwMS4zMTYgNDcuNjQ3NUMxMDEuNDg4IDQ3LjgxOTMgMTAxLjY4OSA0Ny45NDExIDEwMS45MTggNDguMDEyN0MxMDIuMTQ3IDQ4LjA4NDMgMTAyLjM5MSA0OC4xMjAxIDEwMi42NDggNDguMTIwMUMxMDMuMzg2IDQ4LjEyMDEgMTAzLjk2NiA0Ny45NzY5IDEwNC4zODkgNDcuNjkwNEMxMDQuODE4IDQ3LjM5NjggMTA1LjEyMyA0Ny4wMDI5IDEwNS4zMDIgNDYuNTA4OEMxMDUuNDg4IDQ2LjAxNDYgMTA1LjU4MSA0NS40NTk2IDEwNS41ODEgNDQuODQzOFpNMTE2LjA0NyAzOC4zNzdWNDAuMjY3NkgxMDkuNDk0VjM4LjM3N0gxMTYuMDQ3Wk0xMTEuMzg1IDM1LjUzMDNIMTEzLjk3NFY0Ni43ODgxQzExMy45NzQgNDcuMTQ2MiAxMTQuMDI0IDQ3LjQyMTkgMTE0LjEyNCA0Ny42MTUyQzExNC4yMzEgNDcuODAxNCAxMTQuMzc4IDQ3LjkyNjggMTE0LjU2NCA0Ny45OTEyQzExNC43NTEgNDguMDU1NyAxMTQuOTY5IDQ4LjA4NzkgMTE1LjIyIDQ4LjA4NzlDMTE1LjM5OSA0OC4wODc5IDExNS41NzEgNDguMDc3MSAxMTUuNzM1IDQ4LjA1NTdDMTE1LjkgNDguMDM0MiAxMTYuMDMzIDQ4LjAxMjcgMTE2LjEzMyA0Ny45OTEyTDExNi4xNDQgNDkuOTY3OEMxMTUuOTI5IDUwLjAzMjIgMTE1LjY3OCA1MC4wODk1IDExNS4zOTIgNTAuMTM5NkMxMTUuMTEyIDUwLjE4OTggMTE0Ljc5IDUwLjIxNDggMTE0LjQyNSA1MC4yMTQ4QzExMy44MyA1MC4yMTQ4IDExMy4zMDQgNTAuMTExIDExMi44NDYgNDkuOTAzM0MxMTIuMzg3IDQ5LjY4ODUgMTEyLjAyOSA0OS4zNDExIDExMS43NzEgNDguODYxM0MxMTEuNTE0IDQ4LjM4MTUgMTExLjM4NSA0Ny43NDQxIDExMS4zODUgNDYuOTQ5MlYzNS41MzAzWk0xMjMuNjIzIDM4LjM3N1Y0MC4yNjc2SDExNy4wN1YzOC4zNzdIMTIzLjYyM1pNMTE4Ljk2MSAzNS41MzAzSDEyMS41NVY0Ni43ODgxQzEyMS41NSA0Ny4xNDYyIDEyMS42IDQ3LjQyMTkgMTIxLjcgNDcuNjE1MkMxMjEuODA4IDQ3LjgwMTQgMTIxLjk1NCA0Ny45MjY4IDEyMi4xNDEgNDcuOTkxMkMxMjIuMzI3IDQ4LjA1NTcgMTIyLjU0NSA0OC4wODc5IDEyMi43OTYgNDguMDg3OUMxMjIuOTc1IDQ4LjA4NzkgMTIzLjE0NyA0OC4wNzcxIDEyMy4zMTIgNDguMDU1N0MxMjMuNDc2IDQ4LjAzNDIgMTIzLjYwOSA0OC4wMTI3IDEyMy43MDkgNDcuOTkxMkwxMjMuNzIgNDkuOTY3OEMxMjMuNTA1IDUwLjAzMjIgMTIzLjI1NCA1MC4wODk1IDEyMi45NjggNTAuMTM5NkMxMjIuNjg4IDUwLjE4OTggMTIyLjM2NiA1MC4yMTQ4IDEyMi4wMDEgNTAuMjE0OEMxMjEuNDA3IDUwLjIxNDggMTIwLjg4IDUwLjExMSAxMjAuNDIyIDQ5LjkwMzNDMTE5Ljk2NCA0OS42ODg1IDExOS42MDUgNDkuMzQxMSAxMTkuMzQ4IDQ4Ljg2MTNDMTE5LjA5IDQ4LjM4MTUgMTE4Ljk2MSA0Ny43NDQxIDExOC45NjEgNDYuOTQ5MlYzNS41MzAzWk0xMjUuMTE5IDQ0LjMxNzRWNDQuMDcwM0MxMjUuMTE5IDQzLjIzMjQgMTI1LjI0MSA0Mi40NTU0IDEyNS40ODQgNDEuNzM5M0MxMjUuNzI4IDQxLjAxNiAxMjYuMDc5IDQwLjM4OTMgMTI2LjUzNyAzOS44NTk0QzEyNy4wMDMgMzkuMzIyMyAxMjcuNTY4IDM4LjkwNjkgMTI4LjIzNCAzOC42MTMzQzEyOC45MDggMzguMzEyNSAxMjkuNjY3IDM4LjE2MjEgMTMwLjUxMiAzOC4xNjIxQzEzMS4zNjQgMzguMTYyMSAxMzIuMTIzIDM4LjMxMjUgMTMyLjc4OSAzOC42MTMzQzEzMy40NjIgMzguOTA2OSAxMzQuMDMyIDM5LjMyMjMgMTM0LjQ5NyAzOS44NTk0QzEzNC45NjMgNDAuMzg5MyAxMzUuMzE3IDQxLjAxNiAxMzUuNTYxIDQxLjczOTNDMTM1LjgwNCA0Mi40NTU0IDEzNS45MjYgNDMuMjMyNCAxMzUuOTI2IDQ0LjA3MDNWNDQuMzE3NEMxMzUuOTI2IDQ1LjE1NTMgMTM1LjgwNCA0NS45MzIzIDEzNS41NjEgNDYuNjQ4NEMxMzUuMzE3IDQ3LjM2NDYgMTM0Ljk2MyA0Ny45OTEyIDEzNC40OTcgNDguNTI4M0MxMzQuMDMyIDQ5LjA1ODMgMTMzLjQ2NiA0OS40NzM2IDEzMi44IDQ5Ljc3NDRDMTMyLjEzNCA1MC4wNjggMTMxLjM3OCA1MC4yMTQ4IDEzMC41MzMgNTAuMjE0OEMxMjkuNjgxIDUwLjIxNDggMTI4LjkxOCA1MC4wNjggMTI4LjI0NSA0OS43NzQ0QzEyNy41NzkgNDkuNDczNiAxMjcuMDEzIDQ5LjA1ODMgMTI2LjU0OCA0OC41MjgzQzEyNi4wODIgNDcuOTkxMiAxMjUuNzI4IDQ3LjM2NDYgMTI1LjQ4NCA0Ni42NDg0QzEyNS4yNDEgNDUuOTMyMyAxMjUuMTE5IDQ1LjE1NTMgMTI1LjExOSA0NC4zMTc0Wk0xMjcuNzA4IDQ0LjA3MDNWNDQuMzE3NEMxMjcuNzA4IDQ0Ljg0MDIgMTI3Ljc2MiA0NS4zMzQzIDEyNy44NjkgNDUuNzk5OEMxMjcuOTc3IDQ2LjI2NTMgMTI4LjE0NSA0Ni42NzM1IDEyOC4zNzQgNDcuMDI0NEMxMjguNjAzIDQ3LjM3NTMgMTI4Ljg5NyA0Ny42NTEgMTI5LjI1NSA0Ny44NTE2QzEyOS42MTMgNDguMDUyMSAxMzAuMDM5IDQ4LjE1MjMgMTMwLjUzMyA0OC4xNTIzQzEzMS4wMTMgNDguMTUyMyAxMzEuNDI4IDQ4LjA1MjEgMTMxLjc3OSA0Ny44NTE2QzEzMi4xMzcgNDcuNjUxIDEzMi40MzEgNDcuMzc1MyAxMzIuNjYgNDcuMDI0NEMxMzIuODg5IDQ2LjY3MzUgMTMzLjA1OCA0Ni4yNjUzIDEzMy4xNjUgNDUuNzk5OEMxMzMuMjggNDUuMzM0MyAxMzMuMzM3IDQ0Ljg0MDIgMTMzLjMzNyA0NC4zMTc0VjQ0LjA3MDNDMTMzLjMzNyA0My41NTQ3IDEzMy4yOCA0My4wNjc3IDEzMy4xNjUgNDIuNjA5NEMxMzMuMDU4IDQyLjE0MzkgMTMyLjg4NiA0MS43MzIxIDEzMi42NDkgNDEuMzc0QzEzMi40MiA0MS4wMTYgMTMyLjEyNyA0MC43MzY3IDEzMS43NjkgNDAuNTM2MUMxMzEuNDE4IDQwLjMyODUgMTMwLjk5OSA0MC4yMjQ2IDEzMC41MTIgNDAuMjI0NkMxMzAuMDI1IDQwLjIyNDYgMTI5LjYwMiA0MC4zMjg1IDEyOS4yNDQgNDAuNTM2MUMxMjguODkzIDQwLjczNjcgMTI4LjYwMyA0MS4wMTYgMTI4LjM3NCA0MS4zNzRDMTI4LjE0NSA0MS43MzIxIDEyNy45NzcgNDIuMTQzOSAxMjcuODY5IDQyLjYwOTRDMTI3Ljc2MiA0My4wNjc3IDEyNy43MDggNDMuNTU0NyAxMjcuNzA4IDQ0LjA3MDNaTTE0MC45MTMgNDAuODU4NFY1MEgxMzguMzI0VjM4LjM3N0gxNDAuNzYzTDE0MC45MTMgNDAuODU4NFpNMTQwLjQ1MSA0My43NTg4TDEzOS42MTMgNDMuNzQ4QzEzOS42MiA0Mi45MjQ1IDEzOS43MzUgNDIuMTY4OSAxMzkuOTU3IDQxLjQ4MTRDMTQwLjE4NiA0MC43OTM5IDE0MC41MDEgNDAuMjAzMSAxNDAuOTAyIDM5LjcwOUMxNDEuMzExIDM5LjIxNDggMTQxLjc5OCAzOC44MzUzIDE0Mi4zNjMgMzguNTcwM0MxNDIuOTI5IDM4LjI5ODIgMTQzLjU1OSAzOC4xNjIxIDE0NC4yNTQgMzguMTYyMUMxNDQuODEyIDM4LjE2MjEgMTQ1LjMxNyAzOC4yNDA5IDE0NS43NjkgMzguMzk4NEMxNDYuMjI3IDM4LjU0ODggMTQ2LjYxNyAzOC43OTU5IDE0Ni45MzkgMzkuMTM5NkMxNDcuMjY5IDM5LjQ4MzQgMTQ3LjUyIDM5LjkzMSAxNDcuNjkxIDQwLjQ4MjRDMTQ3Ljg2MyA0MS4wMjY3IDE0Ny45NDkgNDEuNjk2MyAxNDcuOTQ5IDQyLjQ5MTJWNTBIMTQ1LjM1VjQyLjQ4MDVDMTQ1LjM1IDQxLjkyMTkgMTQ1LjI2NyA0MS40ODE0IDE0NS4xMDMgNDEuMTU5MkMxNDQuOTQ1IDQwLjgyOTggMTQ0LjcxMiA0MC41OTcgMTQ0LjQwNCA0MC40NjA5QzE0NC4xMDQgNDAuMzE3NyAxNDMuNzI4IDQwLjI0NjEgMTQzLjI3NiA0MC4yNDYxQzE0Mi44MzIgNDAuMjQ2MSAxNDIuNDM1IDQwLjMzOTIgMTQyLjA4NCA0MC41MjU0QzE0MS43MzMgNDAuNzExNiAxNDEuNDM2IDQwLjk2NTggMTQxLjE5MiA0MS4yODgxQzE0MC45NTYgNDEuNjEwNCAxNDAuNzczIDQxLjk4MjcgMTQwLjY0NSA0Mi40MDUzQzE0MC41MTYgNDIuODI3OCAxNDAuNDUxIDQzLjI3OSAxNDAuNDUxIDQzLjc1ODhaIiBmaWxsPSIjM0Y1MkREIi8+CjxyZWN0IHg9IjAuNzUiIHk9Ijg4Ljc1IiB3aWR0aD0iMTk4LjUiIGhlaWdodD0iNTguNSIgcng9IjMuMjUiIGZpbGw9IndoaXRlIi8+CjxyZWN0IHg9IjAuNzUiIHk9Ijg4Ljc1IiB3aWR0aD0iMTk4LjUiIGhlaWdodD0iNTguNSIgcng9IjMuMjUiIHN0cm9rZT0iIzNGNTJERCIgc3Ryb2tlLXdpZHRoPSIxLjUiLz4KPHBhdGggZD0iTTY1LjQ5OTcgMTExVjExMy4zMzNINzUuNTIxM0w2NC4zMzMgMTI0LjUyMkw2NS45NzggMTI2LjE2N0w3Ny4xNjYzIDExNC45NzhWMTI1SDc5LjQ5OTdWMTExSDY1LjQ5OTdaIiBmaWxsPSIjM0Y1MkREIi8+CjxwYXRoIGQ9Ik0xMDAuNTY0IDEyMS45NzJDMTAwLjU2NCAxMjEuNjQ5IDEwMC41MTQgMTIxLjM2MyAxMDAuNDE0IDEyMS4xMTJDMTAwLjMyMSAxMjAuODYyIDEwMC4xNTMgMTIwLjYzMiA5OS45MDkyIDEyMC40MjVDOTkuNjY1NyAxMjAuMjE3IDk5LjMyMTkgMTIwLjAxNyA5OC44Nzc5IDExOS44MjNDOTguNDQxMSAxMTkuNjIzIDk3Ljg4MjUgMTE5LjQxOSA5Ny4yMDIxIDExOS4yMTFDOTYuNDU3NCAxMTguOTgyIDk1Ljc2OTkgMTE4LjcyOCA5NS4xMzk2IDExOC40NDhDOTQuNTE2NiAxMTguMTYyIDkzLjk3MjMgMTE3LjgzMiA5My41MDY4IDExNy40NkM5My4wNDEzIDExNy4wOCA5Mi42Nzk3IDExNi42NDcgOTIuNDIxOSAxMTYuMTZDOTIuMTY0MSAxMTUuNjY2IDkyLjAzNTIgMTE1LjA5NyA5Mi4wMzUyIDExNC40NTJDOTIuMDM1MiAxMTMuODE1IDkyLjE2NzYgMTEzLjIzNSA5Mi40MzI2IDExMi43MTJDOTIuNzA0OCAxMTIuMTg5IDkzLjA4NzkgMTExLjczOCA5My41ODIgMTExLjM1OEM5NC4wODMzIDExMC45NzIgOTQuNjc0MiAxMTAuNjc0IDk1LjM1NDUgMTEwLjQ2N0M5Ni4wMzQ4IDExMC4yNTIgOTYuNzg2OCAxMTAuMTQ1IDk3LjYxMDQgMTEwLjE0NUM5OC43NzA1IDExMC4xNDUgOTkuNzY5NSAxMTAuMzU5IDEwMC42MDcgMTEwLjc4OUMxMDEuNDUyIDExMS4yMTkgMTAyLjEwMSAxMTEuNzk1IDEwMi41NTIgMTEyLjUxOUMxMDMuMDEgMTEzLjI0MiAxMDMuMjM5IDExNC4wNCAxMDMuMjM5IDExNC45MTRIMTAwLjU2NEMxMDAuNTY0IDExNC4zOTggMTAwLjQ1MyAxMTMuOTQ0IDEwMC4yMzEgMTEzLjU1QzEwMC4wMTcgMTEzLjE0OSA5OS42ODcyIDExMi44MzQgOTkuMjQzMiAxMTIuNjA0Qzk4LjgwNjMgMTEyLjM3NSA5OC4yNTEzIDExMi4yNjEgOTcuNTc4MSAxMTIuMjYxQzk2Ljk0MDggMTEyLjI2MSA5Ni40MTA4IDExMi4zNTcgOTUuOTg4MyAxMTIuNTUxQzk1LjU2NTggMTEyLjc0NCA5NS4yNTA3IDExMy4wMDYgOTUuMDQzIDExMy4zMzVDOTQuODM1MyAxMTMuNjY0IDk0LjczMTQgMTE0LjAzNyA5NC43MzE0IDExNC40NTJDOTQuNzMxNCAxMTQuNzQ2IDk0Ljc5OTUgMTE1LjAxNCA5NC45MzU1IDExNS4yNThDOTUuMDcxNiAxMTUuNDk0IDk1LjI3OTMgMTE1LjcxNiA5NS41NTg2IDExNS45MjRDOTUuODM3OSAxMTYuMTI0IDk2LjE4ODggMTE2LjMxNCA5Ni42MTEzIDExNi40OTNDOTcuMDMzOSAxMTYuNjcyIDk3LjUzMTYgMTE2Ljg0NCA5OC4xMDQ1IDExNy4wMDlDOTguOTcxIDExNy4yNjcgOTkuNzI2NiAxMTcuNTUzIDEwMC4zNzEgMTE3Ljg2OEMxMDEuMDE2IDExOC4xNzYgMTAxLjU1MyAxMTguNTI3IDEwMS45ODIgMTE4LjkyMUMxMDIuNDEyIDExOS4zMTUgMTAyLjczNCAxMTkuNzYyIDEwMi45NDkgMTIwLjI2NEMxMDMuMTY0IDEyMC43NTggMTAzLjI3MSAxMjEuMzIgMTAzLjI3MSAxMjEuOTVDMTAzLjI3MSAxMjIuNjA5IDEwMy4xMzkgMTIzLjIwMyAxMDIuODc0IDEyMy43MzNDMTAyLjYwOSAxMjQuMjU2IDEwMi4yMjkgMTI0LjcwNCAxMDEuNzM1IDEyNS4wNzZDMTAxLjI0OCAxMjUuNDQxIDEwMC42NjEgMTI1LjcyNCA5OS45NzM2IDEyNS45MjVDOTkuMjkzMyAxMjYuMTE4IDk4LjUzNDIgMTI2LjIxNSA5Ny42OTYzIDEyNi4yMTVDOTYuOTQ0MyAxMjYuMjE1IDk2LjIwMzEgMTI2LjExNSA5NS40NzI3IDEyNS45MTRDOTQuNzQ5MyAxMjUuNzE0IDk0LjA5MDUgMTI1LjQwOSA5My40OTYxIDEyNS4wMDFDOTIuOTAxNyAxMjQuNTg2IDkyLjQyOSAxMjQuMDcgOTIuMDc4MSAxMjMuNDU0QzkxLjcyNzIgMTIyLjgzMSA5MS41NTE4IDEyMi4xMDQgOTEuNTUxOCAxMjEuMjczSDk0LjI0OEM5NC4yNDggMTIxLjc4MiA5NC4zMzQgMTIyLjIxNSA5NC41MDU5IDEyMi41NzNDOTQuNjg0OSAxMjIuOTMxIDk0LjkzMiAxMjMuMjI1IDk1LjI0NzEgMTIzLjQ1NEM5NS41NjIyIDEyMy42NzYgOTUuOTI3NCAxMjMuODQxIDk2LjM0MjggMTIzLjk0OEM5Ni43NjUzIDEyNC4wNTYgOTcuMjE2NSAxMjQuMTA5IDk3LjY5NjMgMTI0LjEwOUM5OC4zMjY1IDEyNC4xMDkgOTguODUyOSAxMjQuMDIgOTkuMjc1NCAxMjMuODQxQzk5LjcwNTEgMTIzLjY2MiAxMDAuMDI3IDEyMy40MTEgMTAwLjI0MiAxMjMuMDg5QzEwMC40NTcgMTIyLjc2NyAxMDAuNTY0IDEyMi4zOTQgMTAwLjU2NCAxMjEuOTcyWk0xMTAuNzcyIDEyNi4yMTVDMTA5LjkxMyAxMjYuMjE1IDEwOS4xMzYgMTI2LjA3NSAxMDguNDQxIDEyNS43OTZDMTA3Ljc1NCAxMjUuNTA5IDEwNy4xNjcgMTI1LjExMiAxMDYuNjggMTI0LjYwNEMxMDYuMiAxMjQuMDk1IDEwNS44MzEgMTIzLjQ5NyAxMDUuNTczIDEyMi44MUMxMDUuMzE1IDEyMi4xMjIgMTA1LjE4NyAxMjEuMzgxIDEwNS4xODcgMTIwLjU4NlYxMjAuMTU2QzEwNS4xODcgMTE5LjI0NyAxMDUuMzE5IDExOC40MjMgMTA1LjU4NCAxMTcuNjg2QzEwNS44NDkgMTE2Ljk0OCAxMDYuMjE4IDExNi4zMTggMTA2LjY5IDExNS43OTVDMTA3LjE2MyAxMTUuMjY1IDEwNy43MjIgMTE0Ljg2IDEwOC4zNjYgMTE0LjU4MUMxMDkuMDExIDExNC4zMDIgMTA5LjcwOSAxMTQuMTYyIDExMC40NjEgMTE0LjE2MkMxMTEuMjkyIDExNC4xNjIgMTEyLjAxOSAxMTQuMzAyIDExMi42NDIgMTE0LjU4MUMxMTMuMjY1IDExNC44NiAxMTMuNzggMTE1LjI1NCAxMTQuMTg4IDExNS43NjNDMTE0LjYwNCAxMTYuMjY0IDExNC45MTIgMTE2Ljg2MiAxMTUuMTEyIDExNy41NTdDMTE1LjMyIDExOC4yNTEgMTE1LjQyNCAxMTkuMDE4IDExNS40MjQgMTE5Ljg1NVYxMjAuOTYySDEwNi40NDNWMTE5LjEwNEgxMTIuODY3VjExOC44OTlDMTEyLjg1MyAxMTguNDM0IDExMi43NiAxMTcuOTk3IDExMi41ODggMTE3LjU4OUMxMTIuNDIzIDExNy4xODEgMTEyLjE2OSAxMTYuODUxIDExMS44MjUgMTE2LjYwMUMxMTEuNDgxIDExNi4zNSAxMTEuMDIzIDExNi4yMjUgMTEwLjQ1IDExNi4yMjVDMTEwLjAyMSAxMTYuMjI1IDEwOS42MzcgMTE2LjMxOCAxMDkuMzAxIDExNi41MDRDMTA4Ljk3MSAxMTYuNjgzIDEwOC42OTYgMTE2Ljk0NCAxMDguNDc0IDExNy4yODhDMTA4LjI1MiAxMTcuNjMyIDEwOC4wOCAxMTguMDQ3IDEwNy45NTggMTE4LjUzNEMxMDcuODQzIDExOS4wMTQgMTA3Ljc4NiAxMTkuNTU1IDEwNy43ODYgMTIwLjE1NlYxMjAuNTg2QzEwNy43ODYgMTIxLjA5NCAxMDcuODU0IDEyMS41NjcgMTA3Ljk5IDEyMi4wMDRDMTA4LjEzMyAxMjIuNDM0IDEwOC4zNDEgMTIyLjgxIDEwOC42MTMgMTIzLjEzMkMxMDguODg1IDEyMy40NTQgMTA5LjIxNSAxMjMuNzA4IDEwOS42MDIgMTIzLjg5NUMxMDkuOTg4IDEyNC4wNzQgMTEwLjQyOSAxMjQuMTYzIDExMC45MjMgMTI0LjE2M0MxMTEuNTQ2IDEyNC4xNjMgMTEyLjEwMSAxMjQuMDM4IDExMi41ODggMTIzLjc4N0MxMTMuMDc1IDEyMy41MzYgMTEzLjQ5NyAxMjMuMTgyIDExMy44NTUgMTIyLjcyNEwxMTUuMjIgMTI0LjA0NUMxMTQuOTY5IDEyNC40MSAxMTQuNjQzIDEyNC43NjEgMTE0LjI0MiAxMjUuMDk4QzExMy44NDEgMTI1LjQyNyAxMTMuMzUxIDEyNS42OTYgMTEyLjc3MSAxMjUuOTAzQzExMi4xOTggMTI2LjExMSAxMTEuNTMyIDEyNi4yMTUgMTEwLjc3MiAxMjYuMjE1Wk0xMjAuMjYxIDExNi44NThWMTI2SDExNy42NzJWMTE0LjM3N0gxMjAuMTFMMTIwLjI2MSAxMTYuODU4Wk0xMTkuNzk5IDExOS43NTlMMTE4Ljk2MSAxMTkuNzQ4QzExOC45NjggMTE4LjkyNCAxMTkuMDgzIDExOC4xNjkgMTE5LjMwNSAxMTcuNDgxQzExOS41MzQgMTE2Ljc5NCAxMTkuODQ5IDExNi4yMDMgMTIwLjI1IDExNS43MDlDMTIwLjY1OCAxMTUuMjE1IDEyMS4xNDUgMTE0LjgzNSAxMjEuNzExIDExNC41N0MxMjIuMjc3IDExNC4yOTggMTIyLjkwNyAxMTQuMTYyIDEyMy42MDIgMTE0LjE2MkMxMjQuMTYgMTE0LjE2MiAxMjQuNjY1IDExNC4yNDEgMTI1LjExNiAxMTQuMzk4QzEyNS41NzUgMTE0LjU0OSAxMjUuOTY1IDExNC43OTYgMTI2LjI4NyAxMTUuMTRDMTI2LjYxNyAxMTUuNDgzIDEyNi44NjcgMTE1LjkzMSAxMjcuMDM5IDExNi40ODJDMTI3LjIxMSAxMTcuMDI3IDEyNy4yOTcgMTE3LjY5NiAxMjcuMjk3IDExOC40OTFWMTI2SDEyNC42OTdWMTE4LjQ4QzEyNC42OTcgMTE3LjkyMiAxMjQuNjE1IDExNy40ODEgMTI0LjQ1IDExNy4xNTlDMTI0LjI5MyAxMTYuODMgMTI0LjA2IDExNi41OTcgMTIzLjc1MiAxMTYuNDYxQzEyMy40NTEgMTE2LjMxOCAxMjMuMDc1IDExNi4yNDYgMTIyLjYyNCAxMTYuMjQ2QzEyMi4xOCAxMTYuMjQ2IDEyMS43ODMgMTE2LjMzOSAxMjEuNDMyIDExNi41MjVDMTIxLjA4MSAxMTYuNzEyIDEyMC43ODQgMTE2Ljk2NiAxMjAuNTQgMTE3LjI4OEMxMjAuMzA0IDExNy42MSAxMjAuMTIxIDExNy45ODMgMTE5Ljk5MiAxMTguNDA1QzExOS44NjMgMTE4LjgyOCAxMTkuNzk5IDExOS4yNzkgMTE5Ljc5OSAxMTkuNzU5Wk0xMzcuMjc5IDEyMy41OTRWMTA5LjVIMTM5Ljg3OVYxMjZIMTM3LjUyNkwxMzcuMjc5IDEyMy41OTRaTTEyOS43MTcgMTIwLjMxN1YxMjAuMDkyQzEyOS43MTcgMTE5LjIxMSAxMjkuODIxIDExOC40MDkgMTMwLjAyOCAxMTcuNjg2QzEzMC4yMzYgMTE2Ljk1NSAxMzAuNTM3IDExNi4zMjggMTMwLjkzMSAxMTUuODA2QzEzMS4zMjUgMTE1LjI3NiAxMzEuODA0IDExNC44NzEgMTMyLjM3IDExNC41OTJDMTMyLjkzNiAxMTQuMzA1IDEzMy41NzMgMTE0LjE2MiAxMzQuMjgyIDExNC4xNjJDMTM0Ljk4NCAxMTQuMTYyIDEzNS42IDExNC4yOTggMTM2LjEzIDExNC41N0MxMzYuNjYgMTE0Ljg0MiAxMzcuMTExIDExNS4yMzMgMTM3LjQ4MyAxMTUuNzQxQzEzNy44NTYgMTE2LjI0MyAxMzguMTUzIDExNi44NDQgMTM4LjM3NSAxMTcuNTQ2QzEzOC41OTcgMTE4LjI0MSAxMzguNzU1IDExOS4wMTQgMTM4Ljg0OCAxMTkuODY2VjEyMC41ODZDMTM4Ljc1NSAxMjEuNDE3IDEzOC41OTcgMTIyLjE3NiAxMzguMzc1IDEyMi44NjNDMTM4LjE1MyAxMjMuNTUxIDEzNy44NTYgMTI0LjE0NSAxMzcuNDgzIDEyNC42NDZDMTM3LjExMSAxMjUuMTQ4IDEzNi42NTYgMTI1LjUzNSAxMzYuMTE5IDEyNS44MDdDMTM1LjU4OSAxMjYuMDc5IDEzNC45NyAxMjYuMjE1IDEzNC4yNjEgMTI2LjIxNUMxMzMuNTU5IDEyNi4yMTUgMTMyLjkyNSAxMjYuMDY4IDEzMi4zNTkgMTI1Ljc3NEMxMzEuODAxIDEyNS40ODEgMTMxLjMyNSAxMjUuMDY5IDEzMC45MzEgMTI0LjUzOUMxMzAuNTM3IDEyNC4wMDkgMTMwLjIzNiAxMjMuMzg2IDEzMC4wMjggMTIyLjY3QzEyOS44MjEgMTIxLjk0NyAxMjkuNzE3IDEyMS4xNjIgMTI5LjcxNyAxMjAuMzE3Wk0xMzIuMzA2IDEyMC4wOTJWMTIwLjMxN0MxMzIuMzA2IDEyMC44NDcgMTMyLjM1MiAxMjEuMzQxIDEzMi40NDUgMTIxLjhDMTMyLjU0NiAxMjIuMjU4IDEzMi43IDEyMi42NjMgMTMyLjkwNyAxMjMuMDE0QzEzMy4xMTUgMTIzLjM1NyAxMzMuMzgzIDEyMy42MyAxMzMuNzEzIDEyMy44M0MxMzQuMDQ5IDEyNC4wMjMgMTM0LjQ1MSAxMjQuMTIgMTM0LjkxNiAxMjQuMTJDMTM1LjUwMyAxMjQuMTIgMTM1Ljk4NyAxMjMuOTkxIDEzNi4zNjYgMTIzLjczM0MxMzYuNzQ2IDEyMy40NzYgMTM3LjA0MyAxMjMuMTI4IDEzNy4yNTggMTIyLjY5MUMxMzcuNDggMTIyLjI0NyAxMzcuNjMgMTIxLjc1MyAxMzcuNzA5IDEyMS4yMDlWMTE5LjI2NUMxMzcuNjY2IDExOC44NDIgMTM3LjU3NiAxMTguNDQ4IDEzNy40NCAxMTguMDgzQzEzNy4zMTIgMTE3LjcxOCAxMzcuMTM2IDExNy4zOTkgMTM2LjkxNCAxMTcuMTI3QzEzNi42OTIgMTE2Ljg0OCAxMzYuNDE2IDExNi42MzMgMTM2LjA4NyAxMTYuNDgyQzEzNS43NjUgMTE2LjMyNSAxMzUuMzgyIDExNi4yNDYgMTM0LjkzOCAxMTYuMjQ2QzEzNC40NjUgMTE2LjI0NiAxMzQuMDY0IDExNi4zNDYgMTMzLjczNCAxMTYuNTQ3QzEzMy40MDUgMTE2Ljc0NyAxMzMuMTMzIDExNy4wMjMgMTMyLjkxOCAxMTcuMzc0QzEzMi43MSAxMTcuNzI1IDEzMi41NTYgMTE4LjEzMyAxMzIuNDU2IDExOC41OTlDMTMyLjM1NiAxMTkuMDY0IDEzMi4zMDYgMTE5LjU2MiAxMzIuMzA2IDEyMC4wOTJaIiBmaWxsPSIjM0Y1MkREIi8+Cjwvc3ZnPgo=", "description": null, "order": 7500, "name": "Buttons" diff --git a/application/src/main/data/json/system/widget_types/single_switch.json b/application/src/main/data/json/system/widget_types/single_switch.json index 4a62cc0598..b14cf633a2 100644 --- a/application/src/main/data/json/system/widget_types/single_switch.json +++ b/application/src/main/data/json/system/widget_types/single_switch.json @@ -2,7 +2,7 @@ "fqn": "single_switch", "name": "Single Switch", "deprecated": false, - "image": "tb-image:c2luZ2xlLXN3aXRjaC5zdmc=:IlNpbmdsZSBTd2l0Y2giIHN5c3RlbSB3aWRnZXQgaW1hZ2U=;data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAxIiBoZWlnaHQ9IjE2MCIgdmlld0JveD0iMCAwIDIwMSAxNjAiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMF8zNjM5XzE1NTY3NCkiPgo8cmVjdCB4PSIwLjUiIHdpZHRoPSIyMDAiIGhlaWdodD0iMTYwIiByeD0iNCIgZmlsbD0id2hpdGUiLz4KPHJlY3QgeD0iMSIgeT0iMC41IiB3aWR0aD0iMTk5IiBoZWlnaHQ9IjE1OSIgcng9IjMuNSIgc3Ryb2tlPSJibGFjayIgc3Ryb2tlLW9wYWNpdHk9IjAuMTIiLz4KPHJlY3QgeD0iNTUiIHk9IjcwIiB3aWR0aD0iMzguMDk1MiIgaGVpZ2h0PSIxOS45NTQ3IiByeD0iOS45NzczMyIgZmlsbD0iIzU0NjlGRiIvPgo8Y2lyY2xlIGN4PSI4My4xMTY0IiBjeT0iNzkuOTc3MiIgcj0iOC4xNjMyNyIgZmlsbD0id2hpdGUiLz4KPHBhdGggZD0iTTEwNi42OTQgODEuNzUzNEMxMDYuNjk0IDgxLjUzMzcgMTA2LjY2IDgxLjMzODQgMTA2LjU5MiA4MS4xNjc1QzEwNi41MjggODAuOTk2NiAxMDYuNDE0IDgwLjg0MDMgMTA2LjI0OCA4MC42OTg3QzEwNi4wODIgODAuNTU3MSAxMDUuODQ3IDgwLjQyMDQgMTA1LjU0NCA4MC4yODg2QzEwNS4yNDcgODAuMTUxOSAxMDQuODY2IDgwLjAxMjcgMTA0LjQwMiA3OS44NzExQzEwMy44OTQgNzkuNzE0OCAxMDMuNDI1IDc5LjU0MTUgMTAyLjk5NiA3OS4zNTExQzEwMi41NzEgNzkuMTU1OCAxMDIuMiA3OC45MzEyIDEwMS44ODIgNzguNjc3MkMxMDEuNTY1IDc4LjQxODUgMTAxLjMxOCA3OC4xMjMgMTAxLjE0MyA3Ny43OTFDMTAwLjk2NyA3Ny40NTQxIDEwMC44NzkgNzcuMDY1OSAxMDAuODc5IDc2LjYyNjVDMTAwLjg3OSA3Ni4xOTE5IDEwMC45NjkgNzUuNzk2NCAxMDEuMTUgNzUuNDM5OUMxMDEuMzM1IDc1LjA4MzUgMTAxLjU5NyA3NC43NzU5IDEwMS45MzQgNzQuNTE3MUMxMDIuMjc1IDc0LjI1MzQgMTAyLjY3OCA3NC4wNTA4IDEwMy4xNDIgNzMuOTA5MkMxMDMuNjA2IDczLjc2MjcgMTA0LjExOSA3My42ODk1IDEwNC42OCA3My42ODk1QzEwNS40NzEgNzMuNjg5NSAxMDYuMTUyIDczLjgzNTkgMTA2LjcyNCA3NC4xMjg5QzEwNy4zIDc0LjQyMTkgMTA3Ljc0MiA3NC44MTQ5IDEwOC4wNDkgNzUuMzA4MUMxMDguMzYyIDc1LjgwMTMgMTA4LjUxOCA3Ni4zNDU3IDEwOC41MTggNzYuOTQxNEgxMDYuNjk0QzEwNi42OTQgNzYuNTg5OCAxMDYuNjE5IDc2LjI3OTggMTA2LjQ2NyA3Ni4wMTEyQzEwNi4zMjEgNzUuNzM3OCAxMDYuMDk2IDc1LjUyMjkgMTA1Ljc5MyA3NS4zNjY3QzEwNS40OTYgNzUuMjEwNCAxMDUuMTE3IDc1LjEzMjMgMTA0LjY1OCA3NS4xMzIzQzEwNC4yMjQgNzUuMTMyMyAxMDMuODYyIDc1LjE5ODIgMTAzLjU3NCA3NS4zMzAxQzEwMy4yODYgNzUuNDYxOSAxMDMuMDcxIDc1LjY0MDEgMTAyLjkzIDc1Ljg2NDdDMTAyLjc4OCA3Ni4wODk0IDEwMi43MTcgNzYuMzQzMyAxMDIuNzE3IDc2LjYyNjVDMTAyLjcxNyA3Ni44MjY3IDEwMi43NjQgNzcuMDA5OCAxMDIuODU2IDc3LjE3NThDMTAyLjk0OSA3Ny4zMzY5IDEwMy4wOTEgNzcuNDg4MyAxMDMuMjgxIDc3LjYyOTlDMTAzLjQ3MiA3Ny43NjY2IDEwMy43MTEgNzcuODk2IDEwMy45OTkgNzguMDE4MUMxMDQuMjg3IDc4LjE0MDEgMTA0LjYyNiA3OC4yNTczIDEwNS4wMTcgNzguMzY5NkMxMDUuNjA4IDc4LjU0NTQgMTA2LjEyMyA3OC43NDA3IDEwNi41NjIgNzguOTU1NkMxMDcuMDAyIDc5LjE2NTUgMTA3LjM2OCA3OS40MDQ4IDEwNy42NjEgNzkuNjczM0MxMDcuOTU0IDc5Ljk0MTkgMTA4LjE3NCA4MC4yNDcxIDEwOC4zMiA4MC41ODg5QzEwOC40NjcgODAuOTI1OCAxMDguNTQgODEuMzA5MSAxMDguNTQgODEuNzM4OEMxMDguNTQgODIuMTg4IDEwOC40NSA4Mi41OTMzIDEwOC4yNjkgODIuOTU0NkMxMDguMDg4IDgzLjMxMSAxMDcuODMgODMuNjE2MiAxMDcuNDkzIDgzLjg3MDFDMTA3LjE2MSA4NC4xMTkxIDEwNi43NiA4NC4zMTIgMTA2LjI5MiA4NC40NDg3QzEwNS44MjggODQuNTgwNiAxMDUuMzEgODQuNjQ2NSAxMDQuNzM5IDg0LjY0NjVDMTA0LjIyNiA4NC42NDY1IDEwMy43MjEgODQuNTc4MSAxMDMuMjIzIDg0LjQ0MTRDMTAyLjcyOSA4NC4zMDQ3IDEwMi4yOCA4NC4wOTcyIDEwMS44NzUgODMuODE4OEMxMDEuNDcgODMuNTM1NiAxMDEuMTQ3IDgzLjE4NDEgMTAwLjkwOCA4Mi43NjQyQzEwMC42NjkgODIuMzM5NCAxMDAuNTQ5IDgxLjg0MzggMTAwLjU0OSA4MS4yNzczSDEwMi4zODhDMTAyLjM4OCA4MS42MjQgMTAyLjQ0NiA4MS45MTk0IDEwMi41NjMgODIuMTYzNkMxMDIuNjg2IDgyLjQwNzcgMTAyLjg1NCA4Mi42MDc5IDEwMy4wNjkgODIuNzY0MkMxMDMuMjg0IDgyLjkxNTUgMTAzLjUzMyA4My4wMjc4IDEwMy44MTYgODMuMTAxMUMxMDQuMTA0IDgzLjE3NDMgMTA0LjQxMiA4My4yMTA5IDEwNC43MzkgODMuMjEwOUMxMDUuMTY4IDgzLjIxMDkgMTA1LjUyNyA4My4xNDk5IDEwNS44MTUgODMuMDI3OEMxMDYuMTA4IDgyLjkwNTggMTA2LjMyOCA4Mi43MzQ5IDEwNi40NzUgODIuNTE1MUMxMDYuNjIxIDgyLjI5NTQgMTA2LjY5NCA4Mi4wNDE1IDEwNi42OTQgODEuNzUzNFpNMTEyLjE0NCA4Mi43NDIyTDExMy45NzUgNzYuNTc1MkgxMTUuMTAzTDExNC43OTUgNzguNDIwOUwxMTIuOTQ5IDg0LjVIMTExLjkzOEwxMTIuMTQ0IDgyLjc0MjJaTTExMS4wNjcgNzYuNTc1MkwxMTIuNDk1IDgyLjc3MTVMMTEyLjYxMiA4NC41SDExMS40ODRMMTA5LjMzOCA3Ni41NzUySDExMS4wNjdaTTExNi44MTYgODIuNjk4MkwxMTguMjAxIDc2LjU3NTJIMTE5LjkyMkwxMTcuNzgzIDg0LjVIMTE2LjY1NUwxMTYuODE2IDgyLjY5ODJaTTExNS4yOTMgNzYuNTc1MkwxMTcuMTAyIDgyLjY2ODlMMTE3LjMyOSA4NC41SDExNi4zMThMMTE0LjQ1MSA3OC40MTM2TDExNC4xNDMgNzYuNTc1MkgxMTUuMjkzWk0xMjMuMDEzIDc2LjU3NTJWODQuNUgxMjEuMjRWNzYuNTc1MkgxMjMuMDEzWk0xMjEuMTIzIDc0LjQ5NTFDMTIxLjEyMyA3NC4yMjY2IDEyMS4yMTEgNzQuMDA0NCAxMjEuMzg3IDczLjgyODZDMTIxLjU2NyA3My42NDc5IDEyMS44MTYgNzMuNTU3NiAxMjIuMTM0IDczLjU1NzZDMTIyLjQ0NiA3My41NTc2IDEyMi42OTMgNzMuNjQ3OSAxMjIuODc0IDczLjgyODZDMTIzLjA1NCA3NC4wMDQ0IDEyMy4xNDUgNzQuMjI2NiAxMjMuMTQ1IDc0LjQ5NTFDMTIzLjE0NSA3NC43NTg4IDEyMy4wNTQgNzQuOTc4NSAxMjIuODc0IDc1LjE1NDNDMTIyLjY5MyA3NS4zMzAxIDEyMi40NDYgNzUuNDE4IDEyMi4xMzQgNzUuNDE4QzEyMS44MTYgNzUuNDE4IDEyMS41NjcgNzUuMzMwMSAxMjEuMzg3IDc1LjE1NDNDMTIxLjIxMSA3NC45Nzg1IDEyMS4xMjMgNzQuNzU4OCAxMjEuMTIzIDc0LjQ5NTFaTTEyOC41NzkgNzYuNTc1MlY3Ny44NjQzSDEyNC4xMTFWNzYuNTc1MkgxMjguNTc5Wk0xMjUuNCA3NC42MzQzSDEyNy4xNjZWODIuMzEwMUMxMjcuMTY2IDgyLjU1NDIgMTI3LjIgODIuNzQyMiAxMjcuMjY4IDgyLjg3NEMxMjcuMzQxIDgzLjAwMSAxMjcuNDQxIDgzLjA4NjQgMTI3LjU2OCA4My4xMzA0QzEyNy42OTUgODMuMTc0MyAxMjcuODQ0IDgzLjE5NjMgMTI4LjAxNSA4My4xOTYzQzEyOC4xMzcgODMuMTk2MyAxMjguMjU0IDgzLjE4OSAxMjguMzY3IDgzLjE3NDNDMTI4LjQ3OSA4My4xNTk3IDEyOC41NjkgODMuMTQ1IDEyOC42MzggODMuMTMwNEwxMjguNjQ1IDg0LjQ3OEMxMjguNDk5IDg0LjUyMiAxMjguMzI4IDg0LjU2MSAxMjguMTMyIDg0LjU5NTJDMTI3Ljk0MiA4NC42Mjk0IDEyNy43MjIgODQuNjQ2NSAxMjcuNDczIDg0LjY0NjVDMTI3LjA2OCA4NC42NDY1IDEyNi43MDkgODQuNTc1NyAxMjYuMzk2IDg0LjQzNDFDMTI2LjA4NCA4NC4yODc2IDEyNS44NCA4NC4wNTA4IDEyNS42NjQgODMuNzIzNkMxMjUuNDg4IDgzLjM5NjUgMTI1LjQgODIuOTYxOSAxMjUuNCA4Mi40MTk5Vjc0LjYzNDNaTTEzMy4xNzkgODMuMjQwMkMxMzMuNDY3IDgzLjI0MDIgMTMzLjcyNiA4My4xODQxIDEzMy45NTUgODMuMDcxOEMxMzQuMTg5IDgyLjk1NDYgMTM0LjM3NyA4Mi43OTM1IDEzNC41MTkgODIuNTg4NEMxMzQuNjY2IDgyLjM4MzMgMTM0Ljc0NiA4Mi4xNDY1IDEzNC43NjEgODEuODc3OUgxMzYuNDIzQzEzNi40MTQgODIuMzkwNiAxMzYuMjYyIDgyLjg1NjkgMTM1Ljk2OSA4My4yNzY5QzEzNS42NzYgODMuNjk2OCAxMzUuMjg4IDg0LjAzMTIgMTM0LjgwNSA4NC4yODAzQzEzNC4zMjEgODQuNTI0NCAxMzMuNzg3IDg0LjY0NjUgMTMzLjIwMSA4NC42NDY1QzEzMi41OTUgODQuNjQ2NSAxMzIuMDY4IDg0LjU0MzkgMTMxLjYxOSA4NC4zMzg5QzEzMS4xNjkgODQuMTI4OSAxMzAuNzk2IDgzLjg0MDggMTMwLjQ5OCA4My40NzQ2QzEzMC4yIDgzLjEwODQgMTI5Ljk3NiA4Mi42ODYgMTI5LjgyNCA4Mi4yMDc1QzEyOS42NzggODEuNzI5IDEyOS42MDQgODEuMjE2MyAxMjkuNjA0IDgwLjY2OTRWODAuNDEzMUMxMjkuNjA0IDc5Ljg2NjIgMTI5LjY3OCA3OS4zNTM1IDEyOS44MjQgNzguODc1QzEyOS45NzYgNzguMzkxNiAxMzAuMiA3Ny45NjY4IDEzMC40OTggNzcuNjAwNkMxMzAuNzk2IDc3LjIzNDQgMTMxLjE2OSA3Ni45NDg3IDEzMS42MTkgNzYuNzQzN0MxMzIuMDY4IDc2LjUzMzcgMTMyLjU5MyA3Ni40Mjg3IDEzMy4xOTMgNzYuNDI4N0MxMzMuODI4IDc2LjQyODcgMTM0LjM4NSA3Ni41NTU3IDEzNC44NjMgNzYuODA5NkMxMzUuMzQyIDc3LjA1ODYgMTM1LjcxOCA3Ny40MDc3IDEzNS45OTEgNzcuODU2OUMxMzYuMjcgNzguMzAxMyAxMzYuNDE0IDc4LjgxODggMTM2LjQyMyA3OS40MDk3SDEzNC43NjFDMTM0Ljc0NiA3OS4xMTY3IDEzNC42NzMgNzguODUzIDEzNC41NDEgNzguNjE4N0MxMzQuNDE0IDc4LjM3OTQgMTM0LjIzMyA3OC4xODkgMTMzLjk5OSA3OC4wNDc0QzEzMy43NyA3Ny45MDU4IDEzMy40OTQgNzcuODM1IDEzMy4xNzEgNzcuODM1QzEzMi44MTUgNzcuODM1IDEzMi41MiA3Ny45MDgyIDEzMi4yODUgNzguMDU0N0MxMzIuMDUxIDc4LjE5NjMgMTMxLjg2OCA3OC4zOTE2IDEzMS43MzYgNzguNjQwNkMxMzEuNjA0IDc4Ljg4NDggMTMxLjUwOSA3OS4xNjA2IDEzMS40NSA3OS40NjgzQzEzMS4zOTYgNzkuNzcxIDEzMS4zNyA4MC4wODU5IDEzMS4zNyA4MC40MTMxVjgwLjY2OTRDMTMxLjM3IDgwLjk5NjYgMTMxLjM5NiA4MS4zMTQgMTMxLjQ1IDgxLjYyMTZDMTMxLjUwNCA4MS45MjkyIDEzMS41OTcgODIuMjA1MSAxMzEuNzI5IDgyLjQ0OTJDMTMxLjg2NSA4Mi42ODg1IDEzMi4wNTEgODIuODgxMyAxMzIuMjg1IDgzLjAyNzhDMTMyLjUyIDgzLjE2OTQgMTMyLjgxNyA4My4yNDAyIDEzMy4xNzkgODMuMjQwMlpNMTM5LjUyMSA3My4yNVY4NC41SDEzNy43NjRWNzMuMjVIMTM5LjUyMVpNMTM5LjIxNCA4MC4yNDQ2TDEzOC42NDMgODAuMjM3M0MxMzguNjQ3IDc5LjY5MDQgMTM4LjcyMyA3OS4xODUxIDEzOC44NyA3OC43MjEyQzEzOS4wMjEgNzguMjU3MyAxMzkuMjMxIDc3Ljg1NDUgMTM5LjUgNzcuNTEyN0MxMzkuNzczIDc3LjE2NiAxNDAuMSA3Ni44OTk5IDE0MC40ODEgNzYuNzE0NEMxNDAuODYyIDc2LjUyMzkgMTQxLjI4NCA3Ni40Mjg3IDE0MS43NDggNzYuNDI4N0MxNDIuMTM5IDc2LjQyODcgMTQyLjQ5IDc2LjQ4MjQgMTQyLjgwMyA3Ni41ODk4QzE0My4xMiA3Ni42OTczIDE0My4zOTQgNzYuODcwNiAxNDMuNjIzIDc3LjEwOTlDMTQzLjg1MyA3Ny4zNDQyIDE0NC4wMjYgNzcuNjUxOSAxNDQuMTQzIDc4LjAzMjdDMTQ0LjI2NSA3OC40MDg3IDE0NC4zMjYgNzguODY3NyAxNDQuMzI2IDc5LjQwOTdWODQuNUgxNDIuNTU0Vjc5LjM5NUMxNDIuNTU0IDc5LjAxNDIgMTQyLjQ5OCA3OC43MTE0IDE0Mi4zODUgNzguNDg2OEMxNDIuMjc4IDc4LjI2MjIgMTQyLjExOSA3OC4xMDExIDE0MS45MDkgNzguMDAzNEMxNDEuNjk5IDc3LjkwMDkgMTQxLjQ0MyA3Ny44NDk2IDE0MS4xNCA3Ny44NDk2QzE0MC44MjMgNzcuODQ5NiAxNDAuNTQyIDc3LjkxMzEgMTQwLjI5OCA3OC4wNEMxNDAuMDU5IDc4LjE2NyAxMzkuODU4IDc4LjM0MDMgMTM5LjY5NyA3OC41NjAxQzEzOS41MzYgNzguNzc5OCAxMzkuNDE0IDc5LjAzMzcgMTM5LjMzMSA3OS4zMjE4QzEzOS4yNTMgNzkuNjA5OSAxMzkuMjE0IDc5LjkxNzUgMTM5LjIxNCA4MC4yNDQ2WiIgZmlsbD0iYmxhY2siIGZpbGwtb3BhY2l0eT0iMC44NyIvPgo8L2c+CjxkZWZzPgo8Y2xpcFBhdGggaWQ9ImNsaXAwXzM2MzlfMTU1Njc0Ij4KPHJlY3QgeD0iMC41IiB3aWR0aD0iMjAwIiBoZWlnaHQ9IjE2MCIgcng9IjQiIGZpbGw9IndoaXRlIi8+CjwvY2xpcFBhdGg+CjwvZGVmcz4KPC9zdmc+Cg==", + "image": "tb-image:c2luZ2xlLXN3aXRjaC5zdmc=:IlNpbmdsZSBTd2l0Y2giIHN5c3RlbSB3aWRnZXQgaW1hZ2U=;data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAwIiBoZWlnaHQ9IjE2MCIgdmlld0JveD0iMCAwIDIwMCAxNjAiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIyMDAiIGhlaWdodD0iMTYwIiByeD0iNCIgZmlsbD0id2hpdGUiLz4KPHJlY3QgeD0iMzEuNTc3MSIgeT0iNjUuMDc0MiIgd2lkdGg9IjU2Ljk5MDEiIGhlaWdodD0iMjkuODUyIiByeD0iMTQuOTI2IiBmaWxsPSIjNTQ2OUZGIi8+CjxjaXJjbGUgY3g9IjczLjY0MDkiIGN5PSI4MC4wMDAzIiByPSIxMi4yMTIyIiBmaWxsPSJ3aGl0ZSIvPgo8cGF0aCBkPSJNMTA5LjI0MSA4My40NzE3QzEwOS4yNDEgODMuMTQ5NCAxMDkuMTkxIDgyLjg2MyAxMDkuMDkxIDgyLjYxMjNDMTA4Ljk5OCA4Mi4zNjE3IDEwOC44MjkgODIuMTMyNSAxMDguNTg2IDgxLjkyNDhDMTA4LjM0MiA4MS43MTcxIDEwNy45OTkgODEuNTE2NiAxMDcuNTU1IDgxLjMyMzJDMTA3LjExOCA4MS4xMjI3IDEwNi41NTkgODAuOTE4NiAxMDUuODc5IDgwLjcxMDlDMTA1LjEzNCA4MC40ODE4IDEwNC40NDcgODAuMjI3NSAxMDMuODE2IDc5Ljk0ODJDMTAzLjE5MyA3OS42NjE4IDEwMi42NDkgNzkuMzMyNCAxMDIuMTg0IDc4Ljk2QzEwMS43MTggNzguNTgwNCAxMDEuMzU2IDc4LjE0NzEgMTAxLjA5OSA3Ny42NjAyQzEwMC44NDEgNzcuMTY2IDEwMC43MTIgNzYuNTk2NyAxMDAuNzEyIDc1Ljk1MjFDMTAwLjcxMiA3NS4zMTQ4IDEwMC44NDQgNzQuNzM0NyAxMDEuMTA5IDc0LjIxMTlDMTAxLjM4MiA3My42ODkxIDEwMS43NjUgNzMuMjM4IDEwMi4yNTkgNzIuODU4NEMxMDIuNzYgNzIuNDcxNyAxMDMuMzUxIDcyLjE3NDUgMTA0LjAzMSA3MS45NjY4QzEwNC43MTIgNzEuNzUyIDEwNS40NjQgNzEuNjQ0NSAxMDYuMjg3IDcxLjY0NDVDMTA3LjQ0NyA3MS42NDQ1IDEwOC40NDYgNzEuODU5NCAxMDkuMjg0IDcyLjI4OTFDMTEwLjEyOSA3Mi43MTg4IDExMC43NzcgNzMuMjk1MiAxMTEuMjI5IDc0LjAxODZDMTExLjY4NyA3NC43NDE5IDExMS45MTYgNzUuNTQwNCAxMTEuOTE2IDc2LjQxNDFIMTA5LjI0MUMxMDkuMjQxIDc1Ljg5ODQgMTA5LjEzIDc1LjQ0MzcgMTA4LjkwOCA3NS4wNDk4QzEwOC42OTMgNzQuNjQ4OCAxMDguMzY0IDc0LjMzMzcgMTA3LjkyIDc0LjEwNDVDMTA3LjQ4MyA3My44NzUzIDEwNi45MjggNzMuNzYwNyAxMDYuMjU1IDczLjc2MDdDMTA1LjYxOCA3My43NjA3IDEwNS4wODggNzMuODU3NCAxMDQuNjY1IDc0LjA1MDhDMTA0LjI0MyA3NC4yNDQxIDEwMy45MjcgNzQuNTA1NSAxMDMuNzIgNzQuODM1QzEwMy41MTIgNzUuMTY0NCAxMDMuNDA4IDc1LjUzNjggMTAzLjQwOCA3NS45NTIxQzEwMy40MDggNzYuMjQ1OCAxMDMuNDc2IDc2LjUxNDMgMTAzLjYxMiA3Ni43NTc4QzEwMy43NDggNzYuOTk0MSAxMDMuOTU2IDc3LjIxNjEgMTA0LjIzNSA3Ny40MjM4QzEwNC41MTUgNzcuNjI0MyAxMDQuODY2IDc3LjgxNDEgMTA1LjI4OCA3Ny45OTMyQzEwNS43MTEgNzguMTcyMiAxMDYuMjA4IDc4LjM0NDEgMTA2Ljc4MSA3OC41MDg4QzEwNy42NDggNzguNzY2NiAxMDguNDAzIDc5LjA1MzEgMTA5LjA0OCA3OS4zNjgyQzEwOS42OTIgNzkuNjc2MSAxMTAuMjI5IDgwLjAyNyAxMTAuNjU5IDgwLjQyMDlDMTExLjA4OSA4MC44MTQ4IDExMS40MTEgODEuMjYyNCAxMTEuNjI2IDgxLjc2MzdDMTExLjg0MSA4Mi4yNTc4IDExMS45NDggODIuODIgMTExLjk0OCA4My40NTAyQzExMS45NDggODQuMTA5IDExMS44MTYgODQuNzAzNSAxMTEuNTUxIDg1LjIzMzRDMTExLjI4NiA4NS43NTYyIDExMC45MDYgODYuMjAzOCAxMTAuNDEyIDg2LjU3NjJDMTA5LjkyNSA4Ni45NDE0IDEwOS4zMzggODcuMjI0MyAxMDguNjUgODcuNDI0OEMxMDcuOTcgODcuNjE4MiAxMDcuMjExIDg3LjcxNDggMTA2LjM3MyA4Ny43MTQ4QzEwNS42MjEgODcuNzE0OCAxMDQuODggODcuNjE0NiAxMDQuMTQ5IDg3LjQxNDFDMTAzLjQyNiA4Ny4yMTM1IDEwMi43NjcgODYuOTA5MiAxMDIuMTczIDg2LjUwMUMxMDEuNTc4IDg2LjA4NTYgMTAxLjEwNiA4NS41NyAxMDAuNzU1IDg0Ljk1NDFDMTAwLjQwNCA4NC4zMzExIDEwMC4yMjkgODMuNjA0MiAxMDAuMjI5IDgyLjc3MzRIMTAyLjkyNUMxMDIuOTI1IDgzLjI4MTkgMTAzLjAxMSA4My43MTUyIDEwMy4xODMgODQuMDczMkMxMDMuMzYyIDg0LjQzMTMgMTAzLjYwOSA4NC43MjQ5IDEwMy45MjQgODQuOTU0MUMxMDQuMjM5IDg1LjE3NjEgMTA0LjYwNCA4NS4zNDA4IDEwNS4wMiA4NS40NDgyQzEwNS40NDIgODUuNTU1NyAxMDUuODkzIDg1LjYwOTQgMTA2LjM3MyA4NS42MDk0QzEwNy4wMDMgODUuNjA5NCAxMDcuNTMgODUuNTE5OSAxMDcuOTUyIDg1LjM0MDhDMTA4LjM4MiA4NS4xNjE4IDEwOC43MDQgODQuOTExMSAxMDguOTE5IDg0LjU4ODlDMTA5LjEzNCA4NC4yNjY2IDEwOS4yNDEgODMuODk0MiAxMDkuMjQxIDgzLjQ3MTdaTTExNy41NzcgODQuOTIxOUwxMjAuMjYzIDc1Ljg3N0gxMjEuOTE3TDEyMS40NjYgNzguNTg0TDExOC43NTkgODcuNUgxMTcuMjc2TDExNy41NzcgODQuOTIxOVpNMTE1Ljk5OCA3NS44NzdMMTE4LjA5MyA4NC45NjQ4TDExOC4yNjUgODcuNUgxMTYuNjFMMTEzLjQ2MyA3NS44NzdIMTE1Ljk5OFpNMTI0LjQzMSA4NC44NTc0TDEyNi40NjEgNzUuODc3SDEyOC45ODVMMTI1Ljg0OSA4Ny41SDEyNC4xOTRMMTI0LjQzMSA4NC44NTc0Wk0xMjIuMTk2IDc1Ljg3N0wxMjQuODUgODQuODE0NUwxMjUuMTgzIDg3LjVIMTIzLjdMMTIwLjk2MSA3OC41NzMyTDEyMC41MSA3NS44NzdIMTIyLjE5NlpNMTMzLjg2MiA3NS44NzdWODcuNUgxMzEuMjYzVjc1Ljg3N0gxMzMuODYyWk0xMzEuMDkxIDcyLjgyNjJDMTMxLjA5MSA3Mi40MzIzIDEzMS4yMiA3Mi4xMDY0IDEzMS40NzggNzEuODQ4NkMxMzEuNzQzIDcxLjU4MzcgMTMyLjEwOCA3MS40NTEyIDEzMi41NzMgNzEuNDUxMkMxMzMuMDMyIDcxLjQ1MTIgMTMzLjM5MyA3MS41ODM3IDEzMy42NTggNzEuODQ4NkMxMzMuOTIzIDcyLjEwNjQgMTM0LjA1NiA3Mi40MzIzIDEzNC4wNTYgNzIuODI2MkMxMzQuMDU2IDczLjIxMjkgMTMzLjkyMyA3My41MzUyIDEzMy42NTggNzMuNzkzQzEzMy4zOTMgNzQuMDUwOCAxMzMuMDMyIDc0LjE3OTcgMTMyLjU3MyA3NC4xNzk3QzEzMi4xMDggNzQuMTc5NyAxMzEuNzQzIDc0LjA1MDggMTMxLjQ3OCA3My43OTNDMTMxLjIyIDczLjUzNTIgMTMxLjA5MSA3My4yMTI5IDEzMS4wOTEgNzIuODI2MlpNMTQyLjM3IDc1Ljg3N1Y3Ny43Njc2SDEzNS44MTdWNzUuODc3SDE0Mi4zN1pNMTM3LjcwOCA3My4wMzAzSDE0MC4yOTdWODQuMjg4MUMxNDAuMjk3IDg0LjY0NjIgMTQwLjM0NyA4NC45MjE5IDE0MC40NDcgODUuMTE1MkMxNDAuNTU1IDg1LjMwMTQgMTQwLjcwMSA4NS40MjY4IDE0MC44ODggODUuNDkxMkMxNDEuMDc0IDg1LjU1NTcgMTQxLjI5MiA4NS41ODc5IDE0MS41NDMgODUuNTg3OUMxNDEuNzIyIDg1LjU4NzkgMTQxLjg5NCA4NS41NzcxIDE0Mi4wNTkgODUuNTU1N0MxNDIuMjIzIDg1LjUzNDIgMTQyLjM1NiA4NS41MTI3IDE0Mi40NTYgODUuNDkxMkwxNDIuNDY3IDg3LjQ2NzhDMTQyLjI1MiA4Ny41MzIyIDE0Mi4wMDEgODcuNTg5NSAxNDEuNzE1IDg3LjYzOTZDMTQxLjQzNiA4Ny42ODk4IDE0MS4xMTMgODcuNzE0OCAxNDAuNzQ4IDg3LjcxNDhDMTQwLjE1NCA4Ny43MTQ4IDEzOS42MjcgODcuNjExIDEzOS4xNjkgODcuNDAzM0MxMzguNzExIDg3LjE4ODUgMTM4LjM1MyA4Ni44NDExIDEzOC4wOTUgODYuMzYxM0MxMzcuODM3IDg1Ljg4MTUgMTM3LjcwOCA4NS4yNDQxIDEzNy43MDggODQuNDQ5MlY3My4wMzAzWk0xNDkuNDYgODUuNjUyM0MxNDkuODgyIDg1LjY1MjMgMTUwLjI2MiA4NS41NyAxNTAuNTk5IDg1LjQwNTNDMTUwLjk0MiA4NS4yMzM0IDE1MS4yMTggODQuOTk3MSAxNTEuNDI2IDg0LjY5NjNDMTUxLjY0MSA4NC4zOTU1IDE1MS43NTkgODQuMDQ4MiAxNTEuNzggODMuNjU0M0gxNTQuMjE5QzE1NC4yMDQgODQuNDA2MiAxNTMuOTgyIDg1LjA5MDIgMTUzLjU1MyA4NS43MDYxQzE1My4xMjMgODYuMzIxOSAxNTIuNTU0IDg2LjgxMjUgMTUxLjg0NSA4Ny4xNzc3QzE1MS4xMzYgODcuNTM1OCAxNTAuMzUyIDg3LjcxNDggMTQ5LjQ5MiA4Ny43MTQ4QzE0OC42MDQgODcuNzE0OCAxNDcuODMxIDg3LjU2NDUgMTQ3LjE3MiA4Ny4yNjM3QzE0Ni41MTMgODYuOTU1NyAxNDUuOTY1IDg2LjUzMzIgMTQ1LjUyOCA4NS45OTYxQzE0NS4wOTEgODUuNDU5IDE0NC43NjIgODQuODM5NSAxNDQuNTQgODQuMTM3N0MxNDQuMzI1IDgzLjQzNTkgMTQ0LjIxOCA4Mi42ODM5IDE0NC4yMTggODEuODgxOFY4MS41MDU5QzE0NC4yMTggODAuNzAzOCAxNDQuMzI1IDc5Ljk1MTggMTQ0LjU0IDc5LjI1QzE0NC43NjIgNzguNTQxIDE0NS4wOTEgNzcuOTE4IDE0NS41MjggNzcuMzgwOUMxNDUuOTY1IDc2Ljg0MzggMTQ2LjUxMyA3Ni40MjQ4IDE0Ny4xNzIgNzYuMTI0QzE0Ny44MzEgNzUuODE2MSAxNDguNjAxIDc1LjY2MjEgMTQ5LjQ4MSA3NS42NjIxQzE1MC40MTIgNzUuNjYyMSAxNTEuMjI5IDc1Ljg0ODMgMTUxLjkzMSA3Ni4yMjA3QzE1Mi42MzIgNzYuNTg1OSAxNTMuMTg0IDc3LjA5OCAxNTMuNTg1IDc3Ljc1NjhDMTUzLjk5MyA3OC40MDg1IDE1NC4yMDQgNzkuMTY3NiAxNTQuMjE5IDgwLjAzNDJIMTUxLjc4QzE1MS43NTkgNzkuNjA0NSAxNTEuNjUxIDc5LjIxNzggMTUxLjQ1OCA3OC44NzRDMTUxLjI3MiA3OC41MjMxIDE1MS4wMDcgNzguMjQzOCAxNTAuNjYzIDc4LjAzNjFDMTUwLjMyNiA3Ny44Mjg1IDE0OS45MjIgNzcuNzI0NiAxNDkuNDQ5IDc3LjcyNDZDMTQ4LjkyNiA3Ny43MjQ2IDE0OC40OTMgNzcuODMyIDE0OC4xNDkgNzguMDQ2OUMxNDcuODA2IDc4LjI1NDYgMTQ3LjUzNyA3OC41NDEgMTQ3LjM0NCA3OC45MDYyQzE0Ny4xNSA3OS4yNjQzIDE0Ny4wMTEgNzkuNjY4OSAxNDYuOTI1IDgwLjEyMDFDMTQ2Ljg0NiA4MC41NjQxIDE0Ni44MDcgODEuMDI2IDE0Ni44MDcgODEuNTA1OVY4MS44ODE4QzE0Ni44MDcgODIuMzYxNyAxNDYuODQ2IDgyLjgyNzEgMTQ2LjkyNSA4My4yNzgzQzE0Ny4wMDQgODMuNzI5NSAxNDcuMTQgODQuMTM0MSAxNDcuMzMzIDg0LjQ5MjJDMTQ3LjUzNCA4NC44NDMxIDE0Ny44MDYgODUuMTI2IDE0OC4xNDkgODUuMzQwOEMxNDguNDkzIDg1LjU0ODUgMTQ4LjkzIDg1LjY1MjMgMTQ5LjQ2IDg1LjY1MjNaTTE1OS4xMDYgNzFWODcuNUgxNTYuNTI4VjcxSDE1OS4xMDZaTTE1OC42NTUgODEuMjU4OEwxNTcuODE3IDgxLjI0OEMxNTcuODI1IDgwLjQ0NiAxNTcuOTM2IDc5LjcwNDggMTU4LjE1IDc5LjAyNDRDMTU4LjM3MiA3OC4zNDQxIDE1OC42OCA3Ny43NTMzIDE1OS4wNzQgNzcuMjUyQzE1OS40NzUgNzYuNzQzNSAxNTkuOTU1IDc2LjM1MzIgMTYwLjUxNCA3Ni4wODExQzE2MS4wNzIgNzUuODAxOCAxNjEuNjkyIDc1LjY2MjEgMTYyLjM3MiA3NS42NjIxQzE2Mi45NDUgNzUuNjYyMSAxNjMuNDYxIDc1Ljc0MDkgMTYzLjkxOSA3NS44OTg0QzE2NC4zODQgNzYuMDU2IDE2NC43ODUgNzYuMzEwMiAxNjUuMTIyIDc2LjY2MTFDMTY1LjQ1OSA3Ny4wMDQ5IDE2NS43MTMgNzcuNDU2MSAxNjUuODg1IDc4LjAxNDZDMTY2LjA2NCA3OC41NjYxIDE2Ni4xNTMgNzkuMjM5MyAxNjYuMTUzIDgwLjAzNDJWODcuNUgxNjMuNTU0VjgwLjAxMjdDMTYzLjU1NCA3OS40NTQxIDE2My40NzEgNzkuMDEwMSAxNjMuMzA3IDc4LjY4MDdDMTYzLjE0OSA3OC4zNTEyIDE2Mi45MTYgNzguMTE0OSAxNjIuNjA4IDc3Ljk3MTdDMTYyLjMgNzcuODIxMyAxNjEuOTI0IDc3Ljc0NjEgMTYxLjQ4IDc3Ljc0NjFDMTYxLjAxNSA3Ny43NDYxIDE2MC42MDMgNzcuODM5MiAxNjAuMjQ1IDc4LjAyNTRDMTU5Ljg5NCA3OC4yMTE2IDE1OS42MDEgNzguNDY1OCAxNTkuMzY0IDc4Ljc4ODFDMTU5LjEyOCA3OS4xMTA0IDE1OC45NDkgNzkuNDgyNyAxNTguODI3IDc5LjkwNTNDMTU4LjcxMyA4MC4zMjc4IDE1OC42NTUgODAuNzc5IDE1OC42NTUgODEuMjU4OFoiIGZpbGw9ImJsYWNrIiBmaWxsLW9wYWNpdHk9IjAuNzYiLz4KPC9zdmc+Cg==", "description": "Sends the command to the device or updates attribute/time-series when the user toggles the slider. Widget settings will enable you to configure behavior how to fetch the initial state and what to trigger when turn on/off states.", "descriptor": { "type": "rpc", From 147f817445d6d83b94e1de0dffd8e85145c3ff8d Mon Sep 17 00:00:00 2001 From: Igor Kulikov Date: Mon, 5 Feb 2024 18:32:31 +0200 Subject: [PATCH 164/179] UI: Command button widget --- .../json/system/widget_bundles/buttons.json | 3 +- .../system/widget_types/command_button.json | 36 +++++++ .../basic/basic-widget-config.module.ts | 12 ++- ...command-button-basic-config.component.html | 59 ++++++++++++ .../command-button-basic-config.component.ts | 85 +++++++++++++++++ .../single-switch-basic-config.component.html | 2 - .../command-button-widget.component.html | 34 +++++++ .../command-button-widget.component.scss | 28 ++++++ .../button/command-button-widget.component.ts | 94 +++++++++++++++++++ .../button/command-button-widget.models.ts | 71 ++++++++++++++ .../lib/rpc/single-switch-widget.component.ts | 16 ++-- ...mand-button-widget-settings.component.html | 49 ++++++++++ ...ommand-button-widget-settings.component.ts | 68 ++++++++++++++ ...t-value-action-settings-panel.component.ts | 9 +- .../set-value-action-settings.component.ts | 5 - ...ngle-switch-widget-settings.component.html | 2 - .../lib/settings/widget-settings.module.ts | 12 ++- .../widget/widget-components.module.ts | 7 +- .../assets/locale/locale.constant-en_US.json | 5 + 19 files changed, 564 insertions(+), 33 deletions(-) create mode 100644 application/src/main/data/json/system/widget_types/command_button.json create mode 100644 ui-ngx/src/app/modules/home/components/widget/config/basic/button/command-button-basic-config.component.html create mode 100644 ui-ngx/src/app/modules/home/components/widget/config/basic/button/command-button-basic-config.component.ts create mode 100644 ui-ngx/src/app/modules/home/components/widget/lib/button/command-button-widget.component.html create mode 100644 ui-ngx/src/app/modules/home/components/widget/lib/button/command-button-widget.component.scss create mode 100644 ui-ngx/src/app/modules/home/components/widget/lib/button/command-button-widget.component.ts create mode 100644 ui-ngx/src/app/modules/home/components/widget/lib/button/command-button-widget.models.ts create mode 100644 ui-ngx/src/app/modules/home/components/widget/lib/settings/button/command-button-widget-settings.component.html create mode 100644 ui-ngx/src/app/modules/home/components/widget/lib/settings/button/command-button-widget-settings.component.ts diff --git a/application/src/main/data/json/system/widget_bundles/buttons.json b/application/src/main/data/json/system/widget_bundles/buttons.json index b5f728dc25..a48fba892b 100644 --- a/application/src/main/data/json/system/widget_bundles/buttons.json +++ b/application/src/main/data/json/system/widget_bundles/buttons.json @@ -8,6 +8,7 @@ "name": "Buttons" }, "widgetTypeFqns": [ - "action_button" + "action_button", + "command_button" ] } \ No newline at end of file diff --git a/application/src/main/data/json/system/widget_types/command_button.json b/application/src/main/data/json/system/widget_types/command_button.json new file mode 100644 index 0000000000..1ffd2326a8 --- /dev/null +++ b/application/src/main/data/json/system/widget_types/command_button.json @@ -0,0 +1,36 @@ +{ + "fqn": "command_button", + "name": "Command button", + "deprecated": false, + "image": "tb-image:Y29tbWFuZC1idXR0b24uc3Zn:IkNvbW1hbmQgYnV0dG9uIiBzeXN0ZW0gd2lkZ2V0IGltYWdl;data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAwIiBoZWlnaHQ9IjE2MCIgdmlld0JveD0iMCAwIDIwMCAxNjAiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHg9IjAuNzUiIHk9IjUwLjc1IiB3aWR0aD0iMTk4LjUiIGhlaWdodD0iNTguNSIgcng9IjMuMjUiIGZpbGw9IndoaXRlIi8+CjxyZWN0IHg9IjAuNzUiIHk9IjUwLjc1IiB3aWR0aD0iMTk4LjUiIGhlaWdodD0iNTguNSIgcng9IjMuMjUiIHN0cm9rZT0iIzNGNTJERCIgc3Ryb2tlLXdpZHRoPSIxLjUiLz4KPHBhdGggZD0iTTY1LjQ5OTcgNzNWNzUuMzMzM0g3NS41MjEzTDY0LjMzMyA4Ni41MjE3TDY1Ljk3OCA4OC4xNjY3TDc3LjE2NjMgNzYuOTc4M1Y4N0g3OS40OTk3VjczSDY1LjQ5OTdaIiBmaWxsPSIjM0Y1MkREIi8+CjxwYXRoIGQ9Ik0xMDAuNTY0IDgzLjk3MTdDMTAwLjU2NCA4My42NDk0IDEwMC41MTQgODMuMzYzIDEwMC40MTQgODMuMTEyM0MxMDAuMzIxIDgyLjg2MTcgMTAwLjE1MyA4Mi42MzI1IDk5LjkwOTIgODIuNDI0OEM5OS42NjU3IDgyLjIxNzEgOTkuMzIxOSA4Mi4wMTY2IDk4Ljg3NzkgODEuODIzMkM5OC40NDExIDgxLjYyMjcgOTcuODgyNSA4MS40MTg2IDk3LjIwMjEgODEuMjEwOUM5Ni40NTc0IDgwLjk4MTggOTUuNzY5OSA4MC43Mjc1IDk1LjEzOTYgODAuNDQ4MkM5NC41MTY2IDgwLjE2MTggOTMuOTcyMyA3OS44MzI0IDkzLjUwNjggNzkuNDZDOTMuMDQxMyA3OS4wODA0IDkyLjY3OTcgNzguNjQ3MSA5Mi40MjE5IDc4LjE2MDJDOTIuMTY0MSA3Ny42NjYgOTIuMDM1MiA3Ny4wOTY3IDkyLjAzNTIgNzYuNDUyMUM5Mi4wMzUyIDc1LjgxNDggOTIuMTY3NiA3NS4yMzQ3IDkyLjQzMjYgNzQuNzExOUM5Mi43MDQ4IDc0LjE4OTEgOTMuMDg3OSA3My43MzggOTMuNTgyIDczLjM1ODRDOTQuMDgzMyA3Mi45NzE3IDk0LjY3NDIgNzIuNjc0NSA5NS4zNTQ1IDcyLjQ2NjhDOTYuMDM0OCA3Mi4yNTIgOTYuNzg2OCA3Mi4xNDQ1IDk3LjYxMDQgNzIuMTQ0NUM5OC43NzA1IDcyLjE0NDUgOTkuNzY5NSA3Mi4zNTk0IDEwMC42MDcgNzIuNzg5MUMxMDEuNDUyIDczLjIxODggMTAyLjEwMSA3My43OTUyIDEwMi41NTIgNzQuNTE4NkMxMDMuMDEgNzUuMjQxOSAxMDMuMjM5IDc2LjA0MDQgMTAzLjIzOSA3Ni45MTQxSDEwMC41NjRDMTAwLjU2NCA3Ni4zOTg0IDEwMC40NTMgNzUuOTQzNyAxMDAuMjMxIDc1LjU0OThDMTAwLjAxNyA3NS4xNDg4IDk5LjY4NzIgNzQuODMzNyA5OS4yNDMyIDc0LjYwNDVDOTguODA2MyA3NC4zNzUzIDk4LjI1MTMgNzQuMjYwNyA5Ny41NzgxIDc0LjI2MDdDOTYuOTQwOCA3NC4yNjA3IDk2LjQxMDggNzQuMzU3NCA5NS45ODgzIDc0LjU1MDhDOTUuNTY1OCA3NC43NDQxIDk1LjI1MDcgNzUuMDA1NSA5NS4wNDMgNzUuMzM1Qzk0LjgzNTMgNzUuNjY0NCA5NC43MzE0IDc2LjAzNjggOTQuNzMxNCA3Ni40NTIxQzk0LjczMTQgNzYuNzQ1OCA5NC43OTk1IDc3LjAxNDMgOTQuOTM1NSA3Ny4yNTc4Qzk1LjA3MTYgNzcuNDk0MSA5NS4yNzkzIDc3LjcxNjEgOTUuNTU4NiA3Ny45MjM4Qzk1LjgzNzkgNzguMTI0MyA5Ni4xODg4IDc4LjMxNDEgOTYuNjExMyA3OC40OTMyQzk3LjAzMzkgNzguNjcyMiA5Ny41MzE2IDc4Ljg0NDEgOTguMTA0NSA3OS4wMDg4Qzk4Ljk3MSA3OS4yNjY2IDk5LjcyNjYgNzkuNTUzMSAxMDAuMzcxIDc5Ljg2ODJDMTAxLjAxNiA4MC4xNzYxIDEwMS41NTMgODAuNTI3IDEwMS45ODIgODAuOTIwOUMxMDIuNDEyIDgxLjMxNDggMTAyLjczNCA4MS43NjI0IDEwMi45NDkgODIuMjYzN0MxMDMuMTY0IDgyLjc1NzggMTAzLjI3MSA4My4zMiAxMDMuMjcxIDgzLjk1MDJDMTAzLjI3MSA4NC42MDkgMTAzLjEzOSA4NS4yMDM1IDEwMi44NzQgODUuNzMzNEMxMDIuNjA5IDg2LjI1NjIgMTAyLjIyOSA4Ni43MDM4IDEwMS43MzUgODcuMDc2MkMxMDEuMjQ4IDg3LjQ0MTQgMTAwLjY2MSA4Ny43MjQzIDk5Ljk3MzYgODcuOTI0OEM5OS4yOTMzIDg4LjExODIgOTguNTM0MiA4OC4yMTQ4IDk3LjY5NjMgODguMjE0OEM5Ni45NDQzIDg4LjIxNDggOTYuMjAzMSA4OC4xMTQ2IDk1LjQ3MjcgODcuOTE0MUM5NC43NDkzIDg3LjcxMzUgOTQuMDkwNSA4Ny40MDkyIDkzLjQ5NjEgODcuMDAxQzkyLjkwMTcgODYuNTg1NiA5Mi40MjkgODYuMDcgOTIuMDc4MSA4NS40NTQxQzkxLjcyNzIgODQuODMxMSA5MS41NTE4IDg0LjEwNDIgOTEuNTUxOCA4My4yNzM0SDk0LjI0OEM5NC4yNDggODMuNzgxOSA5NC4zMzQgODQuMjE1MiA5NC41MDU5IDg0LjU3MzJDOTQuNjg0OSA4NC45MzEzIDk0LjkzMiA4NS4yMjQ5IDk1LjI0NzEgODUuNDU0MUM5NS41NjIyIDg1LjY3NjEgOTUuOTI3NCA4NS44NDA4IDk2LjM0MjggODUuOTQ4MkM5Ni43NjUzIDg2LjA1NTcgOTcuMjE2NSA4Ni4xMDk0IDk3LjY5NjMgODYuMTA5NEM5OC4zMjY1IDg2LjEwOTQgOTguODUyOSA4Ni4wMTk5IDk5LjI3NTQgODUuODQwOEM5OS43MDUxIDg1LjY2MTggMTAwLjAyNyA4NS40MTExIDEwMC4yNDIgODUuMDg4OUMxMDAuNDU3IDg0Ljc2NjYgMTAwLjU2NCA4NC4zOTQyIDEwMC41NjQgODMuOTcxN1pNMTEwLjc3MiA4OC4yMTQ4QzEwOS45MTMgODguMjE0OCAxMDkuMTM2IDg4LjA3NTIgMTA4LjQ0MSA4Ny43OTU5QzEwNy43NTQgODcuNTA5NCAxMDcuMTY3IDg3LjExMiAxMDYuNjggODYuNjAzNUMxMDYuMiA4Ni4wOTUxIDEwNS44MzEgODUuNDk3MSAxMDUuNTczIDg0LjgwOTZDMTA1LjMxNSA4NC4xMjIxIDEwNS4xODcgODMuMzgwOSAxMDUuMTg3IDgyLjU4NTlWODIuMTU2MkMxMDUuMTg3IDgxLjI0NjcgMTA1LjMxOSA4MC40MjMyIDEwNS41ODQgNzkuNjg1NUMxMDUuODQ5IDc4Ljk0NzkgMTA2LjIxOCA3OC4zMTc3IDEwNi42OSA3Ny43OTQ5QzEwNy4xNjMgNzcuMjY1IDEwNy43MjIgNzYuODYwNCAxMDguMzY2IDc2LjU4MTFDMTA5LjAxMSA3Ni4zMDE4IDEwOS43MDkgNzYuMTYyMSAxMTAuNDYxIDc2LjE2MjFDMTExLjI5MiA3Ni4xNjIxIDExMi4wMTkgNzYuMzAxOCAxMTIuNjQyIDc2LjU4MTFDMTEzLjI2NSA3Ni44NjA0IDExMy43OCA3Ny4yNTQyIDExNC4xODggNzcuNzYyN0MxMTQuNjA0IDc4LjI2NCAxMTQuOTEyIDc4Ljg2MiAxMTUuMTEyIDc5LjU1NjZDMTE1LjMyIDgwLjI1MTMgMTE1LjQyNCA4MS4wMTc2IDExNS40MjQgODEuODU1NVY4Mi45NjE5SDEwNi40NDNWODEuMTAzNUgxMTIuODY3VjgwLjg5OTRDMTEyLjg1MyA4MC40MzM5IDExMi43NiA3OS45OTcxIDExMi41ODggNzkuNTg4OUMxMTIuNDIzIDc5LjE4MDcgMTEyLjE2OSA3OC44NTEyIDExMS44MjUgNzguNjAwNkMxMTEuNDgxIDc4LjM0OTkgMTExLjAyMyA3OC4yMjQ2IDExMC40NSA3OC4yMjQ2QzExMC4wMjEgNzguMjI0NiAxMDkuNjM3IDc4LjMxNzcgMTA5LjMwMSA3OC41MDM5QzEwOC45NzEgNzguNjgyOSAxMDguNjk2IDc4Ljk0NDMgMTA4LjQ3NCA3OS4yODgxQzEwOC4yNTIgNzkuNjMxOCAxMDguMDggODAuMDQ3MiAxMDcuOTU4IDgwLjUzNDJDMTA3Ljg0MyA4MS4wMTQgMTA3Ljc4NiA4MS41NTQ3IDEwNy43ODYgODIuMTU2MlY4Mi41ODU5QzEwNy43ODYgODMuMDk0NCAxMDcuODU0IDgzLjU2NzEgMTA3Ljk5IDg0LjAwMzlDMTA4LjEzMyA4NC40MzM2IDEwOC4zNDEgODQuODA5NiAxMDguNjEzIDg1LjEzMThDMTA4Ljg4NSA4NS40NTQxIDEwOS4yMTUgODUuNzA4MyAxMDkuNjAyIDg1Ljg5NDVDMTA5Ljk4OCA4Ni4wNzM2IDExMC40MjkgODYuMTYzMSAxMTAuOTIzIDg2LjE2MzFDMTExLjU0NiA4Ni4xNjMxIDExMi4xMDEgODYuMDM3OCAxMTIuNTg4IDg1Ljc4NzFDMTEzLjA3NSA4NS41MzY1IDExMy40OTcgODUuMTgyIDExMy44NTUgODQuNzIzNkwxMTUuMjIgODYuMDQ0OUMxMTQuOTY5IDg2LjQxMDIgMTE0LjY0MyA4Ni43NjExIDExNC4yNDIgODcuMDk3N0MxMTMuODQxIDg3LjQyNzEgMTEzLjM1MSA4Ny42OTU2IDExMi43NzEgODcuOTAzM0MxMTIuMTk4IDg4LjExMSAxMTEuNTMyIDg4LjIxNDggMTEwLjc3MiA4OC4yMTQ4Wk0xMjAuMjYxIDc4Ljg1ODRWODhIMTE3LjY3MlY3Ni4zNzdIMTIwLjExTDEyMC4yNjEgNzguODU4NFpNMTE5Ljc5OSA4MS43NTg4TDExOC45NjEgODEuNzQ4QzExOC45NjggODAuOTI0NSAxMTkuMDgzIDgwLjE2ODkgMTE5LjMwNSA3OS40ODE0QzExOS41MzQgNzguNzkzOSAxMTkuODQ5IDc4LjIwMzEgMTIwLjI1IDc3LjcwOUMxMjAuNjU4IDc3LjIxNDggMTIxLjE0NSA3Ni44MzUzIDEyMS43MTEgNzYuNTcwM0MxMjIuMjc3IDc2LjI5ODIgMTIyLjkwNyA3Ni4xNjIxIDEyMy42MDIgNzYuMTYyMUMxMjQuMTYgNzYuMTYyMSAxMjQuNjY1IDc2LjI0MDkgMTI1LjExNiA3Ni4zOTg0QzEyNS41NzUgNzYuNTQ4OCAxMjUuOTY1IDc2Ljc5NTkgMTI2LjI4NyA3Ny4xMzk2QzEyNi42MTcgNzcuNDgzNCAxMjYuODY3IDc3LjkzMSAxMjcuMDM5IDc4LjQ4MjRDMTI3LjIxMSA3OS4wMjY3IDEyNy4yOTcgNzkuNjk2MyAxMjcuMjk3IDgwLjQ5MTJWODhIMTI0LjY5N1Y4MC40ODA1QzEyNC42OTcgNzkuOTIxOSAxMjQuNjE1IDc5LjQ4MTQgMTI0LjQ1IDc5LjE1OTJDMTI0LjI5MyA3OC44Mjk4IDEyNC4wNiA3OC41OTcgMTIzLjc1MiA3OC40NjA5QzEyMy40NTEgNzguMzE3NyAxMjMuMDc1IDc4LjI0NjEgMTIyLjYyNCA3OC4yNDYxQzEyMi4xOCA3OC4yNDYxIDEyMS43ODMgNzguMzM5MiAxMjEuNDMyIDc4LjUyNTRDMTIxLjA4MSA3OC43MTE2IDEyMC43ODQgNzguOTY1OCAxMjAuNTQgNzkuMjg4MUMxMjAuMzA0IDc5LjYxMDQgMTIwLjEyMSA3OS45ODI3IDExOS45OTIgODAuNDA1M0MxMTkuODYzIDgwLjgyNzggMTE5Ljc5OSA4MS4yNzkgMTE5Ljc5OSA4MS43NTg4Wk0xMzcuMjc5IDg1LjU5MzhWNzEuNUgxMzkuODc5Vjg4SDEzNy41MjZMMTM3LjI3OSA4NS41OTM4Wk0xMjkuNzE3IDgyLjMxNzRWODIuMDkxOEMxMjkuNzE3IDgxLjIxMDkgMTI5LjgyMSA4MC40MDg5IDEzMC4wMjggNzkuNjg1NUMxMzAuMjM2IDc4Ljk1NTEgMTMwLjUzNyA3OC4zMjg1IDEzMC45MzEgNzcuODA1N0MxMzEuMzI1IDc3LjI3NTcgMTMxLjgwNCA3Ni44NzExIDEzMi4zNyA3Ni41OTE4QzEzMi45MzYgNzYuMzA1MyAxMzMuNTczIDc2LjE2MjEgMTM0LjI4MiA3Ni4xNjIxQzEzNC45ODQgNzYuMTYyMSAxMzUuNiA3Ni4yOTgyIDEzNi4xMyA3Ni41NzAzQzEzNi42NiA3Ni44NDI0IDEzNy4xMTEgNzcuMjMyNyAxMzcuNDgzIDc3Ljc0MTJDMTM3Ljg1NiA3OC4yNDI1IDEzOC4xNTMgNzguODQ0MSAxMzguMzc1IDc5LjU0NTlDMTM4LjU5NyA4MC4yNDA2IDEzOC43NTUgODEuMDE0IDEzOC44NDggODEuODY2MlY4Mi41ODU5QzEzOC43NTUgODMuNDE2NyAxMzguNTk3IDg0LjE3NTggMTM4LjM3NSA4NC44NjMzQzEzOC4xNTMgODUuNTUwOCAxMzcuODU2IDg2LjE0NTIgMTM3LjQ4MyA4Ni42NDY1QzEzNy4xMTEgODcuMTQ3OCAxMzYuNjU2IDg3LjUzNDUgMTM2LjExOSA4Ny44MDY2QzEzNS41ODkgODguMDc4OCAxMzQuOTcgODguMjE0OCAxMzQuMjYxIDg4LjIxNDhDMTMzLjU1OSA4OC4yMTQ4IDEzMi45MjUgODguMDY4IDEzMi4zNTkgODcuNzc0NEMxMzEuODAxIDg3LjQ4MDggMTMxLjMyNSA4Ny4wNjkgMTMwLjkzMSA4Ni41MzkxQzEzMC41MzcgODYuMDA5MSAxMzAuMjM2IDg1LjM4NjEgMTMwLjAyOCA4NC42Njk5QzEyOS44MjEgODMuOTQ2NiAxMjkuNzE3IDgzLjE2MjQgMTI5LjcxNyA4Mi4zMTc0Wk0xMzIuMzA2IDgyLjA5MThWODIuMzE3NEMxMzIuMzA2IDgyLjg0NzMgMTMyLjM1MiA4My4zNDE1IDEzMi40NDUgODMuNzk5OEMxMzIuNTQ2IDg0LjI1ODEgMTMyLjcgODQuNjYyOCAxMzIuOTA3IDg1LjAxMzdDMTMzLjExNSA4NS4zNTc0IDEzMy4zODMgODUuNjI5NiAxMzMuNzEzIDg1LjgzMDFDMTM0LjA0OSA4Ni4wMjM0IDEzNC40NTEgODYuMTIwMSAxMzQuOTE2IDg2LjEyMDFDMTM1LjUwMyA4Ni4xMjAxIDEzNS45ODcgODUuOTkxMiAxMzYuMzY2IDg1LjczMzRDMTM2Ljc0NiA4NS40NzU2IDEzNy4wNDMgODUuMTI4MyAxMzcuMjU4IDg0LjY5MTRDMTM3LjQ4IDg0LjI0NzQgMTM3LjYzIDgzLjc1MzMgMTM3LjcwOSA4My4yMDlWODEuMjY0NkMxMzcuNjY2IDgwLjg0MjEgMTM3LjU3NiA4MC40NDgyIDEzNy40NCA4MC4wODNDMTM3LjMxMiA3OS43MTc4IDEzNy4xMzYgNzkuMzk5MSAxMzYuOTE0IDc5LjEyN0MxMzYuNjkyIDc4Ljg0NzcgMTM2LjQxNiA3OC42MzI4IDEzNi4wODcgNzguNDgyNEMxMzUuNzY1IDc4LjMyNDkgMTM1LjM4MiA3OC4yNDYxIDEzNC45MzggNzguMjQ2MUMxMzQuNDY1IDc4LjI0NjEgMTM0LjA2NCA3OC4zNDY0IDEzMy43MzQgNzguNTQ2OUMxMzMuNDA1IDc4Ljc0NzQgMTMzLjEzMyA3OS4wMjMxIDEzMi45MTggNzkuMzc0QzEzMi43MSA3OS43MjQ5IDEzMi41NTYgODAuMTMzMSAxMzIuNDU2IDgwLjU5ODZDMTMyLjM1NiA4MS4wNjQxIDEzMi4zMDYgODEuNTYxOCAxMzIuMzA2IDgyLjA5MThaIiBmaWxsPSIjM0Y1MkREIi8+Cjwvc3ZnPgo=", + "description": "Sends the command to the device or updates attribute/time-series when the user clicks the button. Widget settings will enable you to configure behavior how to fetch the initial state and what to trigger when click.", + "descriptor": { + "type": "rpc", + "sizeX": 3, + "sizeY": 1, + "resources": [], + "templateHtml": "\n", + "templateCss": "", + "controllerScript": "self.onInit = function() {\n self.ctx.$scope.actionWidget.onInit();\n}\n\nself.typeParameters = function() {\n return {\n previewWidth: '200px',\n previewHeight: '80px',\n embedTitlePanel: true,\n overflowVisible: true,\n displayRpcMessageToast: false\n };\n};\n\nself.onDestroy = function() {\n}\n", + "settingsSchema": "", + "dataKeySettingsSchema": "{}\n", + "settingsDirective": "tb-command-button-widget-settings", + "hasBasicMode": true, + "basicModeDirective": "tb-command-button-basic-config", + "defaultConfig": "{\"showTitle\":false,\"backgroundColor\":\"rgba(255, 255, 255, 0)\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"0px\",\"settings\":{},\"title\":\"Command button\",\"dropShadow\":false,\"enableFullscreen\":false,\"widgetStyle\":{},\"actions\":{},\"widgetCss\":\"\",\"noDataDisplayMessage\":\"\",\"titleFont\":{\"size\":12,\"sizeUnit\":\"px\",\"family\":null,\"weight\":null,\"style\":null,\"lineHeight\":\"1.6\"},\"showTitleIcon\":false,\"titleTooltip\":\"\",\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"pageSize\":1024,\"titleIcon\":\"\",\"iconColor\":\"rgba(0, 0, 0, 0.87)\",\"iconSize\":\"14px\",\"configMode\":\"basic\",\"borderRadius\":\"4px\"}" + }, + "tags": [ + "command", + "downlink", + "device configuration", + "device control", + "invocation", + "remote method", + "remote function", + "interface", + "subroutine call", + "inter-process communication", + "server request", + "button" + ] +} \ No newline at end of file diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/basic-widget-config.module.ts b/ui-ngx/src/app/modules/home/components/widget/config/basic/basic-widget-config.module.ts index 7c19993eb1..bb31daf7bb 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/basic/basic-widget-config.module.ts +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/basic-widget-config.module.ts @@ -97,6 +97,9 @@ import { import { ActionButtonBasicConfigComponent } from '@home/components/widget/config/basic/button/action-button-basic-config.component'; +import { + CommandButtonBasicConfigComponent +} from '@home/components/widget/config/basic/button/command-button-basic-config.component'; @NgModule({ declarations: [ @@ -127,7 +130,8 @@ import { RangeChartBasicConfigComponent, BarChartWithLabelsBasicConfigComponent, SingleSwitchBasicConfigComponent, - ActionButtonBasicConfigComponent + ActionButtonBasicConfigComponent, + CommandButtonBasicConfigComponent ], imports: [ CommonModule, @@ -162,7 +166,8 @@ import { RangeChartBasicConfigComponent, BarChartWithLabelsBasicConfigComponent, SingleSwitchBasicConfigComponent, - ActionButtonBasicConfigComponent + ActionButtonBasicConfigComponent, + CommandButtonBasicConfigComponent ] }) export class BasicWidgetConfigModule { @@ -191,5 +196,6 @@ export const basicWidgetConfigComponentsMap: {[key: string]: Type + + +
+
widgets.command-button.behavior
+
+
widgets.command-button.on-click
+ +
+
+
widgets.button-state.disabled-state
+ +
+
+
+
widget-config.appearance
+ + +
+
+
widget-config.card-appearance
+
+
{{ 'widget-config.card-border-radius' | translate }}
+ + + +
+
+
diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/button/command-button-basic-config.component.ts b/ui-ngx/src/app/modules/home/components/widget/config/basic/button/command-button-basic-config.component.ts new file mode 100644 index 0000000000..2d7d7fc1cc --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/button/command-button-basic-config.component.ts @@ -0,0 +1,85 @@ +/// +/// Copyright © 2016-2024 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 { Component } from '@angular/core'; +import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms'; +import { Store } from '@ngrx/store'; +import { AppState } from '@core/core.state'; +import { BasicWidgetConfigComponent } from '@home/components/widget/config/widget-config.component.models'; +import { WidgetConfigComponentData } from '@home/models/widget-component.models'; +import { TargetDevice, } from '@shared/models/widget.models'; +import { WidgetConfigComponent } from '@home/components/widget/widget-config.component'; +import { ValueType } from '@shared/models/constants'; +import { + commandButtonDefaultSettings, + CommandButtonWidgetSettings +} from '@home/components/widget/lib/button/command-button-widget.models'; + +@Component({ + selector: 'tb-command-button-basic-config', + templateUrl: './command-button-basic-config.component.html', + styleUrls: ['../basic-config.scss'] +}) +export class CommandButtonBasicConfigComponent extends BasicWidgetConfigComponent { + + get targetDevice(): TargetDevice { + return this.commandButtonWidgetConfigForm.get('targetDevice').value; + } + + valueType = ValueType; + + commandButtonWidgetConfigForm: UntypedFormGroup; + + constructor(protected store: Store, + protected widgetConfigComponent: WidgetConfigComponent, + private fb: UntypedFormBuilder) { + super(store, widgetConfigComponent); + } + + protected configForm(): UntypedFormGroup { + return this.commandButtonWidgetConfigForm; + } + + protected onConfigSet(configData: WidgetConfigComponentData) { + const settings: CommandButtonWidgetSettings = {...commandButtonDefaultSettings, ...(configData.config.settings || {})}; + this.commandButtonWidgetConfigForm = this.fb.group({ + targetDevice: [configData.config.targetDevice, []], + + onClickState: [settings.onClickState, []], + disabledState: [settings.disabledState, []], + + appearance: [settings.appearance, []], + + borderRadius: [configData.config.borderRadius, []] + }); + } + + protected prepareOutputConfig(config: any): WidgetConfigComponentData { + + this.widgetConfig.config.targetDevice = config.targetDevice; + + this.widgetConfig.config.settings = this.widgetConfig.config.settings || {}; + + this.widgetConfig.config.settings.onClickState = config.onClickState; + this.widgetConfig.config.settings.disabledState = config.disabledState; + + this.widgetConfig.config.settings.appearance = config.appearance; + + this.widgetConfig.config.borderRadius = config.borderRadius; + + return this.widgetConfig; + } +} diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/rpc/single-switch-basic-config.component.html b/ui-ngx/src/app/modules/home/components/widget/config/basic/rpc/single-switch-basic-config.component.html index df495e32df..18fa3b5587 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/basic/rpc/single-switch-basic-config.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/rpc/single-switch-basic-config.component.html @@ -36,7 +36,6 @@
widgets.rpc-state.turn-on
widgets.rpc-state.turn-off
+
+
+ +
+ + +
+
+
+ +
+
+
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/button/command-button-widget.component.scss b/ui-ngx/src/app/modules/home/components/widget/lib/button/command-button-widget.component.scss new file mode 100644 index 0000000000..bdaa0c0eea --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/lib/button/command-button-widget.component.scss @@ -0,0 +1,28 @@ +/** + * Copyright © 2016-2024 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +.tb-command-button-widget { + width: 100%; + height: 100%; + position: relative; + + > div.tb-command-button-widget-title-panel { + position: absolute; + top: 12px; + left: 12px; + right: 12px; + z-index: 2; + } +} diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/button/command-button-widget.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/button/command-button-widget.component.ts new file mode 100644 index 0000000000..b687001757 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/lib/button/command-button-widget.component.ts @@ -0,0 +1,94 @@ +/// +/// Copyright © 2016-2024 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 { AfterViewInit, ChangeDetectorRef, Component, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core'; +import { BasicActionWidgetComponent, ValueSetter } from '@home/components/widget/lib/action/action-widget.models'; +import { ImagePipe } from '@shared/pipe/image.pipe'; +import { DomSanitizer } from '@angular/platform-browser'; +import { ValueType } from '@shared/models/constants'; +import { WidgetButtonAppearance } from '@shared/components/button/widget-button.models'; +import { + commandButtonDefaultSettings, + CommandButtonWidgetSettings +} from '@home/components/widget/lib/button/command-button-widget.models'; + +@Component({ + selector: 'tb-command-button-widget', + templateUrl: './command-button-widget.component.html', + styleUrls: ['../action/action-widget.scss', './command-button-widget.component.scss'], + encapsulation: ViewEncapsulation.None +}) +export class CommandButtonWidgetComponent extends + BasicActionWidgetComponent implements OnInit, AfterViewInit, OnDestroy { + + settings: CommandButtonWidgetSettings; + + disabled = false; + + appearance: WidgetButtonAppearance; + borderRadius = '4px'; + + private clickValueSetter: ValueSetter; + + constructor(protected imagePipe: ImagePipe, + protected sanitizer: DomSanitizer, + protected cd: ChangeDetectorRef) { + super(cd); + } + + ngOnInit(): void { + super.ngOnInit(); + this.settings = {...commandButtonDefaultSettings, ...this.ctx.settings}; + + this.appearance = this.settings.appearance; + + const disabledStateSettings = + {...this.settings.disabledState, actionLabel: this.ctx.translate.instant('widgets.button-state.disabled-state')}; + this.createValueGetter(disabledStateSettings, ValueType.BOOLEAN, { + next: (value) => this.onDisabled(value) + }); + + const onClickStateSettings = {...this.settings.onClickState, + actionLabel: this.ctx.translate.instant('widgets.command-button.on-click')}; + this.clickValueSetter = this.createValueSetter(onClickStateSettings); + } + + ngAfterViewInit(): void { + super.ngAfterViewInit(); + } + + ngOnDestroy() { + super.ngOnDestroy(); + } + + public onInit() { + super.onInit(); + this.borderRadius = this.ctx.$widgetElement.css('borderRadius'); + this.cd.detectChanges(); + } + + public onClick(_$event: MouseEvent) { + if (!this.ctx.isEdit && !this.ctx.isPreview) { + this.updateValue(this.clickValueSetter, null); + } + } + + private onDisabled(value: boolean): void { + this.disabled = !!value; + this.cd.markForCheck(); + } + +} diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/button/command-button-widget.models.ts b/ui-ngx/src/app/modules/home/components/widget/lib/button/command-button-widget.models.ts new file mode 100644 index 0000000000..87d4706fc8 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/lib/button/command-button-widget.models.ts @@ -0,0 +1,71 @@ +/// +/// Copyright © 2016-2024 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 { WidgetButtonAppearance, widgetButtonDefaultAppearance } from '@shared/components/button/widget-button.models'; +import { + DataToValueType, + GetValueAction, + GetValueSettings, SetValueAction, + SetValueSettings, ValueToDataType +} from '@shared/models/action-widget-settings.models'; +import { AttributeScope } from '@shared/models/telemetry/telemetry.models'; + +export interface CommandButtonWidgetSettings { + appearance: WidgetButtonAppearance; + onClickState: SetValueSettings; + disabledState: GetValueSettings; +} + +export const commandButtonDefaultSettings: CommandButtonWidgetSettings = { + appearance: {...widgetButtonDefaultAppearance, label: 'Send', icon: 'arrow_outward'}, + onClickState: { + action: SetValueAction.EXECUTE_RPC, + executeRpc: { + method: 'setState', + requestTimeout: 5000, + requestPersistent: false, + persistentPollingInterval: 1000 + }, + setAttribute: { + key: 'state', + scope: AttributeScope.SHARED_SCOPE + }, + putTimeSeries: { + key: 'state' + }, + valueToData: { + type: ValueToDataType.NONE, + constantValue: true, + valueToDataFunction: '/* Return RPC parameters or attribute/time-series value */\nreturn true;' + } + }, + disabledState: { + action: GetValueAction.DO_NOTHING, + defaultValue: false, + getAttribute: { + key: 'state', + scope: null + }, + getTimeSeries: { + key: 'state' + }, + dataToValue: { + type: DataToValueType.NONE, + compareToValue: true, + dataToValueFunction: '/* Should return boolean value */\nreturn data;' + } + } +}; diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/rpc/single-switch-widget.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/rpc/single-switch-widget.component.ts index 1103afde39..a767d22408 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/rpc/single-switch-widget.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/rpc/single-switch-widget.component.ts @@ -211,13 +211,15 @@ export class SingleSwitchWidgetComponent extends } public onToggleChange(event: MouseEvent) { - event.preventDefault(); - const targetValue = this.value; - const targetSetter = targetValue ? this.onValueSetter : this.offValueSetter; - this.updateValue(targetSetter, targetValue, { - next: () => this.onValue(targetValue), - error: () => this.onValue(!targetValue) - }); + if (!this.ctx.isEdit && !this.ctx.isPreview) { + event.preventDefault(); + const targetValue = this.value; + const targetSetter = targetValue ? this.onValueSetter : this.offValueSetter; + this.updateValue(targetSetter, targetValue, { + next: () => this.onValue(targetValue), + error: () => this.onValue(!targetValue) + }); + } } private onValue(value: boolean): void { diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/button/command-button-widget-settings.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/button/command-button-widget-settings.component.html new file mode 100644 index 0000000000..29f3833983 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/button/command-button-widget-settings.component.html @@ -0,0 +1,49 @@ + + +
+
widgets.command-button.behavior
+
+
widgets.command-button.on-click
+ +
+
+
widgets.button-state.disabled-state
+ +
+
+
+
widget-config.appearance
+ + +
+
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/button/command-button-widget-settings.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/button/command-button-widget-settings.component.ts new file mode 100644 index 0000000000..ff34a28503 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/button/command-button-widget-settings.component.ts @@ -0,0 +1,68 @@ +/// +/// Copyright © 2016-2024 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 { Component } from '@angular/core'; +import { TargetDevice, WidgetSettings, WidgetSettingsComponent, widgetType } from '@shared/models/widget.models'; +import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms'; +import { Store } from '@ngrx/store'; +import { AppState } from '@core/core.state'; +import { ValueType } from '@shared/models/constants'; +import { commandButtonDefaultSettings } from '@home/components/widget/lib/button/command-button-widget.models'; + +@Component({ + selector: 'tb-command-button-widget-settings', + templateUrl: './command-button-widget-settings.component.html', + styleUrls: ['./../widget-settings.scss'] +}) +export class CommandButtonWidgetSettingsComponent extends WidgetSettingsComponent { + + get targetDevice(): TargetDevice { + return this.widgetConfig?.config?.targetDevice; + } + + get widgetType(): widgetType { + return this.widgetConfig?.widgetType; + } + get borderRadius(): string { + return this.widgetConfig?.config?.borderRadius; + } + + valueType = ValueType; + + commandButtonWidgetSettingsForm: UntypedFormGroup; + + constructor(protected store: Store, + private fb: UntypedFormBuilder) { + super(store); + } + + protected settingsForm(): UntypedFormGroup { + return this.commandButtonWidgetSettingsForm; + } + + protected defaultSettings(): WidgetSettings { + return {...commandButtonDefaultSettings}; + } + + protected onSettingsSet(settings: WidgetSettings) { + this.commandButtonWidgetSettingsForm = this.fb.group({ + onClickState: [settings.onClickState, []], + disabledState: [settings.disabledState, []], + + appearance: [settings.appearance, []] + }); + } +} diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/set-value-action-settings-panel.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/set-value-action-settings-panel.component.ts index 37b8f4d37a..d718168b11 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/set-value-action-settings-panel.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/set-value-action-settings-panel.component.ts @@ -22,14 +22,12 @@ import { Store } from '@ngrx/store'; import { AppState } from '@core/core.state'; import { merge } from 'rxjs'; import { - getValueActions, SetValueAction, - setValueActions, setValueActionsByWidgetType, + setValueActionsByWidgetType, setValueActionTranslations, SetValueSettings, ValueToDataType } from '@shared/models/action-widget-settings.models'; -import { ValueType } from '@shared/models/constants'; import { TargetDevice, widgetType } from '@shared/models/widget.models'; import { AttributeScope, DataKeyType, telemetryTypeTranslationsShort } from '@shared/models/telemetry/telemetry.models'; import { IAliasController } from '@core/api/widget-api.models'; @@ -50,9 +48,6 @@ export class SetValueActionSettingsPanelComponent extends PageComponent implemen @Input() setValueSettings: SetValueSettings; - @Input() - valueType: ValueType; - @Input() aliasController: IAliasController; @@ -84,8 +79,6 @@ export class SetValueActionSettingsPanelComponent extends PageComponent implemen functionScopeVariables = this.widgetService.getWidgetScopeVariables(); - ValueType = ValueType; - setValueSettingsFormGroup: UntypedFormGroup; constructor(private fb: UntypedFormBuilder, diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/set-value-action-settings.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/set-value-action-settings.component.ts index c29cab1643..fce1e23673 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/set-value-action-settings.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/set-value-action-settings.component.ts @@ -30,7 +30,6 @@ import { MatButton } from '@angular/material/button'; import { TbPopoverService } from '@shared/components/popover.service'; import { SetValueAction, SetValueSettings, ValueToDataType } from '@shared/models/action-widget-settings.models'; import { TranslateService } from '@ngx-translate/core'; -import { ValueType } from '@shared/models/constants'; import { IAliasController } from '@core/api/widget-api.models'; import { TargetDevice, widgetType } from '@shared/models/widget.models'; import { isDefinedAndNotNull } from '@core/utils'; @@ -59,9 +58,6 @@ export class SetValueActionSettingsComponent implements OnInit, ControlValueAcce @Input() panelTitle: string; - @Input() - valueType: ValueType; - @Input() aliasController: IAliasController; @@ -118,7 +114,6 @@ export class SetValueActionSettingsComponent implements OnInit, ControlValueAcce const ctx: any = { setValueSettings: this.modelValue, panelTitle: this.panelTitle, - valueType: this.valueType, aliasController: this.aliasController, targetDevice: this.targetDevice, widgetType: this.widgetType diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/single-switch-widget-settings.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/single-switch-widget-settings.component.html index b498116317..9350c2d932 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/single-switch-widget-settings.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/control/single-switch-widget-settings.component.html @@ -35,7 +35,6 @@
widgets.rpc-state.turn-on
widgets.rpc-state.turn-off
Date: Mon, 5 Feb 2024 19:54:04 +0200 Subject: [PATCH 165/179] UI: add pattern support for labels to button widgets. --- .../action-button-widget.component.html | 1 + .../command-button-widget.component.html | 1 + ...t-button-custom-style-panel.component.html | 1 + ...get-button-custom-style-panel.component.ts | 30 +++++++++++++++++-- .../button/widget-button.component.html | 2 +- .../button/widget-button.component.ts | 19 +++++++++++- 6 files changed, 49 insertions(+), 5 deletions(-) diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/button/action-button-widget.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/button/action-button-widget.component.html index f667e63356..02e2406859 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/button/action-button-widget.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/button/action-button-widget.component.html @@ -24,6 +24,7 @@ [borderRadius]="borderRadius" [disabled]="disabled" [activated]="activated" + [ctx]="ctx" (clicked)="onClick($event)">
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/button/command-button-widget.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/button/command-button-widget.component.html index eaf93c2498..a6f01edb67 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/button/command-button-widget.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/button/command-button-widget.component.html @@ -23,6 +23,7 @@ [appearance]="appearance" [borderRadius]="borderRadius" [disabled]="disabled" + [ctx]="ctx" (clicked)="onClick($event)">
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/button/widget-button-custom-style-panel.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/button/widget-button-custom-style-panel.component.html index 7e4a316eef..e5750fd4bb 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/button/widget-button-custom-style-panel.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/button/widget-button-custom-style-panel.component.html @@ -48,6 +48,7 @@ widgets.button.preview
; + @Input() - popover: TbPopoverComponent; + set popover(popover: TbPopoverComponent) { + this.popoverValue = popover; + popover.tbAnimationDone.subscribe(() => { + this.widgetButtonPreview?.validateSize(); + }); + } + + get popover(): TbPopoverComponent { + return this.popoverValue; + } @Output() customStyleApplied = new EventEmitter(); @@ -125,7 +149,7 @@ export class WidgetButtonCustomStylePanelComponent extends PageComponent impleme if (customStyle?.overrideBackgroundColor) { backgroundColor = customStyle?.backgroundColor; } - let dropShadow = this.appearance.type === WidgetButtonType.basic ? false : true; + let dropShadow = this.appearance.type !== WidgetButtonType.basic; if (customStyle?.overrideDropShadow) { dropShadow = customStyle?.dropShadow; } diff --git a/ui-ngx/src/app/shared/components/button/widget-button.component.html b/ui-ngx/src/app/shared/components/button/widget-button.component.html index 9b239db068..03b5dfb75a 100644 --- a/ui-ngx/src/app/shared/components/button/widget-button.component.html +++ b/ui-ngx/src/app/shared/components/button/widget-button.component.html @@ -34,6 +34,6 @@ [style.pointer-events]="disableEvents ? 'none' : ''">
{{ appearance.icon }} - {{ appearance.label }} + {{ label$ | async }}
diff --git a/ui-ngx/src/app/shared/components/button/widget-button.component.ts b/ui-ngx/src/app/shared/components/button/widget-button.component.ts index d8fe88b48e..059f263196 100644 --- a/ui-ngx/src/app/shared/components/button/widget-button.component.ts +++ b/ui-ngx/src/app/shared/components/button/widget-button.component.ts @@ -25,7 +25,8 @@ import { OnInit, Output, Renderer2, - SimpleChanges, ViewChild, + SimpleChanges, + ViewChild, ViewEncapsulation } from '@angular/core'; import { @@ -36,6 +37,8 @@ import { coerceBoolean } from '@shared/decorators/coercion'; import { ComponentStyle, iconStyle } from '@shared/models/widget-settings.models'; import { UtilsService } from '@core/services/utils.service'; import { ResizeObserver } from '@juggle/resize-observer'; +import { Observable, of } from 'rxjs'; +import { WidgetContext } from '@home/models/widget-component.models'; const initialButtonHeight = 60; const horizontalLayoutPadding = 24; @@ -81,9 +84,14 @@ export class WidgetButtonComponent implements OnInit, AfterViewInit, OnDestroy, @coerceBoolean() disableEvents = false; + @Input() + ctx: WidgetContext; + @Output() clicked = new EventEmitter(); + label$: Observable; + iconStyle: ComponentStyle = {}; mousePressed = false; @@ -122,11 +130,20 @@ export class WidgetButtonComponent implements OnInit, AfterViewInit, OnDestroy, this.clearAppearanceCss(); } + public validateSize() { + if (this.appearance.autoScale && this.widgetButton.nativeElement) { + this.onResize(); + } + } + private updateAppearance(): void { this.clearAppearanceCss(); if (this.appearance.showIcon) { this.iconStyle = iconStyle(this.appearance.iconSize, this.appearance.iconSizeUnit); } + if (this.appearance.showLabel) { + this.label$ = this.ctx ? this.ctx.registerLabelPattern(this.appearance.label, this.label$) : of(this.appearance.label); + } const appearanceCss = generateWidgetButtonAppearanceCss(this.appearance); this.appearanceCssClass = this.utils.applyCssToElement(this.renderer, this.elementRef.nativeElement, 'tb-widget-button', appearanceCss); From 495e34c33718a32b7294c99afeccd362459f011c Mon Sep 17 00:00:00 2001 From: Igor Kulikov Date: Tue, 6 Feb 2024 10:18:54 +0200 Subject: [PATCH 166/179] UI: Improve command button widget loading style. Improve single switch widget disabled state style. --- .../dashboard-page.component.ts | 22 +++++-------- .../widget/lib/action/action-widget.scss | 6 ++++ .../command-button-widget.component.html | 3 +- .../rpc/single-switch-widget.component.html | 14 +++++--- .../rpc/single-switch-widget.component.scss | 6 ---- .../lib/rpc/single-switch-widget.component.ts | 33 ++----------------- 6 files changed, 27 insertions(+), 57 deletions(-) diff --git a/ui-ngx/src/app/modules/home/components/dashboard-page/dashboard-page.component.ts b/ui-ngx/src/app/modules/home/components/dashboard-page/dashboard-page.component.ts index f873743340..fe6364cc09 100644 --- a/ui-ngx/src/app/modules/home/components/dashboard-page/dashboard-page.component.ts +++ b/ui-ngx/src/app/modules/home/components/dashboard-page/dashboard-page.component.ts @@ -1049,26 +1049,20 @@ export class DashboardPageComponent extends PageComponent implements IDashboardC this.onAddWidgetClosed(); this.isAddingWidgetClosed = true; } - if (this.widgetEditMode) { - if (revert) { - this.dashboard = this.prevDashboard; - this.dashboardLogoCache = undefined; - this.dashboardConfiguration = this.dashboard.configuration; - } - } else { - this.resetHighlight(); - if (revert) { - this.dashboard = this.prevDashboard; - this.dashboardLogoCache = undefined; - this.dashboardConfiguration = this.dashboard.configuration; + this.resetHighlight(); + if (revert) { + this.dashboard = this.prevDashboard; + this.dashboardLogoCache = undefined; + this.dashboardConfiguration = this.dashboard.configuration; + if (!this.widgetEditMode) { this.dashboardCtx.dashboardTimewindow = this.dashboardConfiguration.timewindow; this.updateDashboardCss(); this.entityAliasesUpdated(); this.filtersUpdated(); this.updateLayouts(); - } else { - this.dashboard.configuration.timewindow = this.dashboardCtx.dashboardTimewindow; } + } else if (!this.widgetEditMode) { + this.dashboard.configuration.timewindow = this.dashboardCtx.dashboardTimewindow; } } } diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/action/action-widget.scss b/ui-ngx/src/app/modules/home/components/widget/lib/action/action-widget.scss index 276fa725b8..6641c2c32e 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/action/action-widget.scss +++ b/ui-ngx/src/app/modules/home/components/widget/lib/action/action-widget.scss @@ -13,6 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +.mdc-linear-progress.tb-action-widget-progress { + position: absolute; + bottom: 0; + left: 0; + right: 0; +} .tb-action-widget-error-container { position: absolute; bottom: 0; diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/button/command-button-widget.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/button/command-button-widget.component.html index a6f01edb67..26f910fdd7 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/button/command-button-widget.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/button/command-button-widget.component.html @@ -22,10 +22,11 @@ +
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/rpc/single-switch-widget.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/rpc/single-switch-widget.component.html index 879902a3ef..c1c05cf880 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/rpc/single-switch-widget.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/rpc/single-switch-widget.component.html @@ -22,17 +22,21 @@
- {{ icon }} -
{{ label$ | async }}
+ {{ icon }} +
{{ label$ | async }}
-
{{ offLabel }}
+
{{ offLabel }}
-
{{ onLabel }}
+
{{ onLabel }}
- +
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/rpc/single-switch-widget.component.scss b/ui-ngx/src/app/modules/home/components/widget/lib/rpc/single-switch-widget.component.scss index bb5648a16d..27207e5f9d 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/rpc/single-switch-widget.component.scss +++ b/ui-ngx/src/app/modules/home/components/widget/lib/rpc/single-switch-widget.component.scss @@ -39,12 +39,6 @@ $switchColorDisabled: var(--tb-single-switch-color-disabled, #D5D7E5); position: absolute; inset: 12px; } - .tb-single-switch-progress { - position: absolute; - bottom: 0; - left: 0; - right: 0; - } > div.tb-single-switch-title-panel { position: absolute; top: 12px; diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/rpc/single-switch-widget.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/rpc/single-switch-widget.component.ts index a767d22408..2c15634893 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/rpc/single-switch-widget.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/rpc/single-switch-widget.component.ts @@ -97,6 +97,8 @@ export class SingleSwitchWidgetComponent extends offLabel = ''; offLabelStyle: ComponentStyle = {}; + disabledColor = 'rgba(0, 0, 0, 0.38)'; + autoScale = false; private panelResize$: ResizeObserver; @@ -129,22 +131,18 @@ export class SingleSwitchWidgetComponent extends this.showLabel = this.settings.showLabel; this.label$ = this.ctx.registerLabelPattern(this.settings.label, this.label$); this.labelStyle = textStyle(this.settings.labelFont); - this.labelStyle.color = this.settings.labelColor; this.showIcon = this.settings.showIcon; this.icon = this.settings.icon; this.iconStyle = iconStyle(this.settings.iconSize, this.settings.iconSizeUnit ); - this.iconStyle.color = this.settings.iconColor; this.showOnLabel = this.settings.showOnLabel; this.onLabel = this.settings.onLabel; this.onLabelStyle = textStyle(this.settings.onLabelFont); - this.onLabelStyle.color = this.settings.onLabelColor; this.showOffLabel = this.settings.showOffLabel; this.offLabel = this.settings.offLabel; this.offLabelStyle = textStyle(this.settings.offLabelFont); - this.offLabelStyle.color = this.settings.offLabelColor; const switchVariablesCss = `.tb-single-switch-panel {\n`+ `--tb-single-switch-tumbler-color-on: ${this.settings.tumblerColorOn};\n`+ `--tb-single-switch-tumbler-color-off: ${this.settings.tumblerColorOff};\n`+ @@ -229,33 +227,6 @@ export class SingleSwitchWidgetComponent extends private onDisabled(value: boolean): void { this.disabled = !!value; - if (this.disabled) { - if (this.showLabel) { - this.labelStyle = {...this.labelStyle, color: 'rgba(0, 0, 0, 0.38)'}; - } - if (this.showIcon) { - this.iconStyle = {...this.iconStyle, color: 'rgba(0, 0, 0, 0.38)'}; - } - if (this.showOnLabel) { - this.onLabelStyle = {...this.onLabelStyle, color: 'rgba(0, 0, 0, 0.38)'}; - } - if (this.showOffLabel) { - this.offLabelStyle = {...this.offLabelStyle, color: 'rgba(0, 0, 0, 0.38)'}; - } - } else { - if (this.showLabel) { - this.labelStyle = {...this.labelStyle, color: this.settings.labelColor}; - } - if (this.showIcon) { - this.iconStyle = {...this.iconStyle, color: this.settings.iconColor}; - } - if (this.showOnLabel) { - this.onLabelStyle = {...this.onLabelStyle, color: this.settings.onLabelColor}; - } - if (this.showOffLabel) { - this.offLabelStyle = {...this.offLabelStyle, color: this.settings.offLabelColor}; - } - } this.cd.markForCheck(); } From ff6074807ab3b25a571177c3f3c361b01ce188e5 Mon Sep 17 00:00:00 2001 From: ViacheslavKlimov Date: Tue, 6 Feb 2024 13:48:21 +0200 Subject: [PATCH 167/179] SNMP: request chunk sending delay; refactoring --- .../src/main/resources/thingsboard.yml | 7 +- .../transport/snmp/SnmpTransportContext.java | 2 + .../snmp/service/SnmpTransportService.java | 125 +++++--- .../snmp/session/DeviceSessionContext.java | 6 +- .../transport/snmp/session/ScheduledTask.java | 62 ++++ .../transport/snmp/SnmpDeviceSimulatorV2.java | 19 +- .../server/transport/snmp/SnmpTestV2.java | 42 ++- .../snmp-device-profile-transport-config.json | 43 --- .../snmp-device-transport-config-v3.json | 13 - .../snmp-device-transport-config.json | 6 - .../test/resources/snmp_device_profile.json | 289 ++++++++++++++++++ .../service/DefaultTransportService.java | 12 +- .../src/main/resources/tb-snmp-transport.yml | 7 +- 13 files changed, 492 insertions(+), 141 deletions(-) create mode 100644 common/transport/snmp/src/main/java/org/thingsboard/server/transport/snmp/session/ScheduledTask.java delete mode 100644 common/transport/snmp/src/test/resources/snmp-device-profile-transport-config.json delete mode 100644 common/transport/snmp/src/test/resources/snmp-device-transport-config-v3.json delete mode 100644 common/transport/snmp/src/test/resources/snmp-device-transport-config.json create mode 100644 common/transport/snmp/src/test/resources/snmp_device_profile.json diff --git a/application/src/main/resources/thingsboard.yml b/application/src/main/resources/thingsboard.yml index 936f30af60..6a20c3bcfc 100644 --- a/application/src/main/resources/thingsboard.yml +++ b/application/src/main/resources/thingsboard.yml @@ -1173,14 +1173,17 @@ transport: bind_port: "${SNMP_BIND_PORT:1620}" response_processing: # parallelism level for executor (workStealingPool) that is responsible for handling responses from SNMP devices - parallelism_level: "${SNMP_RESPONSE_PROCESSING_PARALLELISM_LEVEL:20}" + parallelism_level: "${SNMP_RESPONSE_PROCESSING_PARALLELISM_LEVEL:4}" # to configure SNMP to work over UDP or TCP underlying_protocol: "${SNMP_UNDERLYING_PROTOCOL:udp}" - # Batch size to request OID mappings from the device (useful when the device profile has multiple hundreds of OID mappings) + # Maximum size of a PDU (amount of OID mappings in a single SNMP request). The request will be split into multiple PDUs if mappings amount exceeds this number max_request_oids: "${SNMP_MAX_REQUEST_OIDS:100}" + # Delay after sending each request chunk (in case the request was split into multiple PDUs due to max_request_oids) + request_chunk_delay_ms: "${SNMP_REQUEST_CHUNK_DELAY_MS:100}" response: # To ignore SNMP response values that do not match the data type of the configured OID mapping (by default false - will throw an error if any value of the response not match configured data types) ignore_type_cast_errors: "${SNMP_RESPONSE_IGNORE_TYPE_CAST_ERRORS:false}" + scheduler_thread_pool_size: "${SNMP_SCHEDULER_THREAD_POOL_SIZE:4}" stats: # Enable/Disable the collection of transport statistics enabled: "${TB_TRANSPORT_STATS_ENABLED:true}" diff --git a/common/transport/snmp/src/main/java/org/thingsboard/server/transport/snmp/SnmpTransportContext.java b/common/transport/snmp/src/main/java/org/thingsboard/server/transport/snmp/SnmpTransportContext.java index a59013bbfe..6e30b06a2c 100644 --- a/common/transport/snmp/src/main/java/org/thingsboard/server/transport/snmp/SnmpTransportContext.java +++ b/common/transport/snmp/src/main/java/org/thingsboard/server/transport/snmp/SnmpTransportContext.java @@ -152,12 +152,14 @@ public class SnmpTransportContext extends TransportContext { try { if (!newProfileTransportConfiguration.equals(sessionContext.getProfileTransportConfiguration())) { sessionContext.setProfileTransportConfiguration(newProfileTransportConfiguration); + sessionContext.setDevice(device); sessionContext.initializeTarget(newProfileTransportConfiguration, newDeviceTransportConfiguration); snmpTransportService.cancelQueryingTasks(sessionContext); snmpTransportService.createQueryingTasks(sessionContext); transportService.lifecycleEvent(sessionContext.getTenantId(), sessionContext.getDeviceId(), ComponentLifecycleEvent.UPDATED, true, null); } else if (!newDeviceTransportConfiguration.equals(sessionContext.getDeviceTransportConfiguration())) { sessionContext.setDeviceTransportConfiguration(newDeviceTransportConfiguration); + sessionContext.setDevice(device); sessionContext.initializeTarget(newProfileTransportConfiguration, newDeviceTransportConfiguration); transportService.lifecycleEvent(sessionContext.getTenantId(), sessionContext.getDeviceId(), ComponentLifecycleEvent.UPDATED, true, null); } else { diff --git a/common/transport/snmp/src/main/java/org/thingsboard/server/transport/snmp/service/SnmpTransportService.java b/common/transport/snmp/src/main/java/org/thingsboard/server/transport/snmp/service/SnmpTransportService.java index 3a8811df97..26a1ef037e 100644 --- a/common/transport/snmp/src/main/java/org/thingsboard/server/transport/snmp/service/SnmpTransportService.java +++ b/common/transport/snmp/src/main/java/org/thingsboard/server/transport/snmp/service/SnmpTransportService.java @@ -15,6 +15,11 @@ */ package org.thingsboard.server.transport.snmp.service; +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.ListenableScheduledFuture; +import com.google.common.util.concurrent.ListeningScheduledExecutorService; +import com.google.common.util.concurrent.MoreExecutors; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import lombok.Builder; @@ -44,6 +49,7 @@ import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.thingsboard.common.util.ThingsBoardExecutors; import org.thingsboard.common.util.ThingsBoardThreadFactory; +import org.thingsboard.server.common.adaptor.JsonConverter; import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.TbTransportService; import org.thingsboard.server.common.data.kv.DataType; @@ -53,11 +59,11 @@ import org.thingsboard.server.common.data.transport.snmp.SnmpMethod; import org.thingsboard.server.common.data.transport.snmp.config.RepeatingQueryingSnmpCommunicationConfig; import org.thingsboard.server.common.data.transport.snmp.config.SnmpCommunicationConfig; import org.thingsboard.server.common.transport.TransportService; -import org.thingsboard.server.common.adaptor.JsonConverter; import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.queue.util.TbSnmpTransportComponent; import org.thingsboard.server.transport.snmp.SnmpTransportContext; import org.thingsboard.server.transport.snmp.session.DeviceSessionContext; +import org.thingsboard.server.transport.snmp.session.ScheduledTask; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; @@ -71,8 +77,6 @@ import java.util.Map; import java.util.Optional; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; @@ -80,6 +84,7 @@ import java.util.stream.Collectors; @Service @Slf4j @RequiredArgsConstructor +@SuppressWarnings("UnstableApiUsage") public class SnmpTransportService implements TbTransportService, CommandResponder { private final TransportService transportService; private final PduService pduService; @@ -88,23 +93,27 @@ public class SnmpTransportService implements TbTransportService, CommandResponde @Getter private Snmp snmp; - private ScheduledExecutorService queryingExecutor; - private ExecutorService responseProcessingExecutor; + private ListeningScheduledExecutorService scheduler; + private ExecutorService executor; private final Map responseDataMappers = new EnumMap<>(SnmpCommunicationSpec.class); private final Map responseProcessors = new EnumMap<>(SnmpCommunicationSpec.class); @Value("${transport.snmp.bind_port:1620}") private Integer snmpBindPort; - @Value("${transport.snmp.response_processing.parallelism_level}") - private Integer responseProcessingParallelismLevel; + @Value("${transport.snmp.response_processing.parallelism_level:4}") + private int responseProcessingThreadPoolSize; + @Value("${transport.snmp.scheduler_thread_pool_size:4}") + private int schedulerThreadPoolSize; @Value("${transport.snmp.underlying_protocol}") private String snmpUnderlyingProtocol; + @Value("${transport.snmp.request_chunk_delay_ms:100}") + private int requestChunkDelayMs; @PostConstruct private void init() throws IOException { - queryingExecutor = Executors.newScheduledThreadPool(Runtime.getRuntime().availableProcessors(), ThingsBoardThreadFactory.forName("snmp-querying")); - responseProcessingExecutor = ThingsBoardExecutors.newWorkStealingPool(responseProcessingParallelismLevel, "snmp-response-processing"); + scheduler = MoreExecutors.listeningDecorator(Executors.newScheduledThreadPool(schedulerThreadPoolSize, ThingsBoardThreadFactory.forName("snmp-querying"))); + executor = ThingsBoardExecutors.newWorkStealingPool(responseProcessingThreadPoolSize, "snmp-response-processing"); initializeSnmp(); configureResponseDataMappers(); @@ -115,11 +124,11 @@ public class SnmpTransportService implements TbTransportService, CommandResponde @PreDestroy public void stop() { - if (queryingExecutor != null) { - queryingExecutor.shutdownNow(); + if (scheduler != null) { + scheduler.shutdownNow(); } - if (responseProcessingExecutor != null) { - responseProcessingExecutor.shutdownNow(); + if (executor != null) { + executor.shutdownNow(); } } @@ -144,38 +153,39 @@ public class SnmpTransportService implements TbTransportService, CommandResponde } public void createQueryingTasks(DeviceSessionContext sessionContext) { - List> queryingTasks = sessionContext.getProfileTransportConfiguration().getCommunicationConfigs().stream() + sessionContext.getProfileTransportConfiguration().getCommunicationConfigs().stream() .filter(communicationConfig -> communicationConfig instanceof RepeatingQueryingSnmpCommunicationConfig) - .map(config -> { + .forEach(config -> { RepeatingQueryingSnmpCommunicationConfig repeatingCommunicationConfig = (RepeatingQueryingSnmpCommunicationConfig) config; Long queryingFrequency = repeatingCommunicationConfig.getQueryingFrequencyMs(); - return queryingExecutor.scheduleWithFixedDelay(() -> { + ScheduledTask scheduledTask = new ScheduledTask(); + scheduledTask.init(() -> { try { if (sessionContext.isActive()) { - sendRequest(sessionContext, repeatingCommunicationConfig); + return sendRequest(sessionContext, repeatingCommunicationConfig); } } catch (Exception e) { log.error("Failed to send SNMP request for device {}: {}", sessionContext.getDeviceId(), e.toString()); transportService.errorEvent(sessionContext.getTenantId(), sessionContext.getDeviceId(), config.getSpec().getLabel(), e); } - }, queryingFrequency, queryingFrequency, TimeUnit.MILLISECONDS); - }) - .collect(Collectors.toList()); - sessionContext.getQueryingTasks().addAll(queryingTasks); + return Futures.immediateVoidFuture(); + }, queryingFrequency, scheduler); + sessionContext.getQueryingTasks().add(scheduledTask); + }); } public void cancelQueryingTasks(DeviceSessionContext sessionContext) { - sessionContext.getQueryingTasks().forEach(task -> task.cancel(true)); + sessionContext.getQueryingTasks().forEach(ScheduledTask::cancel); sessionContext.getQueryingTasks().clear(); } - private void sendRequest(DeviceSessionContext sessionContext, SnmpCommunicationConfig communicationConfig) { - sendRequest(sessionContext, communicationConfig, Collections.emptyMap()); + private ListenableFuture sendRequest(DeviceSessionContext sessionContext, SnmpCommunicationConfig communicationConfig) { + return sendRequest(sessionContext, communicationConfig, Collections.emptyMap()); } - private void sendRequest(DeviceSessionContext sessionContext, SnmpCommunicationConfig communicationConfig, Map values) { + private ListenableFuture sendRequest(DeviceSessionContext sessionContext, SnmpCommunicationConfig communicationConfig, Map values) { List request = pduService.createPdus(sessionContext, communicationConfig, values); RequestContext requestContext = RequestContext.builder() .communicationSpec(communicationConfig.getSpec()) @@ -183,19 +193,40 @@ public class SnmpTransportService implements TbTransportService, CommandResponde .responseMappings(communicationConfig.getAllMappings()) .requestSize(request.size()) .build(); - sendRequest(sessionContext, request, requestContext); + return sendRequest(sessionContext, request, requestContext); } - private void sendRequest(DeviceSessionContext sessionContext, List request, RequestContext requestContext) { - for (PDU pdu : request) { - log.debug("Executing SNMP request for device {} with {} variable bindings", sessionContext.getDeviceId(), pdu.size()); - try { - snmp.send(pdu, sessionContext.getTarget(), requestContext, sessionContext); - } catch (IOException e) { - log.error("Failed to send SNMP request to device {}: {}", sessionContext.getDeviceId(), e.toString()); - transportService.errorEvent(sessionContext.getTenantId(), sessionContext.getDeviceId(), requestContext.getCommunicationSpec().getLabel(), e); + private ListenableFuture sendRequest(DeviceSessionContext sessionContext, List request, RequestContext requestContext) { + if (request.size() <= 1 || requestChunkDelayMs == 0) { + for (PDU pdu : request) { + sendPdu(pdu, requestContext, sessionContext); + } + return Futures.immediateVoidFuture(); + } + + List> futures = new ArrayList<>(); + for (int i = 0, delay = 0; i < request.size(); i++, delay += requestChunkDelayMs) { + PDU pdu = request.get(i); + if (delay == 0) { + sendPdu(pdu, requestContext, sessionContext); + } else { + ListenableScheduledFuture future = scheduler.schedule(() -> { + sendPdu(pdu, requestContext, sessionContext); + }, delay, TimeUnit.MILLISECONDS); + futures.add(future); } } + return Futures.whenAllComplete(futures).call(() -> null, MoreExecutors.directExecutor()); + } + + private void sendPdu(PDU pdu, RequestContext requestContext, DeviceSessionContext sessionContext) { + log.debug("[{}] Sending SNMP request with {} variable bindings to {}", sessionContext.getDeviceId(), pdu.size(), sessionContext.getTarget().getAddress()); + try { + snmp.send(pdu, sessionContext.getTarget(), requestContext, sessionContext); + } catch (Exception e) { + log.error("[{}] Failed to send SNMP request", sessionContext.getDeviceId(), e); + transportService.errorEvent(sessionContext.getTenantId(), sessionContext.getDeviceId(), requestContext.getCommunicationSpec().getLabel(), e); + } } public void onAttributeUpdate(DeviceSessionContext sessionContext, TransportProtos.AttributeUpdateNotificationMsg attributeUpdateNotification) { @@ -251,21 +282,19 @@ public class SnmpTransportService implements TbTransportService, CommandResponde ((Snmp) event.getSource()).cancel(event.getRequest(), sessionContext); RequestContext requestContext = (RequestContext) event.getUserObject(); if (event.getError() != null) { - log.warn("SNMP response error: {}", event.getError().toString()); + log.warn("[{}] SNMP response error: {}", sessionContext.getDeviceId(), event.getError().toString()); transportService.errorEvent(sessionContext.getTenantId(), sessionContext.getDeviceId(), requestContext.getCommunicationSpec().getLabel(), new RuntimeException(event.getError())); return; } PDU responsePdu = event.getResponse(); - if (log.isTraceEnabled()) { - log.trace("Received PDU for device {}: {}", sessionContext.getDeviceId(), responsePdu); - } + log.trace("[{}] Received PDU: {}", sessionContext.getDeviceId(), responsePdu); List response; if (requestContext.getRequestSize() == 1) { if (responsePdu == null) { - log.debug("No response from SNMP device {}, requestId: {}", sessionContext.getDeviceId(), event.getRequest().getRequestID()); if (requestContext.getMethod() == SnmpMethod.GET) { + log.debug("[{}][{}] Empty response from device", sessionContext.getDeviceId(), event.getRequest().getRequestID()); transportService.errorEvent(sessionContext.getTenantId(), sessionContext.getDeviceId(), requestContext.getCommunicationSpec().getLabel(), new RuntimeException("No response from device")); } return; @@ -281,14 +310,14 @@ public class SnmpTransportService implements TbTransportService, CommandResponde response.add(responsePart); } } - log.debug("All response parts are collected for request to device {}", sessionContext.getDeviceId()); + log.debug("[{}] All {} response parts are collected for request", sessionContext.getDeviceId(), responseParts.size()); } else { - log.trace("Awaiting other response parts for request to device {}", sessionContext.getDeviceId()); + log.trace("[{}] Awaiting other response parts for request", sessionContext.getDeviceId()); return; } } - responseProcessingExecutor.execute(() -> { + executor.execute(() -> { try { processResponse(sessionContext, response, requestContext); } catch (Exception e) { @@ -341,7 +370,7 @@ public class SnmpTransportService implements TbTransportService, CommandResponde .method(SnmpMethod.TRAP) .build(); - responseProcessingExecutor.execute(() -> { + executor.execute(() -> { processResponse(sessionContext, List.of(pdu), requestContext); }); } @@ -352,7 +381,7 @@ public class SnmpTransportService implements TbTransportService, CommandResponde JsonObject responseData = responseDataMappers.get(requestContext.getCommunicationSpec()).map(response, requestContext); if (responseData.size() == 0) { - log.warn("No values in the SNMP response for device {}", sessionContext.getDeviceId()); + log.warn("[{}] No values in the response", sessionContext.getDeviceId()); throw new IllegalArgumentException("No values in the response"); } @@ -428,11 +457,11 @@ public class SnmpTransportService implements TbTransportService, CommandResponde @PreDestroy public void shutdown() { log.info("Stopping SNMP transport!"); - if (queryingExecutor != null) { - queryingExecutor.shutdownNow(); + if (scheduler != null) { + scheduler.shutdownNow(); } - if (responseProcessingExecutor != null) { - responseProcessingExecutor.shutdownNow(); + if (executor != null) { + executor.shutdownNow(); } if (snmp != null) { try { diff --git a/common/transport/snmp/src/main/java/org/thingsboard/server/transport/snmp/session/DeviceSessionContext.java b/common/transport/snmp/src/main/java/org/thingsboard/server/transport/snmp/session/DeviceSessionContext.java index 5819c76f74..8ec0c6841d 100644 --- a/common/transport/snmp/src/main/java/org/thingsboard/server/transport/snmp/session/DeviceSessionContext.java +++ b/common/transport/snmp/src/main/java/org/thingsboard/server/transport/snmp/session/DeviceSessionContext.java @@ -45,7 +45,6 @@ import org.thingsboard.server.transport.snmp.SnmpTransportContext; import java.util.LinkedList; import java.util.List; import java.util.UUID; -import java.util.concurrent.ScheduledFuture; import java.util.concurrent.atomic.AtomicInteger; @Slf4j @@ -60,7 +59,8 @@ public class DeviceSessionContext extends DeviceAwareSessionContext implements S @Setter private SnmpDeviceTransportConfiguration deviceTransportConfiguration; @Getter - private final Device device; + @Setter + private Device device; @Getter private final TenantId tenantId; @@ -73,7 +73,7 @@ public class DeviceSessionContext extends DeviceAwareSessionContext implements S private Runnable sessionTimeoutHandler; @Getter - private final List> queryingTasks = new LinkedList<>(); + private final List queryingTasks = new LinkedList<>(); @Builder public DeviceSessionContext(TenantId tenantId, Device device, DeviceProfile deviceProfile, String token, diff --git a/common/transport/snmp/src/main/java/org/thingsboard/server/transport/snmp/session/ScheduledTask.java b/common/transport/snmp/src/main/java/org/thingsboard/server/transport/snmp/session/ScheduledTask.java new file mode 100644 index 0000000000..43d83e5e2c --- /dev/null +++ b/common/transport/snmp/src/main/java/org/thingsboard/server/transport/snmp/session/ScheduledTask.java @@ -0,0 +1,62 @@ +/** + * Copyright © 2016-2024 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.server.transport.snmp.session; + +import com.google.common.util.concurrent.AsyncCallable; +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.MoreExecutors; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + +@Data +@Slf4j +public class ScheduledTask { + private ListenableFuture scheduledFuture; + private boolean stopped = false; + + public void init(AsyncCallable task, long delayMs, ScheduledExecutorService scheduler) { + schedule(task, delayMs, scheduler); + } + + private void schedule(AsyncCallable task, long delayMs, ScheduledExecutorService scheduler) { + scheduledFuture = Futures.scheduleAsync(() -> { + if (stopped) { + return Futures.immediateCancelledFuture(); + } + try { + return task.call(); + } catch (Throwable t) { + log.error("Unhandled error in scheduled task", t); + return Futures.immediateFailedFuture(t); + } + }, delayMs, TimeUnit.MILLISECONDS, scheduler); + if (!stopped) { + scheduledFuture.addListener(() -> schedule(task, delayMs, scheduler), MoreExecutors.directExecutor()); + } + } + + public void cancel() { + stopped = true; + if (scheduledFuture != null) { + scheduledFuture.cancel(true); + } + } + +} diff --git a/common/transport/snmp/src/test/java/org/thingsboard/server/transport/snmp/SnmpDeviceSimulatorV2.java b/common/transport/snmp/src/test/java/org/thingsboard/server/transport/snmp/SnmpDeviceSimulatorV2.java index 261e67bac8..ced8f21288 100644 --- a/common/transport/snmp/src/test/java/org/thingsboard/server/transport/snmp/SnmpDeviceSimulatorV2.java +++ b/common/transport/snmp/src/test/java/org/thingsboard/server/transport/snmp/SnmpDeviceSimulatorV2.java @@ -58,11 +58,10 @@ public class SnmpDeviceSimulatorV2 extends BaseAgent { private final Target target; private final Address address; + private final Map mappings; private Snmp snmp; - private final String password; - - public SnmpDeviceSimulatorV2(int port, String password) throws IOException { + public SnmpDeviceSimulatorV2(int port, String password, Map mappings) throws IOException { super(new File("conf.agent"), new File("bootCounter.agent"), new CommandProcessor(new OctetString("12312"))); CommunityTarget target = new CommunityTarget(); target.setCommunity(new OctetString(password)); @@ -72,7 +71,7 @@ public class SnmpDeviceSimulatorV2 extends BaseAgent { target.setTimeout(1500); target.setVersion(SnmpConstants.version2c); this.target = target; - this.password = password; + this.mappings = mappings; } public void start() throws IOException { @@ -85,13 +84,6 @@ public class SnmpDeviceSimulatorV2 extends BaseAgent { snmp = new Snmp(transportMappings[0]); } - public void setUpMappings(Map oidToResponseMappings) { - unregisterManagedObject(getSnmpv2MIB()); - oidToResponseMappings.forEach((oid, response) -> { - registerManagedObject(new MOScalar<>(new OID(oid), MOAccessImpl.ACCESS_READ_WRITE, new OctetString(response))); - }); - } - public void sendTrap(String host, int port, Map values) throws IOException { PDU pdu = new PDU(); pdu.addAll(values.entrySet().stream() @@ -107,6 +99,10 @@ public class SnmpDeviceSimulatorV2 extends BaseAgent { @Override protected void registerManagedObjects() { + unregisterManagedObject(getSnmpv2MIB()); + mappings.forEach((oid, response) -> { + registerManagedObject(new MOScalar<>(new OID(oid), MOAccessImpl.ACCESS_READ_WRITE, new OctetString(response))); + }); } protected void registerManagedObject(ManagedObject mo) { @@ -152,6 +148,7 @@ public class SnmpDeviceSimulatorV2 extends BaseAgent { } protected void unregisterManagedObjects() { + unregisterManagedObject(getSnmpv2MIB()); } protected void addCommunities(SnmpCommunityMIB communityMIB) { diff --git a/common/transport/snmp/src/test/java/org/thingsboard/server/transport/snmp/SnmpTestV2.java b/common/transport/snmp/src/test/java/org/thingsboard/server/transport/snmp/SnmpTestV2.java index cb99c85655..c87507f962 100644 --- a/common/transport/snmp/src/test/java/org/thingsboard/server/transport/snmp/SnmpTestV2.java +++ b/common/transport/snmp/src/test/java/org/thingsboard/server/transport/snmp/SnmpTestV2.java @@ -15,28 +15,34 @@ */ package org.thingsboard.server.transport.snmp; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ArrayNode; +import org.thingsboard.common.util.JacksonUtil; + +import java.io.File; import java.io.IOException; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Map; import java.util.Scanner; +import java.util.stream.Collectors; public class SnmpTestV2 { private static final Scanner scanner = new Scanner(System.in); public static void main(String[] args) throws IOException { - SnmpDeviceSimulatorV2 client = new SnmpDeviceSimulatorV2(1610, "public"); + Map mappings = new LinkedHashMap<>(); + for (int i = 1; i <= 50; i++) { + String oid = String.format("1.3.6.1.2.1.%s.1.52", i); + mappings.put(oid, "value_" + i); + } - client.start(); - Map mappings = new HashMap<>(); -// for (int i = 1; i <= 500; i++) { -// String oid = String.format(".1.3.6.1.2.1.%s.1.52", i); -// mappings.put(oid, "value_" + i); -// } - mappings.put("1.3.6.1.2.1.266.1.52", "****"); + SnmpDeviceSimulatorV2 device = new SnmpDeviceSimulatorV2(1610, "public", mappings); + device.start(); - client.setUpMappings(mappings); - inputTraps(client); + System.out.println("Hosting the following values:\n" + mappings.entrySet().stream() + .map(entry -> entry.getKey() + " - " + entry.getValue()) + .collect(Collectors.joining("\n"))); scanner.nextLine(); } @@ -53,4 +59,18 @@ public class SnmpTestV2 { } } + private static void updateDeviceProfile(String file) throws Exception { + File profileFile = new File(file); + JsonNode deviceProfile = JacksonUtil.OBJECT_MAPPER.readTree(profileFile); + ArrayNode mappingsJson = (ArrayNode) deviceProfile.at("/profileData/transportConfiguration/communicationConfigs/0/mappings"); + for (int i = 1; i <= 50; i++) { + String oid = String.format(".1.3.6.1.2.1.%s.1.52", i); + mappingsJson.add(JacksonUtil.newObjectNode() + .put("oid", oid) + .put("key", "key_" + i) + .put("dataType", "STRING")); + } + JacksonUtil.OBJECT_MAPPER.writeValue(profileFile, deviceProfile); + } + } diff --git a/common/transport/snmp/src/test/resources/snmp-device-profile-transport-config.json b/common/transport/snmp/src/test/resources/snmp-device-profile-transport-config.json deleted file mode 100644 index f74ebca0bf..0000000000 --- a/common/transport/snmp/src/test/resources/snmp-device-profile-transport-config.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - "timeoutMs": 500, - "retries": 0, - "communicationConfigs": [ - { - "spec": "TELEMETRY_QUERYING", - "queryingFrequencyMs": 3000, - "mappings": [ - { - "oid": ".1.3.6.1.2.1.1.1.50", - "key": "temperature", - "dataType": "LONG" - }, - { - "oid": ".1.3.6.1.2.1.2.1.52", - "key": "humidity", - "dataType": "DOUBLE" - } - ] - }, - { - "spec": "CLIENT_ATTRIBUTES_QUERYING", - "queryingFrequencyMs": 5000, - "mappings": [ - { - "oid": ".1.3.6.1.2.1.3.1.54", - "key": "isCool", - "dataType": "STRING" - } - ] - }, - { - "spec": "SHARED_ATTRIBUTES_SETTING", - "mappings": [ - { - "oid": ".1.3.6.1.2.1.7.1.58", - "key": "shared", - "dataType": "STRING" - } - ] - } - ] -} diff --git a/common/transport/snmp/src/test/resources/snmp-device-transport-config-v3.json b/common/transport/snmp/src/test/resources/snmp-device-transport-config-v3.json deleted file mode 100644 index 039e03fa53..0000000000 --- a/common/transport/snmp/src/test/resources/snmp-device-transport-config-v3.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "address": "192.168.3.23", - "port": 1610, - "protocolVersion": "V3", - - "username": "tb-user", - "engineId": "qwertyuioa", - "securityName": "tb-user", - "authenticationProtocol": "SHA_512", - "authenticationPassphrase": "sdfghjkloifgh", - "privacyProtocol": "DES", - "privacyPassphrase": "rtytguijokod" -} \ No newline at end of file diff --git a/common/transport/snmp/src/test/resources/snmp-device-transport-config.json b/common/transport/snmp/src/test/resources/snmp-device-transport-config.json deleted file mode 100644 index c73d817bfb..0000000000 --- a/common/transport/snmp/src/test/resources/snmp-device-transport-config.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "address": "127.0.0.1", - "port": 1610, - "community": "public", - "protocolVersion": "V2C" -} \ No newline at end of file diff --git a/common/transport/snmp/src/test/resources/snmp_device_profile.json b/common/transport/snmp/src/test/resources/snmp_device_profile.json new file mode 100644 index 0000000000..0e72c46ce8 --- /dev/null +++ b/common/transport/snmp/src/test/resources/snmp_device_profile.json @@ -0,0 +1,289 @@ +{ + "name": "SNMP Device Profile", + "description": "", + "image": null, + "type": "DEFAULT", + "transportType": "SNMP", + "provisionType": "DISABLED", + "defaultRuleChainId": null, + "defaultDashboardId": null, + "defaultQueueName": null, + "profileData": { + "configuration": { + "type": "DEFAULT" + }, + "transportConfiguration": { + "type": "SNMP", + "timeoutMs": 500, + "retries": 0, + "communicationConfigs": [ + { + "spec": "TELEMETRY_QUERYING", + "mappings": [ + { + "oid": ".1.3.6.1.2.1.1.1.52", + "key": "key_1", + "dataType": "STRING" + }, + { + "oid": ".1.3.6.1.2.1.2.1.52", + "key": "key_2", + "dataType": "STRING" + }, + { + "oid": ".1.3.6.1.2.1.3.1.52", + "key": "key_3", + "dataType": "STRING" + }, + { + "oid": ".1.3.6.1.2.1.4.1.52", + "key": "key_4", + "dataType": "STRING" + }, + { + "oid": ".1.3.6.1.2.1.5.1.52", + "key": "key_5", + "dataType": "STRING" + }, + { + "oid": ".1.3.6.1.2.1.6.1.52", + "key": "key_6", + "dataType": "STRING" + }, + { + "oid": ".1.3.6.1.2.1.7.1.52", + "key": "key_7", + "dataType": "STRING" + }, + { + "oid": ".1.3.6.1.2.1.8.1.52", + "key": "key_8", + "dataType": "STRING" + }, + { + "oid": ".1.3.6.1.2.1.9.1.52", + "key": "key_9", + "dataType": "STRING" + }, + { + "oid": ".1.3.6.1.2.1.10.1.52", + "key": "key_10", + "dataType": "STRING" + }, + { + "oid": ".1.3.6.1.2.1.11.1.52", + "key": "key_11", + "dataType": "STRING" + }, + { + "oid": ".1.3.6.1.2.1.12.1.52", + "key": "key_12", + "dataType": "STRING" + }, + { + "oid": ".1.3.6.1.2.1.13.1.52", + "key": "key_13", + "dataType": "STRING" + }, + { + "oid": ".1.3.6.1.2.1.14.1.52", + "key": "key_14", + "dataType": "STRING" + }, + { + "oid": ".1.3.6.1.2.1.15.1.52", + "key": "key_15", + "dataType": "STRING" + }, + { + "oid": ".1.3.6.1.2.1.16.1.52", + "key": "key_16", + "dataType": "STRING" + }, + { + "oid": ".1.3.6.1.2.1.17.1.52", + "key": "key_17", + "dataType": "STRING" + }, + { + "oid": ".1.3.6.1.2.1.18.1.52", + "key": "key_18", + "dataType": "STRING" + }, + { + "oid": ".1.3.6.1.2.1.19.1.52", + "key": "key_19", + "dataType": "STRING" + }, + { + "oid": ".1.3.6.1.2.1.20.1.52", + "key": "key_20", + "dataType": "STRING" + }, + { + "oid": ".1.3.6.1.2.1.21.1.52", + "key": "key_21", + "dataType": "STRING" + }, + { + "oid": ".1.3.6.1.2.1.22.1.52", + "key": "key_22", + "dataType": "STRING" + }, + { + "oid": ".1.3.6.1.2.1.23.1.52", + "key": "key_23", + "dataType": "STRING" + }, + { + "oid": ".1.3.6.1.2.1.24.1.52", + "key": "key_24", + "dataType": "STRING" + }, + { + "oid": ".1.3.6.1.2.1.25.1.52", + "key": "key_25", + "dataType": "STRING" + }, + { + "oid": ".1.3.6.1.2.1.26.1.52", + "key": "key_26", + "dataType": "STRING" + }, + { + "oid": ".1.3.6.1.2.1.27.1.52", + "key": "key_27", + "dataType": "STRING" + }, + { + "oid": ".1.3.6.1.2.1.28.1.52", + "key": "key_28", + "dataType": "STRING" + }, + { + "oid": ".1.3.6.1.2.1.29.1.52", + "key": "key_29", + "dataType": "STRING" + }, + { + "oid": ".1.3.6.1.2.1.30.1.52", + "key": "key_30", + "dataType": "STRING" + }, + { + "oid": ".1.3.6.1.2.1.31.1.52", + "key": "key_31", + "dataType": "STRING" + }, + { + "oid": ".1.3.6.1.2.1.32.1.52", + "key": "key_32", + "dataType": "STRING" + }, + { + "oid": ".1.3.6.1.2.1.33.1.52", + "key": "key_33", + "dataType": "STRING" + }, + { + "oid": ".1.3.6.1.2.1.34.1.52", + "key": "key_34", + "dataType": "STRING" + }, + { + "oid": ".1.3.6.1.2.1.35.1.52", + "key": "key_35", + "dataType": "STRING" + }, + { + "oid": ".1.3.6.1.2.1.36.1.52", + "key": "key_36", + "dataType": "STRING" + }, + { + "oid": ".1.3.6.1.2.1.37.1.52", + "key": "key_37", + "dataType": "STRING" + }, + { + "oid": ".1.3.6.1.2.1.38.1.52", + "key": "key_38", + "dataType": "STRING" + }, + { + "oid": ".1.3.6.1.2.1.39.1.52", + "key": "key_39", + "dataType": "STRING" + }, + { + "oid": ".1.3.6.1.2.1.40.1.52", + "key": "key_40", + "dataType": "STRING" + }, + { + "oid": ".1.3.6.1.2.1.41.1.52", + "key": "key_41", + "dataType": "STRING" + }, + { + "oid": ".1.3.6.1.2.1.42.1.52", + "key": "key_42", + "dataType": "STRING" + }, + { + "oid": ".1.3.6.1.2.1.43.1.52", + "key": "key_43", + "dataType": "STRING" + }, + { + "oid": ".1.3.6.1.2.1.44.1.52", + "key": "key_44", + "dataType": "STRING" + }, + { + "oid": ".1.3.6.1.2.1.45.1.52", + "key": "key_45", + "dataType": "STRING" + }, + { + "oid": ".1.3.6.1.2.1.46.1.52", + "key": "key_46", + "dataType": "STRING" + }, + { + "oid": ".1.3.6.1.2.1.47.1.52", + "key": "key_47", + "dataType": "STRING" + }, + { + "oid": ".1.3.6.1.2.1.48.1.52", + "key": "key_48", + "dataType": "STRING" + }, + { + "oid": ".1.3.6.1.2.1.49.1.52", + "key": "key_49", + "dataType": "STRING" + }, + { + "oid": ".1.3.6.1.2.1.50.1.52", + "key": "key_50", + "dataType": "STRING" + } + ], + "queryingFrequencyMs": 5000 + } + ] + }, + "provisionConfiguration": { + "type": "DISABLED", + "provisionDeviceSecret": null + }, + "alarms": null + }, + "provisionDeviceKey": null, + "firmwareId": null, + "softwareId": null, + "defaultEdgeRuleChainId": null, + "default": false +} \ No newline at end of file diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java index 0d7fbfc332..504b9bdf6d 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java @@ -788,7 +788,11 @@ public class DefaultTransportService extends TransportActivityManager implements .setSuccess(success) .setError(error != null ? ExceptionUtils.getStackTrace(error) : "")) .build(); - sendToCore(tenantId, deviceId, msg, deviceId.getId(), TransportServiceCallback.EMPTY); + try { + sendToCore(tenantId, deviceId, msg, deviceId.getId(), TransportServiceCallback.EMPTY); + } catch (Exception e) { + log.error("[{}][{}] Failed to send lifecycle event to core", tenantId, deviceId, e); + } } @Override @@ -803,7 +807,11 @@ public class DefaultTransportService extends TransportActivityManager implements .setMethod(method) .setError(ExceptionUtils.getStackTrace(error))) .build(); - sendToCore(tenantId, deviceId, msg, deviceId.getId(), TransportServiceCallback.EMPTY); + try { + sendToCore(tenantId, deviceId, msg, deviceId.getId(), TransportServiceCallback.EMPTY); + } catch (Exception e) { + log.error("[{}][{}] Failed to send error event to core", tenantId, deviceId, e); + } } @Override diff --git a/transport/snmp/src/main/resources/tb-snmp-transport.yml b/transport/snmp/src/main/resources/tb-snmp-transport.yml index 805ab5a8dd..2e69032cb3 100644 --- a/transport/snmp/src/main/resources/tb-snmp-transport.yml +++ b/transport/snmp/src/main/resources/tb-snmp-transport.yml @@ -128,14 +128,17 @@ transport: bind_port: "${SNMP_BIND_PORT:1620}" response_processing: # parallelism level for executor (workStealingPool) that is responsible for handling responses from SNMP devices - parallelism_level: "${SNMP_RESPONSE_PROCESSING_PARALLELISM_LEVEL:20}" + parallelism_level: "${SNMP_RESPONSE_PROCESSING_PARALLELISM_LEVEL:4}" # to configure SNMP to work over UDP or TCP underlying_protocol: "${SNMP_UNDERLYING_PROTOCOL:udp}" - # Batch size to request OID mappings from the device (useful when the device profile has multiple hundreds of OID mappings) + # Maximum size of a PDU (amount of OID mappings in a single SNMP request). The request will be split into multiple PDUs if mappings amount exceeds this number max_request_oids: "${SNMP_MAX_REQUEST_OIDS:100}" + # Delay after sending each request chunk (in case the request was split into multiple PDUs due to max_request_oids) + request_chunk_delay_ms: "${SNMP_REQUEST_CHUNK_DELAY_MS:100}" response: # To ignore SNMP response values that do not match the data type of the configured OID mapping (by default false - will throw an error if any value of the response not match configured data types) ignore_type_cast_errors: "${SNMP_RESPONSE_IGNORE_TYPE_CAST_ERRORS:false}" + scheduler_thread_pool_size: "${SNMP_SCHEDULER_THREAD_POOL_SIZE:4}" sessions: # Session inactivity timeout is a global configuration parameter that defines how long the device transport session will be opened after the last message arrives from the device. # The parameter value is in milliseconds. From 1c59cef7eb23892dbb47ceae9bcd98d2cfdba8b6 Mon Sep 17 00:00:00 2001 From: ViacheslavKlimov Date: Tue, 6 Feb 2024 13:59:17 +0200 Subject: [PATCH 168/179] Add scheduler_thread_pool_size param description for SNMP --- application/src/main/resources/thingsboard.yml | 1 + transport/snmp/src/main/resources/tb-snmp-transport.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/application/src/main/resources/thingsboard.yml b/application/src/main/resources/thingsboard.yml index 6a20c3bcfc..535d6189c8 100644 --- a/application/src/main/resources/thingsboard.yml +++ b/application/src/main/resources/thingsboard.yml @@ -1183,6 +1183,7 @@ transport: response: # To ignore SNMP response values that do not match the data type of the configured OID mapping (by default false - will throw an error if any value of the response not match configured data types) ignore_type_cast_errors: "${SNMP_RESPONSE_IGNORE_TYPE_CAST_ERRORS:false}" + # Thread pool size for scheduler that executes device querying tasks scheduler_thread_pool_size: "${SNMP_SCHEDULER_THREAD_POOL_SIZE:4}" stats: # Enable/Disable the collection of transport statistics diff --git a/transport/snmp/src/main/resources/tb-snmp-transport.yml b/transport/snmp/src/main/resources/tb-snmp-transport.yml index 2e69032cb3..a40374e1f6 100644 --- a/transport/snmp/src/main/resources/tb-snmp-transport.yml +++ b/transport/snmp/src/main/resources/tb-snmp-transport.yml @@ -138,6 +138,7 @@ transport: response: # To ignore SNMP response values that do not match the data type of the configured OID mapping (by default false - will throw an error if any value of the response not match configured data types) ignore_type_cast_errors: "${SNMP_RESPONSE_IGNORE_TYPE_CAST_ERRORS:false}" + # Thread pool size for scheduler that executes device querying tasks scheduler_thread_pool_size: "${SNMP_SCHEDULER_THREAD_POOL_SIZE:4}" sessions: # Session inactivity timeout is a global configuration parameter that defines how long the device transport session will be opened after the last message arrives from the device. From c6372e6e4e01c88bd18f60a02cf5c226b28f0325 Mon Sep 17 00:00:00 2001 From: imbeacon Date: Tue, 6 Feb 2024 14:25:05 +0200 Subject: [PATCH 169/179] Added extra mapping for the gateway launch command docker compose file --- .../server/dao/util/DeviceConnectivityUtil.java | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/dao/src/main/java/org/thingsboard/server/dao/util/DeviceConnectivityUtil.java b/dao/src/main/java/org/thingsboard/server/dao/util/DeviceConnectivityUtil.java index b0d42cdb07..f4a77dc725 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/util/DeviceConnectivityUtil.java +++ b/dao/src/main/java/org/thingsboard/server/dao/util/DeviceConnectivityUtil.java @@ -112,12 +112,10 @@ public class DeviceConnectivityUtil { dockerComposeBuilder.append("# - \"5026:5026\" # Modbus TCP connector (Modbus Slave)\n"); dockerComposeBuilder.append("# - \"50000:50000/tcp\" # Socket connector with type TCP\n"); dockerComposeBuilder.append("# - \"50000:50000/udp\" # Socket connector with type UDP\n"); - if (isLocalhost(host)) { - dockerComposeBuilder.append("\n"); - dockerComposeBuilder.append(" # Necessary mapping for Linux\n"); - dockerComposeBuilder.append(" extra_hosts:\n"); - dockerComposeBuilder.append(" - \"host.docker.internal:host-gateway\"\n"); - } + dockerComposeBuilder.append("\n"); + dockerComposeBuilder.append(" # Necessary mapping for Linux\n"); + dockerComposeBuilder.append(" extra_hosts:\n"); + dockerComposeBuilder.append(" - \"host.docker.internal:host-gateway\"\n"); dockerComposeBuilder.append("\n"); dockerComposeBuilder.append(" # Environment variables\n"); dockerComposeBuilder.append(" environment:\n"); From dec09fc479890cc3d051fa1f7f24854f0e4a7951 Mon Sep 17 00:00:00 2001 From: dashevchenko Date: Tue, 6 Feb 2024 15:21:57 +0200 Subject: [PATCH 170/179] extracted duplicated string to variable --- .../CassandraBaseTimeseriesDao.java | 38 +++++++------------ 1 file changed, 14 insertions(+), 24 deletions(-) diff --git a/dao/src/main/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDao.java b/dao/src/main/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDao.java index 8d96dd293b..833a18ad39 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDao.java @@ -86,6 +86,18 @@ public class CassandraBaseTimeseriesDao extends AbstractCassandraBaseTimeseriesD public static final String ASC_ORDER = "ASC"; public static final long SECONDS_IN_DAY = TimeUnit.DAYS.toSeconds(1); protected static final List FIXED_PARTITION = List.of(0L); + private static String INSERT_WITH_NULL = INSERT_INTO + ModelConstants.TS_KV_CF + + "(" + ModelConstants.ENTITY_TYPE_COLUMN + + "," + ModelConstants.ENTITY_ID_COLUMN + + "," + ModelConstants.KEY_COLUMN + + "," + ModelConstants.PARTITION_COLUMN + + "," + ModelConstants.TS_COLUMN + + "," + ModelConstants.BOOLEAN_VALUE_COLUMN + + "," + ModelConstants.STRING_VALUE_COLUMN + + "," + ModelConstants.LONG_VALUE_COLUMN + + "," + ModelConstants.DOUBLE_VALUE_COLUMN + + "," + ModelConstants.JSON_VALUE_COLUMN + ")" + + " VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; private CassandraTsPartitionsCache cassandraTsPartitionsCache; @@ -566,18 +578,7 @@ public class CassandraBaseTimeseriesDao extends AbstractCassandraBaseTimeseriesD stmtCreationLock.lock(); try { if (saveWithNullStmt == null) { - saveWithNullStmt = prepare(INSERT_INTO + ModelConstants.TS_KV_CF + - "(" + ModelConstants.ENTITY_TYPE_COLUMN + - "," + ModelConstants.ENTITY_ID_COLUMN + - "," + ModelConstants.KEY_COLUMN + - "," + ModelConstants.PARTITION_COLUMN + - "," + ModelConstants.TS_COLUMN + - "," + ModelConstants.BOOLEAN_VALUE_COLUMN + - "," + ModelConstants.STRING_VALUE_COLUMN + - "," + ModelConstants.LONG_VALUE_COLUMN + - "," + ModelConstants.DOUBLE_VALUE_COLUMN + - "," + ModelConstants.JSON_VALUE_COLUMN + ")" + - " VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"); + saveWithNullStmt = prepare(INSERT_WITH_NULL); } } finally { stmtCreationLock.unlock(); @@ -591,18 +592,7 @@ public class CassandraBaseTimeseriesDao extends AbstractCassandraBaseTimeseriesD stmtCreationLock.lock(); try { if (saveWithNullWithTtlStmt == null) { - saveWithNullWithTtlStmt = prepare(INSERT_INTO + ModelConstants.TS_KV_CF + - "(" + ModelConstants.ENTITY_TYPE_COLUMN + - "," + ModelConstants.ENTITY_ID_COLUMN + - "," + ModelConstants.KEY_COLUMN + - "," + ModelConstants.PARTITION_COLUMN + - "," + ModelConstants.TS_COLUMN + - "," + ModelConstants.BOOLEAN_VALUE_COLUMN + - "," + ModelConstants.STRING_VALUE_COLUMN + - "," + ModelConstants.LONG_VALUE_COLUMN + - "," + ModelConstants.DOUBLE_VALUE_COLUMN + - "," + ModelConstants.JSON_VALUE_COLUMN + ")" + - " VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?) USING TTL ?"); + saveWithNullWithTtlStmt = prepare(INSERT_WITH_NULL + " USING TTL ?"); } } finally { stmtCreationLock.unlock(); From 23545a64838746a4b322bf098defc3346d46a407 Mon Sep 17 00:00:00 2001 From: dashevchenko Date: Tue, 6 Feb 2024 15:28:55 +0200 Subject: [PATCH 171/179] CassandraBaseTimeseriesDao refactoring --- .../server/dao/timeseries/CassandraBaseTimeseriesDao.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dao/src/main/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDao.java b/dao/src/main/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDao.java index 833a18ad39..6b2ab7e07b 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDao.java @@ -86,7 +86,7 @@ public class CassandraBaseTimeseriesDao extends AbstractCassandraBaseTimeseriesD public static final String ASC_ORDER = "ASC"; public static final long SECONDS_IN_DAY = TimeUnit.DAYS.toSeconds(1); protected static final List FIXED_PARTITION = List.of(0L); - private static String INSERT_WITH_NULL = INSERT_INTO + ModelConstants.TS_KV_CF + + protected static final String INSERT_WITH_NULL = INSERT_INTO + ModelConstants.TS_KV_CF + "(" + ModelConstants.ENTITY_TYPE_COLUMN + "," + ModelConstants.ENTITY_ID_COLUMN + "," + ModelConstants.KEY_COLUMN + From cd46ebe53ae7f83163020d7ac986f4b0baa359fa Mon Sep 17 00:00:00 2001 From: ViacheslavKlimov Date: Tue, 6 Feb 2024 16:57:52 +0200 Subject: [PATCH 172/179] Fix SNMP traps processing --- .../snmp/service/SnmpTransportService.java | 39 +++++++++++-------- .../service/DefaultTransportService.java | 2 +- 2 files changed, 24 insertions(+), 17 deletions(-) diff --git a/common/transport/snmp/src/main/java/org/thingsboard/server/transport/snmp/service/SnmpTransportService.java b/common/transport/snmp/src/main/java/org/thingsboard/server/transport/snmp/service/SnmpTransportService.java index 26a1ef037e..3dc293b70b 100644 --- a/common/transport/snmp/src/main/java/org/thingsboard/server/transport/snmp/service/SnmpTransportService.java +++ b/common/transport/snmp/src/main/java/org/thingsboard/server/transport/snmp/service/SnmpTransportService.java @@ -37,7 +37,7 @@ import org.snmp4j.mp.MPv3; import org.snmp4j.security.SecurityModels; import org.snmp4j.security.SecurityProtocols; import org.snmp4j.security.USM; -import org.snmp4j.smi.Address; +import org.snmp4j.smi.IpAddress; import org.snmp4j.smi.OctetString; import org.snmp4j.smi.TcpAddress; import org.snmp4j.smi.UdpAddress; @@ -327,24 +327,31 @@ public class SnmpTransportService implements TbTransportService, CommandResponde } /* - * SNMP notifications handler - * - * TODO: add check for host uniqueness when saving device (for backward compatibility - only for the ones using from-device RPC requests) - * - * NOTE: SNMP TRAPs support won't work properly when there is more than one SNMP transport, - * due to load-balancing of requests from devices: session might not be on this instance - * */ + * SNMP notifications handler + * + * TODO: add check for host uniqueness when saving device (for backward compatibility - only for the ones using from-device RPC requests) + * + * NOTE: SNMP TRAPs support won't work properly when there is more than one SNMP transport, + * due to load-balancing of requests from devices: session might not be on this instance + * */ @Override public void processPdu(CommandResponderEvent event) { - Address sourceAddress = event.getPeerAddress(); - DeviceSessionContext sessionContext = transportContext.getSessions().stream() - .filter(session -> session.getTarget().getAddress().equals(sourceAddress)) - .findFirst().orElse(null); - if (sessionContext == null) { - log.warn("SNMP TRAP processing failed: couldn't find device session for address {}", sourceAddress); + IpAddress sourceAddress = (IpAddress) event.getPeerAddress(); + List sessions = transportContext.getSessions().stream() + .filter(session -> ((IpAddress) session.getTarget().getAddress()).getInetAddress().equals(sourceAddress.getInetAddress())) + .collect(Collectors.toList()); + if (sessions.isEmpty()) { + log.warn("Couldn't find device session for SNMP TRAP for address {}", sourceAddress); + return; + } else if (sessions.size() > 1) { + for (DeviceSessionContext sessionContext : sessions) { + transportService.errorEvent(sessionContext.getTenantId(), sessionContext.getDeviceId(), SnmpCommunicationSpec.TO_SERVER_RPC_REQUEST.getLabel(), + new IllegalStateException("Found multiple devices for host " + sourceAddress.getInetAddress().getHostAddress())); + } return; } + DeviceSessionContext sessionContext = sessions.get(0); try { processIncomingTrap(sessionContext, event); } catch (Throwable e) { @@ -356,11 +363,11 @@ public class SnmpTransportService implements TbTransportService, CommandResponde private void processIncomingTrap(DeviceSessionContext sessionContext, CommandResponderEvent event) { PDU pdu = event.getPDU(); if (pdu == null) { - log.warn("Got empty trap from device {}", sessionContext.getDeviceId()); + log.warn("[{}] Received empty SNMP trap", sessionContext.getDeviceId()); throw new IllegalArgumentException("Received TRAP with no data"); } - log.debug("Processing SNMP trap from device {} (PDU: {}}", sessionContext.getDeviceId(), pdu); + log.debug("[{}] Processing SNMP trap: {}", sessionContext.getDeviceId(), pdu); SnmpCommunicationConfig communicationConfig = sessionContext.getProfileTransportConfiguration().getCommunicationConfigs().stream() .filter(config -> config.getSpec() == SnmpCommunicationSpec.TO_SERVER_RPC_REQUEST).findFirst() .orElseThrow(() -> new IllegalArgumentException("No config found for to-server RPC requests")); diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java index 504b9bdf6d..14f7bfffff 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java @@ -805,7 +805,7 @@ public class DefaultTransportService extends TransportActivityManager implements .setEntityIdLSB(deviceId.getId().getLeastSignificantBits()) .setServiceId(serviceInfoProvider.getServiceId()) .setMethod(method) - .setError(ExceptionUtils.getStackTrace(error))) + .setError(ExceptionUtils.getRootCauseMessage(error))) .build(); try { sendToCore(tenantId, deviceId, msg, deviceId.getId(), TransportServiceCallback.EMPTY); From f51df3211ddbbf642a15307503070e3f0d173a14 Mon Sep 17 00:00:00 2001 From: dashevchenko Date: Wed, 7 Feb 2024 13:37:14 +0200 Subject: [PATCH 173/179] fixed saveDeviceWithAccessToken method to delete device if credentials saving failed --- .../server/dao/device/DeviceServiceImpl.java | 1 + .../server/dao/service/DeviceServiceTest.java | 27 +++++++++++++++++-- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/dao/src/main/java/org/thingsboard/server/dao/device/DeviceServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/device/DeviceServiceImpl.java index f190923167..f06dfac9f9 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/device/DeviceServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/device/DeviceServiceImpl.java @@ -157,6 +157,7 @@ public class DeviceServiceImpl extends AbstractCachedEntityService deviceDao.findDeviceByTenantIdAndName(tenantId.getId(), name).orElse(null), true); } + @Transactional @Override public Device saveDeviceWithAccessToken(Device device, String accessToken) { return doSaveDevice(device, accessToken, true); diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/DeviceServiceTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/DeviceServiceTest.java index 61d1c845fc..822f26496b 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/DeviceServiceTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/DeviceServiceTest.java @@ -35,8 +35,6 @@ import org.thingsboard.server.common.data.OtaPackage; import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.Tenant; import org.thingsboard.server.common.data.TenantProfile; -import org.thingsboard.server.common.data.asset.Asset; -import org.thingsboard.server.common.data.asset.AssetProfile; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.ota.ChecksumAlgorithm; @@ -50,6 +48,7 @@ import org.thingsboard.server.dao.device.DeviceCredentialsService; import org.thingsboard.server.dao.device.DeviceProfileService; import org.thingsboard.server.dao.device.DeviceService; import org.thingsboard.server.dao.exception.DataValidationException; +import org.thingsboard.server.dao.exception.DeviceCredentialsValidationException; import org.thingsboard.server.dao.ota.OtaPackageService; import org.thingsboard.server.dao.tenant.TenantProfileService; @@ -129,6 +128,30 @@ public class DeviceServiceTest extends AbstractServiceTest { }); } + @Test + public void testSaveDevicesWithTheSameAccessToken() { + Device device = new Device(); + device.setTenantId(tenantId); + device.setName(StringUtils.randomAlphabetic(10)); + device.setType("default"); + String accessToken = StringUtils.generateSafeToken(10); + Device savedDevice = deviceService.saveDeviceWithAccessToken(device, accessToken); + + DeviceCredentials deviceCredentials = deviceCredentialsService.findDeviceCredentialsByDeviceId(tenantId, savedDevice.getId()); + Assert.assertEquals(accessToken, deviceCredentials.getCredentialsId()); + + Device duplicatedDevice = new Device(); + duplicatedDevice.setTenantId(tenantId); + duplicatedDevice.setName(StringUtils.randomAlphabetic(10)); + duplicatedDevice.setType("default"); + assertThatThrownBy(() -> deviceService.saveDeviceWithAccessToken(duplicatedDevice, accessToken)) + .isInstanceOf(DeviceCredentialsValidationException.class) + .hasMessageContaining("Device credentials are already assigned to another device!"); + + Device deviceByName = deviceService.findDeviceByTenantIdAndName(tenantId, duplicatedDevice.getName()); + Assertions.assertNull(deviceByName); + } + @Test public void testCountByTenantId() { Assert.assertEquals(0, deviceService.countByTenantId(tenantId)); From 07ff729d61b1ade57a3bc202f22b192de65052d1 Mon Sep 17 00:00:00 2001 From: dashevchenko Date: Wed, 7 Feb 2024 15:23:31 +0200 Subject: [PATCH 174/179] added Transactional for saveDevice(Device device, boolean doValidate) and saveDevice(Device device) --- .../server/dao/device/DeviceServiceImpl.java | 2 + .../server/dao/service/DeviceServiceTest.java | 45 +++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/dao/src/main/java/org/thingsboard/server/dao/device/DeviceServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/device/DeviceServiceImpl.java index f06dfac9f9..2f7fe0680c 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/device/DeviceServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/device/DeviceServiceImpl.java @@ -163,11 +163,13 @@ public class DeviceServiceImpl extends AbstractCachedEntityService idComparator = new IdComparator<>(); private TenantId anotherTenantId; @@ -152,6 +160,43 @@ public class DeviceServiceTest extends AbstractServiceTest { Assertions.assertNull(deviceByName); } + @Test + public void testShouldRollbackNotValidatedDeviceIfDeviceCredentialsValidationFailed() { + Mockito.reset(validator); + Mockito.doThrow(new DataValidationException("mock message")) + .when(validator).validate(any(), any()); + + Device device = new Device(); + device.setTenantId(tenantId); + device.setName(StringUtils.randomAlphabetic(10)); + device.setType("default"); + assertThatThrownBy(() -> deviceService.saveDevice(device, false)) + .isInstanceOf(DataValidationException.class) + .hasMessageContaining("mock message"); + + Device deviceByName = deviceService.findDeviceByTenantIdAndName(tenantId, device.getName()); + Assertions.assertNull(deviceByName); + } + + @Test + public void testShouldRollbackValidatedDeviceIfDeviceCredentialsValidationFailed() { + Mockito.reset(validator); + Mockito.doThrow(new DataValidationException("mock message")) + .when(validator).validate(any(), any()); + + Device device = new Device(); + device.setTenantId(tenantId); + device.setName(StringUtils.randomAlphabetic(10)); + device.setType("default"); + + assertThatThrownBy(() -> deviceService.saveDevice(device)) + .isInstanceOf(DataValidationException.class) + .hasMessageContaining("mock message"); + + Device deviceByName = deviceService.findDeviceByTenantIdAndName(tenantId, device.getName()); + Assertions.assertNull(deviceByName); + } + @Test public void testCountByTenantId() { Assert.assertEquals(0, deviceService.countByTenantId(tenantId)); From 021252197f861b3796fc314efc0d73d0428fe433 Mon Sep 17 00:00:00 2001 From: Andrii Landiak Date: Thu, 8 Feb 2024 14:36:27 +0200 Subject: [PATCH 175/179] Fix compile error for BaseEdgeEventService --- .../org/thingsboard/server/dao/edge/BaseEdgeEventService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dao/src/main/java/org/thingsboard/server/dao/edge/BaseEdgeEventService.java b/dao/src/main/java/org/thingsboard/server/dao/edge/BaseEdgeEventService.java index 43c3dc4914..4d1e126c49 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/edge/BaseEdgeEventService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/edge/BaseEdgeEventService.java @@ -19,6 +19,7 @@ import com.google.common.util.concurrent.ListenableFuture; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; +import org.thingsboard.server.cache.limits.RateLimitService; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.edge.EdgeEvent; import org.thingsboard.server.common.data.id.EdgeId; @@ -28,7 +29,6 @@ import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.TimePageLink; import org.thingsboard.server.common.msg.tools.TbRateLimitsException; import org.thingsboard.server.dao.service.DataValidator; -import org.thingsboard.server.dao.util.limits.RateLimitService; @Service @Slf4j From 7a28286b0530d4199fa8ee7ba41fc1535d5ffa0b Mon Sep 17 00:00:00 2001 From: Andrii Shvaika Date: Thu, 8 Feb 2024 14:59:27 +0200 Subject: [PATCH 176/179] Hints and description improvements --- .../data/json/system/widget_bundles/buttons.json | 2 +- .../json/system/widget_types/action_button.json | 6 ++++-- .../json/system/widget_types/command_button.json | 7 +++++-- .../json/system/widget_types/single_switch.json | 7 +++++-- .../src/assets/locale/locale.constant-en_US.json | 14 +++++++------- 5 files changed, 22 insertions(+), 14 deletions(-) diff --git a/application/src/main/data/json/system/widget_bundles/buttons.json b/application/src/main/data/json/system/widget_bundles/buttons.json index a48fba892b..8e7584d7c5 100644 --- a/application/src/main/data/json/system/widget_bundles/buttons.json +++ b/application/src/main/data/json/system/widget_bundles/buttons.json @@ -3,7 +3,7 @@ "alias": "buttons", "title": "Buttons", "image": "tb-image:YnV0dG9ucy5zdmc=:IkJ1dHRvbnMiIHN5c3RlbSBidW5kbGUgaW1hZ2U=;data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAwIiBoZWlnaHQ9IjE2MCIgdmlld0JveD0iMCAwIDIwMCAxNjAiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHg9IjAuNzUiIHk9IjEyLjc1IiB3aWR0aD0iMTk4LjUiIGhlaWdodD0iNTguNSIgcng9IjMuMjUiIGZpbGw9IndoaXRlIi8+CjxyZWN0IHg9IjAuNzUiIHk9IjEyLjc1IiB3aWR0aD0iMTk4LjUiIGhlaWdodD0iNTguNSIgcng9IjMuMjUiIHN0cm9rZT0iIzNGNTJERCIgc3Ryb2tlLXdpZHRoPSIxLjUiLz4KPHBhdGggZD0iTTYyLjE2NjMgNTEuMzMzM1Y0NC4zMzMzSDY2LjgzM1Y1MS4zMzMzSDcyLjY2NjNWNDJINzYuMTY2M0w2NC40OTk3IDMxLjVMNTIuODMzIDQySDU2LjMzM1Y1MS4zMzMzSDYyLjE2NjNaIiBmaWxsPSIjM0Y1MkREIi8+CjxwYXRoIGQ9Ik05MC4xOTUzIDQyLjkzMTZIODYuMjFMODYuMTg4NSA0MC45NjU4SDg5LjY2ODlDOTAuMjU2MiA0MC45NjU4IDkwLjc1MzkgNDAuODc5OSA5MS4xNjIxIDQwLjcwOEM5MS41Nzc1IDQwLjUyOSA5MS44OTI2IDQwLjI3NDcgOTIuMTA3NCAzOS45NDUzQzkyLjMyMjMgMzkuNjA4NyA5Mi40Mjk3IDM5LjIwNDEgOTIuNDI5NyAzOC43MzE0QzkyLjQyOTcgMzguMjA4NyA5Mi4zMjk0IDM3Ljc4MjYgOTIuMTI4OSAzNy40NTMxQzkxLjkyODQgMzcuMTIzNyA5MS42MjA0IDM2Ljg4MzggOTEuMjA1MSAzNi43MzM0QzkwLjc5NjkgMzYuNTgzIDkwLjI3NDEgMzYuNTA3OCA4OS42MzY3IDM2LjUwNzhIODcuMDI2NFY1MEg4NC4zMzAxVjM0LjM1OTRIODkuNjM2N0M5MC40OTYxIDM0LjM1OTQgOTEuMjYyNCAzNC40NDE3IDkxLjkzNTUgMzQuNjA2NEM5Mi42MTU5IDM0Ljc3MTIgOTMuMTkyNCAzNS4wMjkgOTMuNjY1IDM1LjM3OTlDOTQuMTQ0OSAzNS43MjM2IDk0LjUwNjUgMzYuMTYwNSA5NC43NSAzNi42OTA0Qzk1LjAwMDcgMzcuMjIwNCA5NS4xMjYgMzcuODUwNiA5NS4xMjYgMzguNTgxMUM5NS4xMjYgMzkuMjI1NiA5NC45NzIgMzkuODE2NCA5NC42NjQxIDQwLjM1MzVDOTQuMzU2MSA0MC44ODM1IDkzLjkwMTQgNDEuMzE2NyA5My4yOTk4IDQxLjY1MzNDOTIuNjk4MiA0MS45ODk5IDkxLjk0OTkgNDIuMTkwNCA5MS4wNTQ3IDQyLjI1NDlMOTAuMTk1MyA0Mi45MzE2Wk05MC4wNzcxIDUwSDg1LjM2MTNMODYuNTc1MiA0Ny44NjIzSDkwLjA3NzFDOTAuNjg1OSA0Ny44NjIzIDkxLjE5NDMgNDcuNzYyIDkxLjYwMjUgNDcuNTYxNUM5Mi4wMTA3IDQ3LjM1MzggOTIuMzE1MSA0Ny4wNzEgOTIuNTE1NiA0Ni43MTI5QzkyLjcyMzMgNDYuMzQ3NyA5Mi44MjcxIDQ1LjkyMTUgOTIuODI3MSA0NS40MzQ2QzkyLjgyNzEgNDQuOTI2MSA5Mi43Mzc2IDQ0LjQ4NTcgOTIuNTU4NiA0NC4xMTMzQzkyLjM3OTYgNDMuNzMzNyA5Mi4wOTY3IDQzLjQ0MzcgOTEuNzEgNDMuMjQzMkM5MS4zMjMyIDQzLjAzNTUgOTAuODE4NCA0Mi45MzE2IDkwLjE5NTMgNDIuOTMxNkg4Ny4xNjZMODcuMTg3NSA0MC45NjU4SDkxLjEyOTlMOTEuNzQyMiA0MS43MDdDOTIuNjAxNiA0MS43MzU3IDkzLjMwNyA0MS45MjU1IDkzLjg1ODQgNDIuMjc2NEM5NC40MTcgNDIuNjI3MyA5NC44MzI0IDQzLjA4MiA5NS4xMDQ1IDQzLjY0MDZDOTUuMzc2NiA0NC4xOTkyIDk1LjUxMjcgNDQuODAwOCA5NS41MTI3IDQ1LjQ0NTNDOTUuNTEyNyA0Ni40NDA4IDk1LjI5NDMgNDcuMjc1MSA5NC44NTc0IDQ3Ljk0ODJDOTQuNDI3NyA0OC42MjE0IDkzLjgwODMgNDkuMTMzNSA5Mi45OTkgNDkuNDg0NEM5Mi4xODk4IDQ5LjgyODEgOTEuMjE1OCA1MCA5MC4wNzcxIDUwWk0xMDUuMjE2IDQ3LjI2MDdWMzguMzc3SDEwNy44MTVWNTBIMTA1LjM2NkwxMDUuMjE2IDQ3LjI2MDdaTTEwNS41ODEgNDQuODQzOEwxMDYuNDUxIDQ0LjgyMjNDMTA2LjQ1MSA0NS42MDI5IDEwNi4zNjUgNDYuMzIyNiAxMDYuMTkzIDQ2Ljk4MTRDMTA2LjAyMSA0Ny42MzMxIDEwNS43NTcgNDguMjAyNSAxMDUuMzk4IDQ4LjY4OTVDMTA1LjA0IDQ5LjE2OTMgMTA0LjU4MiA0OS41NDUyIDEwNC4wMjMgNDkuODE3NEMxMDMuNDY1IDUwLjA4MjQgMTAyLjc5NSA1MC4yMTQ4IDEwMi4wMTUgNTAuMjE0OEMxMDEuNDQ5IDUwLjIxNDggMTAwLjkzIDUwLjEzMjUgMTAwLjQ1NyA0OS45Njc4Qzk5Ljk4NDQgNDkuODAzMSA5OS41NzYyIDQ5LjU0ODggOTkuMjMyNCA0OS4yMDUxQzk4Ljg5NTggNDguODYxMyA5OC42MzQ0IDQ4LjQxMzcgOTguNDQ4MiA0Ny44NjIzQzk4LjI2MiA0Ny4zMTA5IDk4LjE2ODkgNDYuNjUyIDk4LjE2ODkgNDUuODg1N1YzOC4zNzdIMTAwLjc1OFY0NS45MDcyQzEwMC43NTggNDYuMzI5OCAxMDAuODA4IDQ2LjY4NDIgMTAwLjkwOCA0Ni45NzA3QzEwMS4wMDggNDcuMjUgMTAxLjE0NSA0Ny40NzU2IDEwMS4zMTYgNDcuNjQ3NUMxMDEuNDg4IDQ3LjgxOTMgMTAxLjY4OSA0Ny45NDExIDEwMS45MTggNDguMDEyN0MxMDIuMTQ3IDQ4LjA4NDMgMTAyLjM5MSA0OC4xMjAxIDEwMi42NDggNDguMTIwMUMxMDMuMzg2IDQ4LjEyMDEgMTAzLjk2NiA0Ny45NzY5IDEwNC4zODkgNDcuNjkwNEMxMDQuODE4IDQ3LjM5NjggMTA1LjEyMyA0Ny4wMDI5IDEwNS4zMDIgNDYuNTA4OEMxMDUuNDg4IDQ2LjAxNDYgMTA1LjU4MSA0NS40NTk2IDEwNS41ODEgNDQuODQzOFpNMTE2LjA0NyAzOC4zNzdWNDAuMjY3NkgxMDkuNDk0VjM4LjM3N0gxMTYuMDQ3Wk0xMTEuMzg1IDM1LjUzMDNIMTEzLjk3NFY0Ni43ODgxQzExMy45NzQgNDcuMTQ2MiAxMTQuMDI0IDQ3LjQyMTkgMTE0LjEyNCA0Ny42MTUyQzExNC4yMzEgNDcuODAxNCAxMTQuMzc4IDQ3LjkyNjggMTE0LjU2NCA0Ny45OTEyQzExNC43NTEgNDguMDU1NyAxMTQuOTY5IDQ4LjA4NzkgMTE1LjIyIDQ4LjA4NzlDMTE1LjM5OSA0OC4wODc5IDExNS41NzEgNDguMDc3MSAxMTUuNzM1IDQ4LjA1NTdDMTE1LjkgNDguMDM0MiAxMTYuMDMzIDQ4LjAxMjcgMTE2LjEzMyA0Ny45OTEyTDExNi4xNDQgNDkuOTY3OEMxMTUuOTI5IDUwLjAzMjIgMTE1LjY3OCA1MC4wODk1IDExNS4zOTIgNTAuMTM5NkMxMTUuMTEyIDUwLjE4OTggMTE0Ljc5IDUwLjIxNDggMTE0LjQyNSA1MC4yMTQ4QzExMy44MyA1MC4yMTQ4IDExMy4zMDQgNTAuMTExIDExMi44NDYgNDkuOTAzM0MxMTIuMzg3IDQ5LjY4ODUgMTEyLjAyOSA0OS4zNDExIDExMS43NzEgNDguODYxM0MxMTEuNTE0IDQ4LjM4MTUgMTExLjM4NSA0Ny43NDQxIDExMS4zODUgNDYuOTQ5MlYzNS41MzAzWk0xMjMuNjIzIDM4LjM3N1Y0MC4yNjc2SDExNy4wN1YzOC4zNzdIMTIzLjYyM1pNMTE4Ljk2MSAzNS41MzAzSDEyMS41NVY0Ni43ODgxQzEyMS41NSA0Ny4xNDYyIDEyMS42IDQ3LjQyMTkgMTIxLjcgNDcuNjE1MkMxMjEuODA4IDQ3LjgwMTQgMTIxLjk1NCA0Ny45MjY4IDEyMi4xNDEgNDcuOTkxMkMxMjIuMzI3IDQ4LjA1NTcgMTIyLjU0NSA0OC4wODc5IDEyMi43OTYgNDguMDg3OUMxMjIuOTc1IDQ4LjA4NzkgMTIzLjE0NyA0OC4wNzcxIDEyMy4zMTIgNDguMDU1N0MxMjMuNDc2IDQ4LjAzNDIgMTIzLjYwOSA0OC4wMTI3IDEyMy43MDkgNDcuOTkxMkwxMjMuNzIgNDkuOTY3OEMxMjMuNTA1IDUwLjAzMjIgMTIzLjI1NCA1MC4wODk1IDEyMi45NjggNTAuMTM5NkMxMjIuNjg4IDUwLjE4OTggMTIyLjM2NiA1MC4yMTQ4IDEyMi4wMDEgNTAuMjE0OEMxMjEuNDA3IDUwLjIxNDggMTIwLjg4IDUwLjExMSAxMjAuNDIyIDQ5LjkwMzNDMTE5Ljk2NCA0OS42ODg1IDExOS42MDUgNDkuMzQxMSAxMTkuMzQ4IDQ4Ljg2MTNDMTE5LjA5IDQ4LjM4MTUgMTE4Ljk2MSA0Ny43NDQxIDExOC45NjEgNDYuOTQ5MlYzNS41MzAzWk0xMjUuMTE5IDQ0LjMxNzRWNDQuMDcwM0MxMjUuMTE5IDQzLjIzMjQgMTI1LjI0MSA0Mi40NTU0IDEyNS40ODQgNDEuNzM5M0MxMjUuNzI4IDQxLjAxNiAxMjYuMDc5IDQwLjM4OTMgMTI2LjUzNyAzOS44NTk0QzEyNy4wMDMgMzkuMzIyMyAxMjcuNTY4IDM4LjkwNjkgMTI4LjIzNCAzOC42MTMzQzEyOC45MDggMzguMzEyNSAxMjkuNjY3IDM4LjE2MjEgMTMwLjUxMiAzOC4xNjIxQzEzMS4zNjQgMzguMTYyMSAxMzIuMTIzIDM4LjMxMjUgMTMyLjc4OSAzOC42MTMzQzEzMy40NjIgMzguOTA2OSAxMzQuMDMyIDM5LjMyMjMgMTM0LjQ5NyAzOS44NTk0QzEzNC45NjMgNDAuMzg5MyAxMzUuMzE3IDQxLjAxNiAxMzUuNTYxIDQxLjczOTNDMTM1LjgwNCA0Mi40NTU0IDEzNS45MjYgNDMuMjMyNCAxMzUuOTI2IDQ0LjA3MDNWNDQuMzE3NEMxMzUuOTI2IDQ1LjE1NTMgMTM1LjgwNCA0NS45MzIzIDEzNS41NjEgNDYuNjQ4NEMxMzUuMzE3IDQ3LjM2NDYgMTM0Ljk2MyA0Ny45OTEyIDEzNC40OTcgNDguNTI4M0MxMzQuMDMyIDQ5LjA1ODMgMTMzLjQ2NiA0OS40NzM2IDEzMi44IDQ5Ljc3NDRDMTMyLjEzNCA1MC4wNjggMTMxLjM3OCA1MC4yMTQ4IDEzMC41MzMgNTAuMjE0OEMxMjkuNjgxIDUwLjIxNDggMTI4LjkxOCA1MC4wNjggMTI4LjI0NSA0OS43NzQ0QzEyNy41NzkgNDkuNDczNiAxMjcuMDEzIDQ5LjA1ODMgMTI2LjU0OCA0OC41MjgzQzEyNi4wODIgNDcuOTkxMiAxMjUuNzI4IDQ3LjM2NDYgMTI1LjQ4NCA0Ni42NDg0QzEyNS4yNDEgNDUuOTMyMyAxMjUuMTE5IDQ1LjE1NTMgMTI1LjExOSA0NC4zMTc0Wk0xMjcuNzA4IDQ0LjA3MDNWNDQuMzE3NEMxMjcuNzA4IDQ0Ljg0MDIgMTI3Ljc2MiA0NS4zMzQzIDEyNy44NjkgNDUuNzk5OEMxMjcuOTc3IDQ2LjI2NTMgMTI4LjE0NSA0Ni42NzM1IDEyOC4zNzQgNDcuMDI0NEMxMjguNjAzIDQ3LjM3NTMgMTI4Ljg5NyA0Ny42NTEgMTI5LjI1NSA0Ny44NTE2QzEyOS42MTMgNDguMDUyMSAxMzAuMDM5IDQ4LjE1MjMgMTMwLjUzMyA0OC4xNTIzQzEzMS4wMTMgNDguMTUyMyAxMzEuNDI4IDQ4LjA1MjEgMTMxLjc3OSA0Ny44NTE2QzEzMi4xMzcgNDcuNjUxIDEzMi40MzEgNDcuMzc1MyAxMzIuNjYgNDcuMDI0NEMxMzIuODg5IDQ2LjY3MzUgMTMzLjA1OCA0Ni4yNjUzIDEzMy4xNjUgNDUuNzk5OEMxMzMuMjggNDUuMzM0MyAxMzMuMzM3IDQ0Ljg0MDIgMTMzLjMzNyA0NC4zMTc0VjQ0LjA3MDNDMTMzLjMzNyA0My41NTQ3IDEzMy4yOCA0My4wNjc3IDEzMy4xNjUgNDIuNjA5NEMxMzMuMDU4IDQyLjE0MzkgMTMyLjg4NiA0MS43MzIxIDEzMi42NDkgNDEuMzc0QzEzMi40MiA0MS4wMTYgMTMyLjEyNyA0MC43MzY3IDEzMS43NjkgNDAuNTM2MUMxMzEuNDE4IDQwLjMyODUgMTMwLjk5OSA0MC4yMjQ2IDEzMC41MTIgNDAuMjI0NkMxMzAuMDI1IDQwLjIyNDYgMTI5LjYwMiA0MC4zMjg1IDEyOS4yNDQgNDAuNTM2MUMxMjguODkzIDQwLjczNjcgMTI4LjYwMyA0MS4wMTYgMTI4LjM3NCA0MS4zNzRDMTI4LjE0NSA0MS43MzIxIDEyNy45NzcgNDIuMTQzOSAxMjcuODY5IDQyLjYwOTRDMTI3Ljc2MiA0My4wNjc3IDEyNy43MDggNDMuNTU0NyAxMjcuNzA4IDQ0LjA3MDNaTTE0MC45MTMgNDAuODU4NFY1MEgxMzguMzI0VjM4LjM3N0gxNDAuNzYzTDE0MC45MTMgNDAuODU4NFpNMTQwLjQ1MSA0My43NTg4TDEzOS42MTMgNDMuNzQ4QzEzOS42MiA0Mi45MjQ1IDEzOS43MzUgNDIuMTY4OSAxMzkuOTU3IDQxLjQ4MTRDMTQwLjE4NiA0MC43OTM5IDE0MC41MDEgNDAuMjAzMSAxNDAuOTAyIDM5LjcwOUMxNDEuMzExIDM5LjIxNDggMTQxLjc5OCAzOC44MzUzIDE0Mi4zNjMgMzguNTcwM0MxNDIuOTI5IDM4LjI5ODIgMTQzLjU1OSAzOC4xNjIxIDE0NC4yNTQgMzguMTYyMUMxNDQuODEyIDM4LjE2MjEgMTQ1LjMxNyAzOC4yNDA5IDE0NS43NjkgMzguMzk4NEMxNDYuMjI3IDM4LjU0ODggMTQ2LjYxNyAzOC43OTU5IDE0Ni45MzkgMzkuMTM5NkMxNDcuMjY5IDM5LjQ4MzQgMTQ3LjUyIDM5LjkzMSAxNDcuNjkxIDQwLjQ4MjRDMTQ3Ljg2MyA0MS4wMjY3IDE0Ny45NDkgNDEuNjk2MyAxNDcuOTQ5IDQyLjQ5MTJWNTBIMTQ1LjM1VjQyLjQ4MDVDMTQ1LjM1IDQxLjkyMTkgMTQ1LjI2NyA0MS40ODE0IDE0NS4xMDMgNDEuMTU5MkMxNDQuOTQ1IDQwLjgyOTggMTQ0LjcxMiA0MC41OTcgMTQ0LjQwNCA0MC40NjA5QzE0NC4xMDQgNDAuMzE3NyAxNDMuNzI4IDQwLjI0NjEgMTQzLjI3NiA0MC4yNDYxQzE0Mi44MzIgNDAuMjQ2MSAxNDIuNDM1IDQwLjMzOTIgMTQyLjA4NCA0MC41MjU0QzE0MS43MzMgNDAuNzExNiAxNDEuNDM2IDQwLjk2NTggMTQxLjE5MiA0MS4yODgxQzE0MC45NTYgNDEuNjEwNCAxNDAuNzczIDQxLjk4MjcgMTQwLjY0NSA0Mi40MDUzQzE0MC41MTYgNDIuODI3OCAxNDAuNDUxIDQzLjI3OSAxNDAuNDUxIDQzLjc1ODhaIiBmaWxsPSIjM0Y1MkREIi8+CjxyZWN0IHg9IjAuNzUiIHk9Ijg4Ljc1IiB3aWR0aD0iMTk4LjUiIGhlaWdodD0iNTguNSIgcng9IjMuMjUiIGZpbGw9IndoaXRlIi8+CjxyZWN0IHg9IjAuNzUiIHk9Ijg4Ljc1IiB3aWR0aD0iMTk4LjUiIGhlaWdodD0iNTguNSIgcng9IjMuMjUiIHN0cm9rZT0iIzNGNTJERCIgc3Ryb2tlLXdpZHRoPSIxLjUiLz4KPHBhdGggZD0iTTY1LjQ5OTcgMTExVjExMy4zMzNINzUuNTIxM0w2NC4zMzMgMTI0LjUyMkw2NS45NzggMTI2LjE2N0w3Ny4xNjYzIDExNC45NzhWMTI1SDc5LjQ5OTdWMTExSDY1LjQ5OTdaIiBmaWxsPSIjM0Y1MkREIi8+CjxwYXRoIGQ9Ik0xMDAuNTY0IDEyMS45NzJDMTAwLjU2NCAxMjEuNjQ5IDEwMC41MTQgMTIxLjM2MyAxMDAuNDE0IDEyMS4xMTJDMTAwLjMyMSAxMjAuODYyIDEwMC4xNTMgMTIwLjYzMiA5OS45MDkyIDEyMC40MjVDOTkuNjY1NyAxMjAuMjE3IDk5LjMyMTkgMTIwLjAxNyA5OC44Nzc5IDExOS44MjNDOTguNDQxMSAxMTkuNjIzIDk3Ljg4MjUgMTE5LjQxOSA5Ny4yMDIxIDExOS4yMTFDOTYuNDU3NCAxMTguOTgyIDk1Ljc2OTkgMTE4LjcyOCA5NS4xMzk2IDExOC40NDhDOTQuNTE2NiAxMTguMTYyIDkzLjk3MjMgMTE3LjgzMiA5My41MDY4IDExNy40NkM5My4wNDEzIDExNy4wOCA5Mi42Nzk3IDExNi42NDcgOTIuNDIxOSAxMTYuMTZDOTIuMTY0MSAxMTUuNjY2IDkyLjAzNTIgMTE1LjA5NyA5Mi4wMzUyIDExNC40NTJDOTIuMDM1MiAxMTMuODE1IDkyLjE2NzYgMTEzLjIzNSA5Mi40MzI2IDExMi43MTJDOTIuNzA0OCAxMTIuMTg5IDkzLjA4NzkgMTExLjczOCA5My41ODIgMTExLjM1OEM5NC4wODMzIDExMC45NzIgOTQuNjc0MiAxMTAuNjc0IDk1LjM1NDUgMTEwLjQ2N0M5Ni4wMzQ4IDExMC4yNTIgOTYuNzg2OCAxMTAuMTQ1IDk3LjYxMDQgMTEwLjE0NUM5OC43NzA1IDExMC4xNDUgOTkuNzY5NSAxMTAuMzU5IDEwMC42MDcgMTEwLjc4OUMxMDEuNDUyIDExMS4yMTkgMTAyLjEwMSAxMTEuNzk1IDEwMi41NTIgMTEyLjUxOUMxMDMuMDEgMTEzLjI0MiAxMDMuMjM5IDExNC4wNCAxMDMuMjM5IDExNC45MTRIMTAwLjU2NEMxMDAuNTY0IDExNC4zOTggMTAwLjQ1MyAxMTMuOTQ0IDEwMC4yMzEgMTEzLjU1QzEwMC4wMTcgMTEzLjE0OSA5OS42ODcyIDExMi44MzQgOTkuMjQzMiAxMTIuNjA0Qzk4LjgwNjMgMTEyLjM3NSA5OC4yNTEzIDExMi4yNjEgOTcuNTc4MSAxMTIuMjYxQzk2Ljk0MDggMTEyLjI2MSA5Ni40MTA4IDExMi4zNTcgOTUuOTg4MyAxMTIuNTUxQzk1LjU2NTggMTEyLjc0NCA5NS4yNTA3IDExMy4wMDYgOTUuMDQzIDExMy4zMzVDOTQuODM1MyAxMTMuNjY0IDk0LjczMTQgMTE0LjAzNyA5NC43MzE0IDExNC40NTJDOTQuNzMxNCAxMTQuNzQ2IDk0Ljc5OTUgMTE1LjAxNCA5NC45MzU1IDExNS4yNThDOTUuMDcxNiAxMTUuNDk0IDk1LjI3OTMgMTE1LjcxNiA5NS41NTg2IDExNS45MjRDOTUuODM3OSAxMTYuMTI0IDk2LjE4ODggMTE2LjMxNCA5Ni42MTEzIDExNi40OTNDOTcuMDMzOSAxMTYuNjcyIDk3LjUzMTYgMTE2Ljg0NCA5OC4xMDQ1IDExNy4wMDlDOTguOTcxIDExNy4yNjcgOTkuNzI2NiAxMTcuNTUzIDEwMC4zNzEgMTE3Ljg2OEMxMDEuMDE2IDExOC4xNzYgMTAxLjU1MyAxMTguNTI3IDEwMS45ODIgMTE4LjkyMUMxMDIuNDEyIDExOS4zMTUgMTAyLjczNCAxMTkuNzYyIDEwMi45NDkgMTIwLjI2NEMxMDMuMTY0IDEyMC43NTggMTAzLjI3MSAxMjEuMzIgMTAzLjI3MSAxMjEuOTVDMTAzLjI3MSAxMjIuNjA5IDEwMy4xMzkgMTIzLjIwMyAxMDIuODc0IDEyMy43MzNDMTAyLjYwOSAxMjQuMjU2IDEwMi4yMjkgMTI0LjcwNCAxMDEuNzM1IDEyNS4wNzZDMTAxLjI0OCAxMjUuNDQxIDEwMC42NjEgMTI1LjcyNCA5OS45NzM2IDEyNS45MjVDOTkuMjkzMyAxMjYuMTE4IDk4LjUzNDIgMTI2LjIxNSA5Ny42OTYzIDEyNi4yMTVDOTYuOTQ0MyAxMjYuMjE1IDk2LjIwMzEgMTI2LjExNSA5NS40NzI3IDEyNS45MTRDOTQuNzQ5MyAxMjUuNzE0IDk0LjA5MDUgMTI1LjQwOSA5My40OTYxIDEyNS4wMDFDOTIuOTAxNyAxMjQuNTg2IDkyLjQyOSAxMjQuMDcgOTIuMDc4MSAxMjMuNDU0QzkxLjcyNzIgMTIyLjgzMSA5MS41NTE4IDEyMi4xMDQgOTEuNTUxOCAxMjEuMjczSDk0LjI0OEM5NC4yNDggMTIxLjc4MiA5NC4zMzQgMTIyLjIxNSA5NC41MDU5IDEyMi41NzNDOTQuNjg0OSAxMjIuOTMxIDk0LjkzMiAxMjMuMjI1IDk1LjI0NzEgMTIzLjQ1NEM5NS41NjIyIDEyMy42NzYgOTUuOTI3NCAxMjMuODQxIDk2LjM0MjggMTIzLjk0OEM5Ni43NjUzIDEyNC4wNTYgOTcuMjE2NSAxMjQuMTA5IDk3LjY5NjMgMTI0LjEwOUM5OC4zMjY1IDEyNC4xMDkgOTguODUyOSAxMjQuMDIgOTkuMjc1NCAxMjMuODQxQzk5LjcwNTEgMTIzLjY2MiAxMDAuMDI3IDEyMy40MTEgMTAwLjI0MiAxMjMuMDg5QzEwMC40NTcgMTIyLjc2NyAxMDAuNTY0IDEyMi4zOTQgMTAwLjU2NCAxMjEuOTcyWk0xMTAuNzcyIDEyNi4yMTVDMTA5LjkxMyAxMjYuMjE1IDEwOS4xMzYgMTI2LjA3NSAxMDguNDQxIDEyNS43OTZDMTA3Ljc1NCAxMjUuNTA5IDEwNy4xNjcgMTI1LjExMiAxMDYuNjggMTI0LjYwNEMxMDYuMiAxMjQuMDk1IDEwNS44MzEgMTIzLjQ5NyAxMDUuNTczIDEyMi44MUMxMDUuMzE1IDEyMi4xMjIgMTA1LjE4NyAxMjEuMzgxIDEwNS4xODcgMTIwLjU4NlYxMjAuMTU2QzEwNS4xODcgMTE5LjI0NyAxMDUuMzE5IDExOC40MjMgMTA1LjU4NCAxMTcuNjg2QzEwNS44NDkgMTE2Ljk0OCAxMDYuMjE4IDExNi4zMTggMTA2LjY5IDExNS43OTVDMTA3LjE2MyAxMTUuMjY1IDEwNy43MjIgMTE0Ljg2IDEwOC4zNjYgMTE0LjU4MUMxMDkuMDExIDExNC4zMDIgMTA5LjcwOSAxMTQuMTYyIDExMC40NjEgMTE0LjE2MkMxMTEuMjkyIDExNC4xNjIgMTEyLjAxOSAxMTQuMzAyIDExMi42NDIgMTE0LjU4MUMxMTMuMjY1IDExNC44NiAxMTMuNzggMTE1LjI1NCAxMTQuMTg4IDExNS43NjNDMTE0LjYwNCAxMTYuMjY0IDExNC45MTIgMTE2Ljg2MiAxMTUuMTEyIDExNy41NTdDMTE1LjMyIDExOC4yNTEgMTE1LjQyNCAxMTkuMDE4IDExNS40MjQgMTE5Ljg1NVYxMjAuOTYySDEwNi40NDNWMTE5LjEwNEgxMTIuODY3VjExOC44OTlDMTEyLjg1MyAxMTguNDM0IDExMi43NiAxMTcuOTk3IDExMi41ODggMTE3LjU4OUMxMTIuNDIzIDExNy4xODEgMTEyLjE2OSAxMTYuODUxIDExMS44MjUgMTE2LjYwMUMxMTEuNDgxIDExNi4zNSAxMTEuMDIzIDExNi4yMjUgMTEwLjQ1IDExNi4yMjVDMTEwLjAyMSAxMTYuMjI1IDEwOS42MzcgMTE2LjMxOCAxMDkuMzAxIDExNi41MDRDMTA4Ljk3MSAxMTYuNjgzIDEwOC42OTYgMTE2Ljk0NCAxMDguNDc0IDExNy4yODhDMTA4LjI1MiAxMTcuNjMyIDEwOC4wOCAxMTguMDQ3IDEwNy45NTggMTE4LjUzNEMxMDcuODQzIDExOS4wMTQgMTA3Ljc4NiAxMTkuNTU1IDEwNy43ODYgMTIwLjE1NlYxMjAuNTg2QzEwNy43ODYgMTIxLjA5NCAxMDcuODU0IDEyMS41NjcgMTA3Ljk5IDEyMi4wMDRDMTA4LjEzMyAxMjIuNDM0IDEwOC4zNDEgMTIyLjgxIDEwOC42MTMgMTIzLjEzMkMxMDguODg1IDEyMy40NTQgMTA5LjIxNSAxMjMuNzA4IDEwOS42MDIgMTIzLjg5NUMxMDkuOTg4IDEyNC4wNzQgMTEwLjQyOSAxMjQuMTYzIDExMC45MjMgMTI0LjE2M0MxMTEuNTQ2IDEyNC4xNjMgMTEyLjEwMSAxMjQuMDM4IDExMi41ODggMTIzLjc4N0MxMTMuMDc1IDEyMy41MzYgMTEzLjQ5NyAxMjMuMTgyIDExMy44NTUgMTIyLjcyNEwxMTUuMjIgMTI0LjA0NUMxMTQuOTY5IDEyNC40MSAxMTQuNjQzIDEyNC43NjEgMTE0LjI0MiAxMjUuMDk4QzExMy44NDEgMTI1LjQyNyAxMTMuMzUxIDEyNS42OTYgMTEyLjc3MSAxMjUuOTAzQzExMi4xOTggMTI2LjExMSAxMTEuNTMyIDEyNi4yMTUgMTEwLjc3MiAxMjYuMjE1Wk0xMjAuMjYxIDExNi44NThWMTI2SDExNy42NzJWMTE0LjM3N0gxMjAuMTFMMTIwLjI2MSAxMTYuODU4Wk0xMTkuNzk5IDExOS43NTlMMTE4Ljk2MSAxMTkuNzQ4QzExOC45NjggMTE4LjkyNCAxMTkuMDgzIDExOC4xNjkgMTE5LjMwNSAxMTcuNDgxQzExOS41MzQgMTE2Ljc5NCAxMTkuODQ5IDExNi4yMDMgMTIwLjI1IDExNS43MDlDMTIwLjY1OCAxMTUuMjE1IDEyMS4xNDUgMTE0LjgzNSAxMjEuNzExIDExNC41N0MxMjIuMjc3IDExNC4yOTggMTIyLjkwNyAxMTQuMTYyIDEyMy42MDIgMTE0LjE2MkMxMjQuMTYgMTE0LjE2MiAxMjQuNjY1IDExNC4yNDEgMTI1LjExNiAxMTQuMzk4QzEyNS41NzUgMTE0LjU0OSAxMjUuOTY1IDExNC43OTYgMTI2LjI4NyAxMTUuMTRDMTI2LjYxNyAxMTUuNDgzIDEyNi44NjcgMTE1LjkzMSAxMjcuMDM5IDExNi40ODJDMTI3LjIxMSAxMTcuMDI3IDEyNy4yOTcgMTE3LjY5NiAxMjcuMjk3IDExOC40OTFWMTI2SDEyNC42OTdWMTE4LjQ4QzEyNC42OTcgMTE3LjkyMiAxMjQuNjE1IDExNy40ODEgMTI0LjQ1IDExNy4xNTlDMTI0LjI5MyAxMTYuODMgMTI0LjA2IDExNi41OTcgMTIzLjc1MiAxMTYuNDYxQzEyMy40NTEgMTE2LjMxOCAxMjMuMDc1IDExNi4yNDYgMTIyLjYyNCAxMTYuMjQ2QzEyMi4xOCAxMTYuMjQ2IDEyMS43ODMgMTE2LjMzOSAxMjEuNDMyIDExNi41MjVDMTIxLjA4MSAxMTYuNzEyIDEyMC43ODQgMTE2Ljk2NiAxMjAuNTQgMTE3LjI4OEMxMjAuMzA0IDExNy42MSAxMjAuMTIxIDExNy45ODMgMTE5Ljk5MiAxMTguNDA1QzExOS44NjMgMTE4LjgyOCAxMTkuNzk5IDExOS4yNzkgMTE5Ljc5OSAxMTkuNzU5Wk0xMzcuMjc5IDEyMy41OTRWMTA5LjVIMTM5Ljg3OVYxMjZIMTM3LjUyNkwxMzcuMjc5IDEyMy41OTRaTTEyOS43MTcgMTIwLjMxN1YxMjAuMDkyQzEyOS43MTcgMTE5LjIxMSAxMjkuODIxIDExOC40MDkgMTMwLjAyOCAxMTcuNjg2QzEzMC4yMzYgMTE2Ljk1NSAxMzAuNTM3IDExNi4zMjggMTMwLjkzMSAxMTUuODA2QzEzMS4zMjUgMTE1LjI3NiAxMzEuODA0IDExNC44NzEgMTMyLjM3IDExNC41OTJDMTMyLjkzNiAxMTQuMzA1IDEzMy41NzMgMTE0LjE2MiAxMzQuMjgyIDExNC4xNjJDMTM0Ljk4NCAxMTQuMTYyIDEzNS42IDExNC4yOTggMTM2LjEzIDExNC41N0MxMzYuNjYgMTE0Ljg0MiAxMzcuMTExIDExNS4yMzMgMTM3LjQ4MyAxMTUuNzQxQzEzNy44NTYgMTE2LjI0MyAxMzguMTUzIDExNi44NDQgMTM4LjM3NSAxMTcuNTQ2QzEzOC41OTcgMTE4LjI0MSAxMzguNzU1IDExOS4wMTQgMTM4Ljg0OCAxMTkuODY2VjEyMC41ODZDMTM4Ljc1NSAxMjEuNDE3IDEzOC41OTcgMTIyLjE3NiAxMzguMzc1IDEyMi44NjNDMTM4LjE1MyAxMjMuNTUxIDEzNy44NTYgMTI0LjE0NSAxMzcuNDgzIDEyNC42NDZDMTM3LjExMSAxMjUuMTQ4IDEzNi42NTYgMTI1LjUzNSAxMzYuMTE5IDEyNS44MDdDMTM1LjU4OSAxMjYuMDc5IDEzNC45NyAxMjYuMjE1IDEzNC4yNjEgMTI2LjIxNUMxMzMuNTU5IDEyNi4yMTUgMTMyLjkyNSAxMjYuMDY4IDEzMi4zNTkgMTI1Ljc3NEMxMzEuODAxIDEyNS40ODEgMTMxLjMyNSAxMjUuMDY5IDEzMC45MzEgMTI0LjUzOUMxMzAuNTM3IDEyNC4wMDkgMTMwLjIzNiAxMjMuMzg2IDEzMC4wMjggMTIyLjY3QzEyOS44MjEgMTIxLjk0NyAxMjkuNzE3IDEyMS4xNjIgMTI5LjcxNyAxMjAuMzE3Wk0xMzIuMzA2IDEyMC4wOTJWMTIwLjMxN0MxMzIuMzA2IDEyMC44NDcgMTMyLjM1MiAxMjEuMzQxIDEzMi40NDUgMTIxLjhDMTMyLjU0NiAxMjIuMjU4IDEzMi43IDEyMi42NjMgMTMyLjkwNyAxMjMuMDE0QzEzMy4xMTUgMTIzLjM1NyAxMzMuMzgzIDEyMy42MyAxMzMuNzEzIDEyMy44M0MxMzQuMDQ5IDEyNC4wMjMgMTM0LjQ1MSAxMjQuMTIgMTM0LjkxNiAxMjQuMTJDMTM1LjUwMyAxMjQuMTIgMTM1Ljk4NyAxMjMuOTkxIDEzNi4zNjYgMTIzLjczM0MxMzYuNzQ2IDEyMy40NzYgMTM3LjA0MyAxMjMuMTI4IDEzNy4yNTggMTIyLjY5MUMxMzcuNDggMTIyLjI0NyAxMzcuNjMgMTIxLjc1MyAxMzcuNzA5IDEyMS4yMDlWMTE5LjI2NUMxMzcuNjY2IDExOC44NDIgMTM3LjU3NiAxMTguNDQ4IDEzNy40NCAxMTguMDgzQzEzNy4zMTIgMTE3LjcxOCAxMzcuMTM2IDExNy4zOTkgMTM2LjkxNCAxMTcuMTI3QzEzNi42OTIgMTE2Ljg0OCAxMzYuNDE2IDExNi42MzMgMTM2LjA4NyAxMTYuNDgyQzEzNS43NjUgMTE2LjMyNSAxMzUuMzgyIDExNi4yNDYgMTM0LjkzOCAxMTYuMjQ2QzEzNC40NjUgMTE2LjI0NiAxMzQuMDY0IDExNi4zNDYgMTMzLjczNCAxMTYuNTQ3QzEzMy40MDUgMTE2Ljc0NyAxMzMuMTMzIDExNy4wMjMgMTMyLjkxOCAxMTcuMzc0QzEzMi43MSAxMTcuNzI1IDEzMi41NTYgMTE4LjEzMyAxMzIuNDU2IDExOC41OTlDMTMyLjM1NiAxMTkuMDY0IDEzMi4zMDYgMTE5LjU2MiAxMzIuMzA2IDEyMC4wOTJaIiBmaWxsPSIjM0Y1MkREIi8+Cjwvc3ZnPgo=", - "description": null, + "description": "Facilitates user interaction by enabling navigation between dashboard states, sending RPC commands to devices, and updating device attributes or time-series data.", "order": 7500, "name": "Buttons" }, diff --git a/application/src/main/data/json/system/widget_types/action_button.json b/application/src/main/data/json/system/widget_types/action_button.json index e6ffa8084e..a73aa198e7 100644 --- a/application/src/main/data/json/system/widget_types/action_button.json +++ b/application/src/main/data/json/system/widget_types/action_button.json @@ -3,7 +3,7 @@ "name": "Action button", "deprecated": false, "image": "tb-image:YWN0aW9uLWJ1dHRvbi5zdmc=:IkFjdGlvbiBidXR0b24iIHN5c3RlbSB3aWRnZXQgaW1hZ2U=;data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAwIiBoZWlnaHQ9IjE2MCIgdmlld0JveD0iMCAwIDIwMCAxNjAiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHg9IjAuNzUiIHk9IjUwLjc1IiB3aWR0aD0iMTk4LjUiIGhlaWdodD0iNTguNSIgcng9IjMuMjUiIGZpbGw9IndoaXRlIi8+CjxyZWN0IHg9IjAuNzUiIHk9IjUwLjc1IiB3aWR0aD0iMTk4LjUiIGhlaWdodD0iNTguNSIgcng9IjMuMjUiIHN0cm9rZT0iIzNGNTJERCIgc3Ryb2tlLXdpZHRoPSIxLjUiLz4KPHBhdGggZD0iTTYyLjE2NzMgODkuMzMzM1Y4Mi4zMzMzSDY2LjgzNFY4OS4zMzMzSDcyLjY2NzNWODBINzYuMTY3M0w2NC41MDA3IDY5LjVMNTIuODM0IDgwSDU2LjMzNFY4OS4zMzMzSDYyLjE2NzNaIiBmaWxsPSIjM0Y1MkREIi8+CjxwYXRoIGQ9Ik05MC4xOTUzIDgwLjkzMTZIODYuMjFMODYuMTg4NSA3OC45NjU4SDg5LjY2ODlDOTAuMjU2MiA3OC45NjU4IDkwLjc1MzkgNzguODc5OSA5MS4xNjIxIDc4LjcwOEM5MS41Nzc1IDc4LjUyOSA5MS44OTI2IDc4LjI3NDcgOTIuMTA3NCA3Ny45NDUzQzkyLjMyMjMgNzcuNjA4NyA5Mi40Mjk3IDc3LjIwNDEgOTIuNDI5NyA3Ni43MzE0QzkyLjQyOTcgNzYuMjA4NyA5Mi4zMjk0IDc1Ljc4MjYgOTIuMTI4OSA3NS40NTMxQzkxLjkyODQgNzUuMTIzNyA5MS42MjA0IDc0Ljg4MzggOTEuMjA1MSA3NC43MzM0QzkwLjc5NjkgNzQuNTgzIDkwLjI3NDEgNzQuNTA3OCA4OS42MzY3IDc0LjUwNzhIODcuMDI2NFY4OEg4NC4zMzAxVjcyLjM1OTRIODkuNjM2N0M5MC40OTYxIDcyLjM1OTQgOTEuMjYyNCA3Mi40NDE3IDkxLjkzNTUgNzIuNjA2NEM5Mi42MTU5IDcyLjc3MTIgOTMuMTkyNCA3My4wMjkgOTMuNjY1IDczLjM3OTlDOTQuMTQ0OSA3My43MjM2IDk0LjUwNjUgNzQuMTYwNSA5NC43NSA3NC42OTA0Qzk1LjAwMDcgNzUuMjIwNCA5NS4xMjYgNzUuODUwNiA5NS4xMjYgNzYuNTgxMUM5NS4xMjYgNzcuMjI1NiA5NC45NzIgNzcuODE2NCA5NC42NjQxIDc4LjM1MzVDOTQuMzU2MSA3OC44ODM1IDkzLjkwMTQgNzkuMzE2NyA5My4yOTk4IDc5LjY1MzNDOTIuNjk4MiA3OS45ODk5IDkxLjk0OTkgODAuMTkwNCA5MS4wNTQ3IDgwLjI1NDlMOTAuMTk1MyA4MC45MzE2Wk05MC4wNzcxIDg4SDg1LjM2MTNMODYuNTc1MiA4NS44NjIzSDkwLjA3NzFDOTAuNjg1OSA4NS44NjIzIDkxLjE5NDMgODUuNzYyIDkxLjYwMjUgODUuNTYxNUM5Mi4wMTA3IDg1LjM1MzggOTIuMzE1MSA4NS4wNzEgOTIuNTE1NiA4NC43MTI5QzkyLjcyMzMgODQuMzQ3NyA5Mi44MjcxIDgzLjkyMTUgOTIuODI3MSA4My40MzQ2QzkyLjgyNzEgODIuOTI2MSA5Mi43Mzc2IDgyLjQ4NTcgOTIuNTU4NiA4Mi4xMTMzQzkyLjM3OTYgODEuNzMzNyA5Mi4wOTY3IDgxLjQ0MzcgOTEuNzEgODEuMjQzMkM5MS4zMjMyIDgxLjAzNTUgOTAuODE4NCA4MC45MzE2IDkwLjE5NTMgODAuOTMxNkg4Ny4xNjZMODcuMTg3NSA3OC45NjU4SDkxLjEyOTlMOTEuNzQyMiA3OS43MDdDOTIuNjAxNiA3OS43MzU3IDkzLjMwNyA3OS45MjU1IDkzLjg1ODQgODAuMjc2NEM5NC40MTcgODAuNjI3MyA5NC44MzI0IDgxLjA4MiA5NS4xMDQ1IDgxLjY0MDZDOTUuMzc2NiA4Mi4xOTkyIDk1LjUxMjcgODIuODAwOCA5NS41MTI3IDgzLjQ0NTNDOTUuNTEyNyA4NC40NDA4IDk1LjI5NDMgODUuMjc1MSA5NC44NTc0IDg1Ljk0ODJDOTQuNDI3NyA4Ni42MjE0IDkzLjgwODMgODcuMTMzNSA5Mi45OTkgODcuNDg0NEM5Mi4xODk4IDg3LjgyODEgOTEuMjE1OCA4OCA5MC4wNzcxIDg4Wk0xMDUuMjE2IDg1LjI2MDdWNzYuMzc3SDEwNy44MTVWODhIMTA1LjM2NkwxMDUuMjE2IDg1LjI2MDdaTTEwNS41ODEgODIuODQzOEwxMDYuNDUxIDgyLjgyMjNDMTA2LjQ1MSA4My42MDI5IDEwNi4zNjUgODQuMzIyNiAxMDYuMTkzIDg0Ljk4MTRDMTA2LjAyMSA4NS42MzMxIDEwNS43NTcgODYuMjAyNSAxMDUuMzk4IDg2LjY4OTVDMTA1LjA0IDg3LjE2OTMgMTA0LjU4MiA4Ny41NDUyIDEwNC4wMjMgODcuODE3NEMxMDMuNDY1IDg4LjA4MjQgMTAyLjc5NSA4OC4yMTQ4IDEwMi4wMTUgODguMjE0OEMxMDEuNDQ5IDg4LjIxNDggMTAwLjkzIDg4LjEzMjUgMTAwLjQ1NyA4Ny45Njc4Qzk5Ljk4NDQgODcuODAzMSA5OS41NzYyIDg3LjU0ODggOTkuMjMyNCA4Ny4yMDUxQzk4Ljg5NTggODYuODYxMyA5OC42MzQ0IDg2LjQxMzcgOTguNDQ4MiA4NS44NjIzQzk4LjI2MiA4NS4zMTA5IDk4LjE2ODkgODQuNjUyIDk4LjE2ODkgODMuODg1N1Y3Ni4zNzdIMTAwLjc1OFY4My45MDcyQzEwMC43NTggODQuMzI5OCAxMDAuODA4IDg0LjY4NDIgMTAwLjkwOCA4NC45NzA3QzEwMS4wMDggODUuMjUgMTAxLjE0NSA4NS40NzU2IDEwMS4zMTYgODUuNjQ3NUMxMDEuNDg4IDg1LjgxOTMgMTAxLjY4OSA4NS45NDExIDEwMS45MTggODYuMDEyN0MxMDIuMTQ3IDg2LjA4NDMgMTAyLjM5MSA4Ni4xMjAxIDEwMi42NDggODYuMTIwMUMxMDMuMzg2IDg2LjEyMDEgMTAzLjk2NiA4NS45NzY5IDEwNC4zODkgODUuNjkwNEMxMDQuODE4IDg1LjM5NjggMTA1LjEyMyA4NS4wMDI5IDEwNS4zMDIgODQuNTA4OEMxMDUuNDg4IDg0LjAxNDYgMTA1LjU4MSA4My40NTk2IDEwNS41ODEgODIuODQzOFpNMTE2LjA0NyA3Ni4zNzdWNzguMjY3NkgxMDkuNDk0Vjc2LjM3N0gxMTYuMDQ3Wk0xMTEuMzg1IDczLjUzMDNIMTEzLjk3NFY4NC43ODgxQzExMy45NzQgODUuMTQ2MiAxMTQuMDI0IDg1LjQyMTkgMTE0LjEyNCA4NS42MTUyQzExNC4yMzEgODUuODAxNCAxMTQuMzc4IDg1LjkyNjggMTE0LjU2NCA4NS45OTEyQzExNC43NTEgODYuMDU1NyAxMTQuOTY5IDg2LjA4NzkgMTE1LjIyIDg2LjA4NzlDMTE1LjM5OSA4Ni4wODc5IDExNS41NzEgODYuMDc3MSAxMTUuNzM1IDg2LjA1NTdDMTE1LjkgODYuMDM0MiAxMTYuMDMzIDg2LjAxMjcgMTE2LjEzMyA4NS45OTEyTDExNi4xNDQgODcuOTY3OEMxMTUuOTI5IDg4LjAzMjIgMTE1LjY3OCA4OC4wODk1IDExNS4zOTIgODguMTM5NkMxMTUuMTEyIDg4LjE4OTggMTE0Ljc5IDg4LjIxNDggMTE0LjQyNSA4OC4yMTQ4QzExMy44MyA4OC4yMTQ4IDExMy4zMDQgODguMTExIDExMi44NDYgODcuOTAzM0MxMTIuMzg3IDg3LjY4ODUgMTEyLjAyOSA4Ny4zNDExIDExMS43NzEgODYuODYxM0MxMTEuNTE0IDg2LjM4MTUgMTExLjM4NSA4NS43NDQxIDExMS4zODUgODQuOTQ5MlY3My41MzAzWk0xMjMuNjIzIDc2LjM3N1Y3OC4yNjc2SDExNy4wN1Y3Ni4zNzdIMTIzLjYyM1pNMTE4Ljk2MSA3My41MzAzSDEyMS41NVY4NC43ODgxQzEyMS41NSA4NS4xNDYyIDEyMS42IDg1LjQyMTkgMTIxLjcgODUuNjE1MkMxMjEuODA4IDg1LjgwMTQgMTIxLjk1NCA4NS45MjY4IDEyMi4xNDEgODUuOTkxMkMxMjIuMzI3IDg2LjA1NTcgMTIyLjU0NSA4Ni4wODc5IDEyMi43OTYgODYuMDg3OUMxMjIuOTc1IDg2LjA4NzkgMTIzLjE0NyA4Ni4wNzcxIDEyMy4zMTIgODYuMDU1N0MxMjMuNDc2IDg2LjAzNDIgMTIzLjYwOSA4Ni4wMTI3IDEyMy43MDkgODUuOTkxMkwxMjMuNzIgODcuOTY3OEMxMjMuNTA1IDg4LjAzMjIgMTIzLjI1NCA4OC4wODk1IDEyMi45NjggODguMTM5NkMxMjIuNjg4IDg4LjE4OTggMTIyLjM2NiA4OC4yMTQ4IDEyMi4wMDEgODguMjE0OEMxMjEuNDA3IDg4LjIxNDggMTIwLjg4IDg4LjExMSAxMjAuNDIyIDg3LjkwMzNDMTE5Ljk2NCA4Ny42ODg1IDExOS42MDUgODcuMzQxMSAxMTkuMzQ4IDg2Ljg2MTNDMTE5LjA5IDg2LjM4MTUgMTE4Ljk2MSA4NS43NDQxIDExOC45NjEgODQuOTQ5MlY3My41MzAzWk0xMjUuMTE5IDgyLjMxNzRWODIuMDcwM0MxMjUuMTE5IDgxLjIzMjQgMTI1LjI0MSA4MC40NTU0IDEyNS40ODQgNzkuNzM5M0MxMjUuNzI4IDc5LjAxNiAxMjYuMDc5IDc4LjM4OTMgMTI2LjUzNyA3Ny44NTk0QzEyNy4wMDMgNzcuMzIyMyAxMjcuNTY4IDc2LjkwNjkgMTI4LjIzNCA3Ni42MTMzQzEyOC45MDggNzYuMzEyNSAxMjkuNjY3IDc2LjE2MjEgMTMwLjUxMiA3Ni4xNjIxQzEzMS4zNjQgNzYuMTYyMSAxMzIuMTIzIDc2LjMxMjUgMTMyLjc4OSA3Ni42MTMzQzEzMy40NjIgNzYuOTA2OSAxMzQuMDMyIDc3LjMyMjMgMTM0LjQ5NyA3Ny44NTk0QzEzNC45NjMgNzguMzg5MyAxMzUuMzE3IDc5LjAxNiAxMzUuNTYxIDc5LjczOTNDMTM1LjgwNCA4MC40NTU0IDEzNS45MjYgODEuMjMyNCAxMzUuOTI2IDgyLjA3MDNWODIuMzE3NEMxMzUuOTI2IDgzLjE1NTMgMTM1LjgwNCA4My45MzIzIDEzNS41NjEgODQuNjQ4NEMxMzUuMzE3IDg1LjM2NDYgMTM0Ljk2MyA4NS45OTEyIDEzNC40OTcgODYuNTI4M0MxMzQuMDMyIDg3LjA1ODMgMTMzLjQ2NiA4Ny40NzM2IDEzMi44IDg3Ljc3NDRDMTMyLjEzNCA4OC4wNjggMTMxLjM3OCA4OC4yMTQ4IDEzMC41MzMgODguMjE0OEMxMjkuNjgxIDg4LjIxNDggMTI4LjkxOCA4OC4wNjggMTI4LjI0NSA4Ny43NzQ0QzEyNy41NzkgODcuNDczNiAxMjcuMDEzIDg3LjA1ODMgMTI2LjU0OCA4Ni41MjgzQzEyNi4wODIgODUuOTkxMiAxMjUuNzI4IDg1LjM2NDYgMTI1LjQ4NCA4NC42NDg0QzEyNS4yNDEgODMuOTMyMyAxMjUuMTE5IDgzLjE1NTMgMTI1LjExOSA4Mi4zMTc0Wk0xMjcuNzA4IDgyLjA3MDNWODIuMzE3NEMxMjcuNzA4IDgyLjg0MDIgMTI3Ljc2MiA4My4zMzQzIDEyNy44NjkgODMuNzk5OEMxMjcuOTc3IDg0LjI2NTMgMTI4LjE0NSA4NC42NzM1IDEyOC4zNzQgODUuMDI0NEMxMjguNjAzIDg1LjM3NTMgMTI4Ljg5NyA4NS42NTEgMTI5LjI1NSA4NS44NTE2QzEyOS42MTMgODYuMDUyMSAxMzAuMDM5IDg2LjE1MjMgMTMwLjUzMyA4Ni4xNTIzQzEzMS4wMTMgODYuMTUyMyAxMzEuNDI4IDg2LjA1MjEgMTMxLjc3OSA4NS44NTE2QzEzMi4xMzcgODUuNjUxIDEzMi40MzEgODUuMzc1MyAxMzIuNjYgODUuMDI0NEMxMzIuODg5IDg0LjY3MzUgMTMzLjA1OCA4NC4yNjUzIDEzMy4xNjUgODMuNzk5OEMxMzMuMjggODMuMzM0MyAxMzMuMzM3IDgyLjg0MDIgMTMzLjMzNyA4Mi4zMTc0VjgyLjA3MDNDMTMzLjMzNyA4MS41NTQ3IDEzMy4yOCA4MS4wNjc3IDEzMy4xNjUgODAuNjA5NEMxMzMuMDU4IDgwLjE0MzkgMTMyLjg4NiA3OS43MzIxIDEzMi42NDkgNzkuMzc0QzEzMi40MiA3OS4wMTYgMTMyLjEyNyA3OC43MzY3IDEzMS43NjkgNzguNTM2MUMxMzEuNDE4IDc4LjMyODUgMTMwLjk5OSA3OC4yMjQ2IDEzMC41MTIgNzguMjI0NkMxMzAuMDI1IDc4LjIyNDYgMTI5LjYwMiA3OC4zMjg1IDEyOS4yNDQgNzguNTM2MUMxMjguODkzIDc4LjczNjcgMTI4LjYwMyA3OS4wMTYgMTI4LjM3NCA3OS4zNzRDMTI4LjE0NSA3OS43MzIxIDEyNy45NzcgODAuMTQzOSAxMjcuODY5IDgwLjYwOTRDMTI3Ljc2MiA4MS4wNjc3IDEyNy43MDggODEuNTU0NyAxMjcuNzA4IDgyLjA3MDNaTTE0MC45MTMgNzguODU4NFY4OEgxMzguMzI0Vjc2LjM3N0gxNDAuNzYzTDE0MC45MTMgNzguODU4NFpNMTQwLjQ1MSA4MS43NTg4TDEzOS42MTMgODEuNzQ4QzEzOS42MiA4MC45MjQ1IDEzOS43MzUgODAuMTY4OSAxMzkuOTU3IDc5LjQ4MTRDMTQwLjE4NiA3OC43OTM5IDE0MC41MDEgNzguMjAzMSAxNDAuOTAyIDc3LjcwOUMxNDEuMzExIDc3LjIxNDggMTQxLjc5OCA3Ni44MzUzIDE0Mi4zNjMgNzYuNTcwM0MxNDIuOTI5IDc2LjI5ODIgMTQzLjU1OSA3Ni4xNjIxIDE0NC4yNTQgNzYuMTYyMUMxNDQuODEyIDc2LjE2MjEgMTQ1LjMxNyA3Ni4yNDA5IDE0NS43NjkgNzYuMzk4NEMxNDYuMjI3IDc2LjU0ODggMTQ2LjYxNyA3Ni43OTU5IDE0Ni45MzkgNzcuMTM5NkMxNDcuMjY5IDc3LjQ4MzQgMTQ3LjUyIDc3LjkzMSAxNDcuNjkxIDc4LjQ4MjRDMTQ3Ljg2MyA3OS4wMjY3IDE0Ny45NDkgNzkuNjk2MyAxNDcuOTQ5IDgwLjQ5MTJWODhIMTQ1LjM1VjgwLjQ4MDVDMTQ1LjM1IDc5LjkyMTkgMTQ1LjI2NyA3OS40ODE0IDE0NS4xMDMgNzkuMTU5MkMxNDQuOTQ1IDc4LjgyOTggMTQ0LjcxMiA3OC41OTcgMTQ0LjQwNCA3OC40NjA5QzE0NC4xMDQgNzguMzE3NyAxNDMuNzI4IDc4LjI0NjEgMTQzLjI3NiA3OC4yNDYxQzE0Mi44MzIgNzguMjQ2MSAxNDIuNDM1IDc4LjMzOTIgMTQyLjA4NCA3OC41MjU0QzE0MS43MzMgNzguNzExNiAxNDEuNDM2IDc4Ljk2NTggMTQxLjE5MiA3OS4yODgxQzE0MC45NTYgNzkuNjEwNCAxNDAuNzczIDc5Ljk4MjcgMTQwLjY0NSA4MC40MDUzQzE0MC41MTYgODAuODI3OCAxNDAuNDUxIDgxLjI3OSAxNDAuNDUxIDgxLjc1ODhaIiBmaWxsPSIjM0Y1MkREIi8+Cjwvc3ZnPgo=", - "description": "Action button.", + "description": "Facilitates single-click navigation to other dashboards, states, or custom actions. Configurable settings allow for on-click action definition and conditions for button activation or deactivation. It offers various layouts and custom styling options for different states.", "descriptor": { "type": "latest", "sizeX": 3, @@ -22,6 +22,8 @@ "tags": [ "button", "action", - "navigation" + "navigation", + "navigate", + "dashboard state" ] } \ No newline at end of file diff --git a/application/src/main/data/json/system/widget_types/command_button.json b/application/src/main/data/json/system/widget_types/command_button.json index 1ffd2326a8..dcfeb108f2 100644 --- a/application/src/main/data/json/system/widget_types/command_button.json +++ b/application/src/main/data/json/system/widget_types/command_button.json @@ -3,7 +3,7 @@ "name": "Command button", "deprecated": false, "image": "tb-image:Y29tbWFuZC1idXR0b24uc3Zn:IkNvbW1hbmQgYnV0dG9uIiBzeXN0ZW0gd2lkZ2V0IGltYWdl;data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAwIiBoZWlnaHQ9IjE2MCIgdmlld0JveD0iMCAwIDIwMCAxNjAiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHg9IjAuNzUiIHk9IjUwLjc1IiB3aWR0aD0iMTk4LjUiIGhlaWdodD0iNTguNSIgcng9IjMuMjUiIGZpbGw9IndoaXRlIi8+CjxyZWN0IHg9IjAuNzUiIHk9IjUwLjc1IiB3aWR0aD0iMTk4LjUiIGhlaWdodD0iNTguNSIgcng9IjMuMjUiIHN0cm9rZT0iIzNGNTJERCIgc3Ryb2tlLXdpZHRoPSIxLjUiLz4KPHBhdGggZD0iTTY1LjQ5OTcgNzNWNzUuMzMzM0g3NS41MjEzTDY0LjMzMyA4Ni41MjE3TDY1Ljk3OCA4OC4xNjY3TDc3LjE2NjMgNzYuOTc4M1Y4N0g3OS40OTk3VjczSDY1LjQ5OTdaIiBmaWxsPSIjM0Y1MkREIi8+CjxwYXRoIGQ9Ik0xMDAuNTY0IDgzLjk3MTdDMTAwLjU2NCA4My42NDk0IDEwMC41MTQgODMuMzYzIDEwMC40MTQgODMuMTEyM0MxMDAuMzIxIDgyLjg2MTcgMTAwLjE1MyA4Mi42MzI1IDk5LjkwOTIgODIuNDI0OEM5OS42NjU3IDgyLjIxNzEgOTkuMzIxOSA4Mi4wMTY2IDk4Ljg3NzkgODEuODIzMkM5OC40NDExIDgxLjYyMjcgOTcuODgyNSA4MS40MTg2IDk3LjIwMjEgODEuMjEwOUM5Ni40NTc0IDgwLjk4MTggOTUuNzY5OSA4MC43Mjc1IDk1LjEzOTYgODAuNDQ4MkM5NC41MTY2IDgwLjE2MTggOTMuOTcyMyA3OS44MzI0IDkzLjUwNjggNzkuNDZDOTMuMDQxMyA3OS4wODA0IDkyLjY3OTcgNzguNjQ3MSA5Mi40MjE5IDc4LjE2MDJDOTIuMTY0MSA3Ny42NjYgOTIuMDM1MiA3Ny4wOTY3IDkyLjAzNTIgNzYuNDUyMUM5Mi4wMzUyIDc1LjgxNDggOTIuMTY3NiA3NS4yMzQ3IDkyLjQzMjYgNzQuNzExOUM5Mi43MDQ4IDc0LjE4OTEgOTMuMDg3OSA3My43MzggOTMuNTgyIDczLjM1ODRDOTQuMDgzMyA3Mi45NzE3IDk0LjY3NDIgNzIuNjc0NSA5NS4zNTQ1IDcyLjQ2NjhDOTYuMDM0OCA3Mi4yNTIgOTYuNzg2OCA3Mi4xNDQ1IDk3LjYxMDQgNzIuMTQ0NUM5OC43NzA1IDcyLjE0NDUgOTkuNzY5NSA3Mi4zNTk0IDEwMC42MDcgNzIuNzg5MUMxMDEuNDUyIDczLjIxODggMTAyLjEwMSA3My43OTUyIDEwMi41NTIgNzQuNTE4NkMxMDMuMDEgNzUuMjQxOSAxMDMuMjM5IDc2LjA0MDQgMTAzLjIzOSA3Ni45MTQxSDEwMC41NjRDMTAwLjU2NCA3Ni4zOTg0IDEwMC40NTMgNzUuOTQzNyAxMDAuMjMxIDc1LjU0OThDMTAwLjAxNyA3NS4xNDg4IDk5LjY4NzIgNzQuODMzNyA5OS4yNDMyIDc0LjYwNDVDOTguODA2MyA3NC4zNzUzIDk4LjI1MTMgNzQuMjYwNyA5Ny41NzgxIDc0LjI2MDdDOTYuOTQwOCA3NC4yNjA3IDk2LjQxMDggNzQuMzU3NCA5NS45ODgzIDc0LjU1MDhDOTUuNTY1OCA3NC43NDQxIDk1LjI1MDcgNzUuMDA1NSA5NS4wNDMgNzUuMzM1Qzk0LjgzNTMgNzUuNjY0NCA5NC43MzE0IDc2LjAzNjggOTQuNzMxNCA3Ni40NTIxQzk0LjczMTQgNzYuNzQ1OCA5NC43OTk1IDc3LjAxNDMgOTQuOTM1NSA3Ny4yNTc4Qzk1LjA3MTYgNzcuNDk0MSA5NS4yNzkzIDc3LjcxNjEgOTUuNTU4NiA3Ny45MjM4Qzk1LjgzNzkgNzguMTI0MyA5Ni4xODg4IDc4LjMxNDEgOTYuNjExMyA3OC40OTMyQzk3LjAzMzkgNzguNjcyMiA5Ny41MzE2IDc4Ljg0NDEgOTguMTA0NSA3OS4wMDg4Qzk4Ljk3MSA3OS4yNjY2IDk5LjcyNjYgNzkuNTUzMSAxMDAuMzcxIDc5Ljg2ODJDMTAxLjAxNiA4MC4xNzYxIDEwMS41NTMgODAuNTI3IDEwMS45ODIgODAuOTIwOUMxMDIuNDEyIDgxLjMxNDggMTAyLjczNCA4MS43NjI0IDEwMi45NDkgODIuMjYzN0MxMDMuMTY0IDgyLjc1NzggMTAzLjI3MSA4My4zMiAxMDMuMjcxIDgzLjk1MDJDMTAzLjI3MSA4NC42MDkgMTAzLjEzOSA4NS4yMDM1IDEwMi44NzQgODUuNzMzNEMxMDIuNjA5IDg2LjI1NjIgMTAyLjIyOSA4Ni43MDM4IDEwMS43MzUgODcuMDc2MkMxMDEuMjQ4IDg3LjQ0MTQgMTAwLjY2MSA4Ny43MjQzIDk5Ljk3MzYgODcuOTI0OEM5OS4yOTMzIDg4LjExODIgOTguNTM0MiA4OC4yMTQ4IDk3LjY5NjMgODguMjE0OEM5Ni45NDQzIDg4LjIxNDggOTYuMjAzMSA4OC4xMTQ2IDk1LjQ3MjcgODcuOTE0MUM5NC43NDkzIDg3LjcxMzUgOTQuMDkwNSA4Ny40MDkyIDkzLjQ5NjEgODcuMDAxQzkyLjkwMTcgODYuNTg1NiA5Mi40MjkgODYuMDcgOTIuMDc4MSA4NS40NTQxQzkxLjcyNzIgODQuODMxMSA5MS41NTE4IDg0LjEwNDIgOTEuNTUxOCA4My4yNzM0SDk0LjI0OEM5NC4yNDggODMuNzgxOSA5NC4zMzQgODQuMjE1MiA5NC41MDU5IDg0LjU3MzJDOTQuNjg0OSA4NC45MzEzIDk0LjkzMiA4NS4yMjQ5IDk1LjI0NzEgODUuNDU0MUM5NS41NjIyIDg1LjY3NjEgOTUuOTI3NCA4NS44NDA4IDk2LjM0MjggODUuOTQ4MkM5Ni43NjUzIDg2LjA1NTcgOTcuMjE2NSA4Ni4xMDk0IDk3LjY5NjMgODYuMTA5NEM5OC4zMjY1IDg2LjEwOTQgOTguODUyOSA4Ni4wMTk5IDk5LjI3NTQgODUuODQwOEM5OS43MDUxIDg1LjY2MTggMTAwLjAyNyA4NS40MTExIDEwMC4yNDIgODUuMDg4OUMxMDAuNDU3IDg0Ljc2NjYgMTAwLjU2NCA4NC4zOTQyIDEwMC41NjQgODMuOTcxN1pNMTEwLjc3MiA4OC4yMTQ4QzEwOS45MTMgODguMjE0OCAxMDkuMTM2IDg4LjA3NTIgMTA4LjQ0MSA4Ny43OTU5QzEwNy43NTQgODcuNTA5NCAxMDcuMTY3IDg3LjExMiAxMDYuNjggODYuNjAzNUMxMDYuMiA4Ni4wOTUxIDEwNS44MzEgODUuNDk3MSAxMDUuNTczIDg0LjgwOTZDMTA1LjMxNSA4NC4xMjIxIDEwNS4xODcgODMuMzgwOSAxMDUuMTg3IDgyLjU4NTlWODIuMTU2MkMxMDUuMTg3IDgxLjI0NjcgMTA1LjMxOSA4MC40MjMyIDEwNS41ODQgNzkuNjg1NUMxMDUuODQ5IDc4Ljk0NzkgMTA2LjIxOCA3OC4zMTc3IDEwNi42OSA3Ny43OTQ5QzEwNy4xNjMgNzcuMjY1IDEwNy43MjIgNzYuODYwNCAxMDguMzY2IDc2LjU4MTFDMTA5LjAxMSA3Ni4zMDE4IDEwOS43MDkgNzYuMTYyMSAxMTAuNDYxIDc2LjE2MjFDMTExLjI5MiA3Ni4xNjIxIDExMi4wMTkgNzYuMzAxOCAxMTIuNjQyIDc2LjU4MTFDMTEzLjI2NSA3Ni44NjA0IDExMy43OCA3Ny4yNTQyIDExNC4xODggNzcuNzYyN0MxMTQuNjA0IDc4LjI2NCAxMTQuOTEyIDc4Ljg2MiAxMTUuMTEyIDc5LjU1NjZDMTE1LjMyIDgwLjI1MTMgMTE1LjQyNCA4MS4wMTc2IDExNS40MjQgODEuODU1NVY4Mi45NjE5SDEwNi40NDNWODEuMTAzNUgxMTIuODY3VjgwLjg5OTRDMTEyLjg1MyA4MC40MzM5IDExMi43NiA3OS45OTcxIDExMi41ODggNzkuNTg4OUMxMTIuNDIzIDc5LjE4MDcgMTEyLjE2OSA3OC44NTEyIDExMS44MjUgNzguNjAwNkMxMTEuNDgxIDc4LjM0OTkgMTExLjAyMyA3OC4yMjQ2IDExMC40NSA3OC4yMjQ2QzExMC4wMjEgNzguMjI0NiAxMDkuNjM3IDc4LjMxNzcgMTA5LjMwMSA3OC41MDM5QzEwOC45NzEgNzguNjgyOSAxMDguNjk2IDc4Ljk0NDMgMTA4LjQ3NCA3OS4yODgxQzEwOC4yNTIgNzkuNjMxOCAxMDguMDggODAuMDQ3MiAxMDcuOTU4IDgwLjUzNDJDMTA3Ljg0MyA4MS4wMTQgMTA3Ljc4NiA4MS41NTQ3IDEwNy43ODYgODIuMTU2MlY4Mi41ODU5QzEwNy43ODYgODMuMDk0NCAxMDcuODU0IDgzLjU2NzEgMTA3Ljk5IDg0LjAwMzlDMTA4LjEzMyA4NC40MzM2IDEwOC4zNDEgODQuODA5NiAxMDguNjEzIDg1LjEzMThDMTA4Ljg4NSA4NS40NTQxIDEwOS4yMTUgODUuNzA4MyAxMDkuNjAyIDg1Ljg5NDVDMTA5Ljk4OCA4Ni4wNzM2IDExMC40MjkgODYuMTYzMSAxMTAuOTIzIDg2LjE2MzFDMTExLjU0NiA4Ni4xNjMxIDExMi4xMDEgODYuMDM3OCAxMTIuNTg4IDg1Ljc4NzFDMTEzLjA3NSA4NS41MzY1IDExMy40OTcgODUuMTgyIDExMy44NTUgODQuNzIzNkwxMTUuMjIgODYuMDQ0OUMxMTQuOTY5IDg2LjQxMDIgMTE0LjY0MyA4Ni43NjExIDExNC4yNDIgODcuMDk3N0MxMTMuODQxIDg3LjQyNzEgMTEzLjM1MSA4Ny42OTU2IDExMi43NzEgODcuOTAzM0MxMTIuMTk4IDg4LjExMSAxMTEuNTMyIDg4LjIxNDggMTEwLjc3MiA4OC4yMTQ4Wk0xMjAuMjYxIDc4Ljg1ODRWODhIMTE3LjY3MlY3Ni4zNzdIMTIwLjExTDEyMC4yNjEgNzguODU4NFpNMTE5Ljc5OSA4MS43NTg4TDExOC45NjEgODEuNzQ4QzExOC45NjggODAuOTI0NSAxMTkuMDgzIDgwLjE2ODkgMTE5LjMwNSA3OS40ODE0QzExOS41MzQgNzguNzkzOSAxMTkuODQ5IDc4LjIwMzEgMTIwLjI1IDc3LjcwOUMxMjAuNjU4IDc3LjIxNDggMTIxLjE0NSA3Ni44MzUzIDEyMS43MTEgNzYuNTcwM0MxMjIuMjc3IDc2LjI5ODIgMTIyLjkwNyA3Ni4xNjIxIDEyMy42MDIgNzYuMTYyMUMxMjQuMTYgNzYuMTYyMSAxMjQuNjY1IDc2LjI0MDkgMTI1LjExNiA3Ni4zOTg0QzEyNS41NzUgNzYuNTQ4OCAxMjUuOTY1IDc2Ljc5NTkgMTI2LjI4NyA3Ny4xMzk2QzEyNi42MTcgNzcuNDgzNCAxMjYuODY3IDc3LjkzMSAxMjcuMDM5IDc4LjQ4MjRDMTI3LjIxMSA3OS4wMjY3IDEyNy4yOTcgNzkuNjk2MyAxMjcuMjk3IDgwLjQ5MTJWODhIMTI0LjY5N1Y4MC40ODA1QzEyNC42OTcgNzkuOTIxOSAxMjQuNjE1IDc5LjQ4MTQgMTI0LjQ1IDc5LjE1OTJDMTI0LjI5MyA3OC44Mjk4IDEyNC4wNiA3OC41OTcgMTIzLjc1MiA3OC40NjA5QzEyMy40NTEgNzguMzE3NyAxMjMuMDc1IDc4LjI0NjEgMTIyLjYyNCA3OC4yNDYxQzEyMi4xOCA3OC4yNDYxIDEyMS43ODMgNzguMzM5MiAxMjEuNDMyIDc4LjUyNTRDMTIxLjA4MSA3OC43MTE2IDEyMC43ODQgNzguOTY1OCAxMjAuNTQgNzkuMjg4MUMxMjAuMzA0IDc5LjYxMDQgMTIwLjEyMSA3OS45ODI3IDExOS45OTIgODAuNDA1M0MxMTkuODYzIDgwLjgyNzggMTE5Ljc5OSA4MS4yNzkgMTE5Ljc5OSA4MS43NTg4Wk0xMzcuMjc5IDg1LjU5MzhWNzEuNUgxMzkuODc5Vjg4SDEzNy41MjZMMTM3LjI3OSA4NS41OTM4Wk0xMjkuNzE3IDgyLjMxNzRWODIuMDkxOEMxMjkuNzE3IDgxLjIxMDkgMTI5LjgyMSA4MC40MDg5IDEzMC4wMjggNzkuNjg1NUMxMzAuMjM2IDc4Ljk1NTEgMTMwLjUzNyA3OC4zMjg1IDEzMC45MzEgNzcuODA1N0MxMzEuMzI1IDc3LjI3NTcgMTMxLjgwNCA3Ni44NzExIDEzMi4zNyA3Ni41OTE4QzEzMi45MzYgNzYuMzA1MyAxMzMuNTczIDc2LjE2MjEgMTM0LjI4MiA3Ni4xNjIxQzEzNC45ODQgNzYuMTYyMSAxMzUuNiA3Ni4yOTgyIDEzNi4xMyA3Ni41NzAzQzEzNi42NiA3Ni44NDI0IDEzNy4xMTEgNzcuMjMyNyAxMzcuNDgzIDc3Ljc0MTJDMTM3Ljg1NiA3OC4yNDI1IDEzOC4xNTMgNzguODQ0MSAxMzguMzc1IDc5LjU0NTlDMTM4LjU5NyA4MC4yNDA2IDEzOC43NTUgODEuMDE0IDEzOC44NDggODEuODY2MlY4Mi41ODU5QzEzOC43NTUgODMuNDE2NyAxMzguNTk3IDg0LjE3NTggMTM4LjM3NSA4NC44NjMzQzEzOC4xNTMgODUuNTUwOCAxMzcuODU2IDg2LjE0NTIgMTM3LjQ4MyA4Ni42NDY1QzEzNy4xMTEgODcuMTQ3OCAxMzYuNjU2IDg3LjUzNDUgMTM2LjExOSA4Ny44MDY2QzEzNS41ODkgODguMDc4OCAxMzQuOTcgODguMjE0OCAxMzQuMjYxIDg4LjIxNDhDMTMzLjU1OSA4OC4yMTQ4IDEzMi45MjUgODguMDY4IDEzMi4zNTkgODcuNzc0NEMxMzEuODAxIDg3LjQ4MDggMTMxLjMyNSA4Ny4wNjkgMTMwLjkzMSA4Ni41MzkxQzEzMC41MzcgODYuMDA5MSAxMzAuMjM2IDg1LjM4NjEgMTMwLjAyOCA4NC42Njk5QzEyOS44MjEgODMuOTQ2NiAxMjkuNzE3IDgzLjE2MjQgMTI5LjcxNyA4Mi4zMTc0Wk0xMzIuMzA2IDgyLjA5MThWODIuMzE3NEMxMzIuMzA2IDgyLjg0NzMgMTMyLjM1MiA4My4zNDE1IDEzMi40NDUgODMuNzk5OEMxMzIuNTQ2IDg0LjI1ODEgMTMyLjcgODQuNjYyOCAxMzIuOTA3IDg1LjAxMzdDMTMzLjExNSA4NS4zNTc0IDEzMy4zODMgODUuNjI5NiAxMzMuNzEzIDg1LjgzMDFDMTM0LjA0OSA4Ni4wMjM0IDEzNC40NTEgODYuMTIwMSAxMzQuOTE2IDg2LjEyMDFDMTM1LjUwMyA4Ni4xMjAxIDEzNS45ODcgODUuOTkxMiAxMzYuMzY2IDg1LjczMzRDMTM2Ljc0NiA4NS40NzU2IDEzNy4wNDMgODUuMTI4MyAxMzcuMjU4IDg0LjY5MTRDMTM3LjQ4IDg0LjI0NzQgMTM3LjYzIDgzLjc1MzMgMTM3LjcwOSA4My4yMDlWODEuMjY0NkMxMzcuNjY2IDgwLjg0MjEgMTM3LjU3NiA4MC40NDgyIDEzNy40NCA4MC4wODNDMTM3LjMxMiA3OS43MTc4IDEzNy4xMzYgNzkuMzk5MSAxMzYuOTE0IDc5LjEyN0MxMzYuNjkyIDc4Ljg0NzcgMTM2LjQxNiA3OC42MzI4IDEzNi4wODcgNzguNDgyNEMxMzUuNzY1IDc4LjMyNDkgMTM1LjM4MiA3OC4yNDYxIDEzNC45MzggNzguMjQ2MUMxMzQuNDY1IDc4LjI0NjEgMTM0LjA2NCA3OC4zNDY0IDEzMy43MzQgNzguNTQ2OUMxMzMuNDA1IDc4Ljc0NzQgMTMzLjEzMyA3OS4wMjMxIDEzMi45MTggNzkuMzc0QzEzMi43MSA3OS43MjQ5IDEzMi41NTYgODAuMTMzMSAxMzIuNDU2IDgwLjU5ODZDMTMyLjM1NiA4MS4wNjQxIDEzMi4zMDYgODEuNTYxOCAxMzIuMzA2IDgyLjA5MThaIiBmaWxsPSIjM0Y1MkREIi8+Cjwvc3ZnPgo=", - "description": "Sends the command to the device or updates attribute/time-series when the user clicks the button. Widget settings will enable you to configure behavior how to fetch the initial state and what to trigger when click.", + "description": "Allows single-click commands to devices or updates to attributes/time-series. Settings enable definition of the on-click action and condition when the button is disabled. Supports multiple layouts and custom styles for different states.", "descriptor": { "type": "rpc", "sizeX": 3, @@ -31,6 +31,9 @@ "subroutine call", "inter-process communication", "server request", - "button" + "button", + "update attribute", + "set attribute", + "add time-series" ] } \ No newline at end of file diff --git a/application/src/main/data/json/system/widget_types/single_switch.json b/application/src/main/data/json/system/widget_types/single_switch.json index b14cf633a2..8faea8ba93 100644 --- a/application/src/main/data/json/system/widget_types/single_switch.json +++ b/application/src/main/data/json/system/widget_types/single_switch.json @@ -3,7 +3,7 @@ "name": "Single Switch", "deprecated": false, "image": "tb-image:c2luZ2xlLXN3aXRjaC5zdmc=:IlNpbmdsZSBTd2l0Y2giIHN5c3RlbSB3aWRnZXQgaW1hZ2U=;data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAwIiBoZWlnaHQ9IjE2MCIgdmlld0JveD0iMCAwIDIwMCAxNjAiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIyMDAiIGhlaWdodD0iMTYwIiByeD0iNCIgZmlsbD0id2hpdGUiLz4KPHJlY3QgeD0iMzEuNTc3MSIgeT0iNjUuMDc0MiIgd2lkdGg9IjU2Ljk5MDEiIGhlaWdodD0iMjkuODUyIiByeD0iMTQuOTI2IiBmaWxsPSIjNTQ2OUZGIi8+CjxjaXJjbGUgY3g9IjczLjY0MDkiIGN5PSI4MC4wMDAzIiByPSIxMi4yMTIyIiBmaWxsPSJ3aGl0ZSIvPgo8cGF0aCBkPSJNMTA5LjI0MSA4My40NzE3QzEwOS4yNDEgODMuMTQ5NCAxMDkuMTkxIDgyLjg2MyAxMDkuMDkxIDgyLjYxMjNDMTA4Ljk5OCA4Mi4zNjE3IDEwOC44MjkgODIuMTMyNSAxMDguNTg2IDgxLjkyNDhDMTA4LjM0MiA4MS43MTcxIDEwNy45OTkgODEuNTE2NiAxMDcuNTU1IDgxLjMyMzJDMTA3LjExOCA4MS4xMjI3IDEwNi41NTkgODAuOTE4NiAxMDUuODc5IDgwLjcxMDlDMTA1LjEzNCA4MC40ODE4IDEwNC40NDcgODAuMjI3NSAxMDMuODE2IDc5Ljk0ODJDMTAzLjE5MyA3OS42NjE4IDEwMi42NDkgNzkuMzMyNCAxMDIuMTg0IDc4Ljk2QzEwMS43MTggNzguNTgwNCAxMDEuMzU2IDc4LjE0NzEgMTAxLjA5OSA3Ny42NjAyQzEwMC44NDEgNzcuMTY2IDEwMC43MTIgNzYuNTk2NyAxMDAuNzEyIDc1Ljk1MjFDMTAwLjcxMiA3NS4zMTQ4IDEwMC44NDQgNzQuNzM0NyAxMDEuMTA5IDc0LjIxMTlDMTAxLjM4MiA3My42ODkxIDEwMS43NjUgNzMuMjM4IDEwMi4yNTkgNzIuODU4NEMxMDIuNzYgNzIuNDcxNyAxMDMuMzUxIDcyLjE3NDUgMTA0LjAzMSA3MS45NjY4QzEwNC43MTIgNzEuNzUyIDEwNS40NjQgNzEuNjQ0NSAxMDYuMjg3IDcxLjY0NDVDMTA3LjQ0NyA3MS42NDQ1IDEwOC40NDYgNzEuODU5NCAxMDkuMjg0IDcyLjI4OTFDMTEwLjEyOSA3Mi43MTg4IDExMC43NzcgNzMuMjk1MiAxMTEuMjI5IDc0LjAxODZDMTExLjY4NyA3NC43NDE5IDExMS45MTYgNzUuNTQwNCAxMTEuOTE2IDc2LjQxNDFIMTA5LjI0MUMxMDkuMjQxIDc1Ljg5ODQgMTA5LjEzIDc1LjQ0MzcgMTA4LjkwOCA3NS4wNDk4QzEwOC42OTMgNzQuNjQ4OCAxMDguMzY0IDc0LjMzMzcgMTA3LjkyIDc0LjEwNDVDMTA3LjQ4MyA3My44NzUzIDEwNi45MjggNzMuNzYwNyAxMDYuMjU1IDczLjc2MDdDMTA1LjYxOCA3My43NjA3IDEwNS4wODggNzMuODU3NCAxMDQuNjY1IDc0LjA1MDhDMTA0LjI0MyA3NC4yNDQxIDEwMy45MjcgNzQuNTA1NSAxMDMuNzIgNzQuODM1QzEwMy41MTIgNzUuMTY0NCAxMDMuNDA4IDc1LjUzNjggMTAzLjQwOCA3NS45NTIxQzEwMy40MDggNzYuMjQ1OCAxMDMuNDc2IDc2LjUxNDMgMTAzLjYxMiA3Ni43NTc4QzEwMy43NDggNzYuOTk0MSAxMDMuOTU2IDc3LjIxNjEgMTA0LjIzNSA3Ny40MjM4QzEwNC41MTUgNzcuNjI0MyAxMDQuODY2IDc3LjgxNDEgMTA1LjI4OCA3Ny45OTMyQzEwNS43MTEgNzguMTcyMiAxMDYuMjA4IDc4LjM0NDEgMTA2Ljc4MSA3OC41MDg4QzEwNy42NDggNzguNzY2NiAxMDguNDAzIDc5LjA1MzEgMTA5LjA0OCA3OS4zNjgyQzEwOS42OTIgNzkuNjc2MSAxMTAuMjI5IDgwLjAyNyAxMTAuNjU5IDgwLjQyMDlDMTExLjA4OSA4MC44MTQ4IDExMS40MTEgODEuMjYyNCAxMTEuNjI2IDgxLjc2MzdDMTExLjg0MSA4Mi4yNTc4IDExMS45NDggODIuODIgMTExLjk0OCA4My40NTAyQzExMS45NDggODQuMTA5IDExMS44MTYgODQuNzAzNSAxMTEuNTUxIDg1LjIzMzRDMTExLjI4NiA4NS43NTYyIDExMC45MDYgODYuMjAzOCAxMTAuNDEyIDg2LjU3NjJDMTA5LjkyNSA4Ni45NDE0IDEwOS4zMzggODcuMjI0MyAxMDguNjUgODcuNDI0OEMxMDcuOTcgODcuNjE4MiAxMDcuMjExIDg3LjcxNDggMTA2LjM3MyA4Ny43MTQ4QzEwNS42MjEgODcuNzE0OCAxMDQuODggODcuNjE0NiAxMDQuMTQ5IDg3LjQxNDFDMTAzLjQyNiA4Ny4yMTM1IDEwMi43NjcgODYuOTA5MiAxMDIuMTczIDg2LjUwMUMxMDEuNTc4IDg2LjA4NTYgMTAxLjEwNiA4NS41NyAxMDAuNzU1IDg0Ljk1NDFDMTAwLjQwNCA4NC4zMzExIDEwMC4yMjkgODMuNjA0MiAxMDAuMjI5IDgyLjc3MzRIMTAyLjkyNUMxMDIuOTI1IDgzLjI4MTkgMTAzLjAxMSA4My43MTUyIDEwMy4xODMgODQuMDczMkMxMDMuMzYyIDg0LjQzMTMgMTAzLjYwOSA4NC43MjQ5IDEwMy45MjQgODQuOTU0MUMxMDQuMjM5IDg1LjE3NjEgMTA0LjYwNCA4NS4zNDA4IDEwNS4wMiA4NS40NDgyQzEwNS40NDIgODUuNTU1NyAxMDUuODkzIDg1LjYwOTQgMTA2LjM3MyA4NS42MDk0QzEwNy4wMDMgODUuNjA5NCAxMDcuNTMgODUuNTE5OSAxMDcuOTUyIDg1LjM0MDhDMTA4LjM4MiA4NS4xNjE4IDEwOC43MDQgODQuOTExMSAxMDguOTE5IDg0LjU4ODlDMTA5LjEzNCA4NC4yNjY2IDEwOS4yNDEgODMuODk0MiAxMDkuMjQxIDgzLjQ3MTdaTTExNy41NzcgODQuOTIxOUwxMjAuMjYzIDc1Ljg3N0gxMjEuOTE3TDEyMS40NjYgNzguNTg0TDExOC43NTkgODcuNUgxMTcuMjc2TDExNy41NzcgODQuOTIxOVpNMTE1Ljk5OCA3NS44NzdMMTE4LjA5MyA4NC45NjQ4TDExOC4yNjUgODcuNUgxMTYuNjFMMTEzLjQ2MyA3NS44NzdIMTE1Ljk5OFpNMTI0LjQzMSA4NC44NTc0TDEyNi40NjEgNzUuODc3SDEyOC45ODVMMTI1Ljg0OSA4Ny41SDEyNC4xOTRMMTI0LjQzMSA4NC44NTc0Wk0xMjIuMTk2IDc1Ljg3N0wxMjQuODUgODQuODE0NUwxMjUuMTgzIDg3LjVIMTIzLjdMMTIwLjk2MSA3OC41NzMyTDEyMC41MSA3NS44NzdIMTIyLjE5NlpNMTMzLjg2MiA3NS44NzdWODcuNUgxMzEuMjYzVjc1Ljg3N0gxMzMuODYyWk0xMzEuMDkxIDcyLjgyNjJDMTMxLjA5MSA3Mi40MzIzIDEzMS4yMiA3Mi4xMDY0IDEzMS40NzggNzEuODQ4NkMxMzEuNzQzIDcxLjU4MzcgMTMyLjEwOCA3MS40NTEyIDEzMi41NzMgNzEuNDUxMkMxMzMuMDMyIDcxLjQ1MTIgMTMzLjM5MyA3MS41ODM3IDEzMy42NTggNzEuODQ4NkMxMzMuOTIzIDcyLjEwNjQgMTM0LjA1NiA3Mi40MzIzIDEzNC4wNTYgNzIuODI2MkMxMzQuMDU2IDczLjIxMjkgMTMzLjkyMyA3My41MzUyIDEzMy42NTggNzMuNzkzQzEzMy4zOTMgNzQuMDUwOCAxMzMuMDMyIDc0LjE3OTcgMTMyLjU3MyA3NC4xNzk3QzEzMi4xMDggNzQuMTc5NyAxMzEuNzQzIDc0LjA1MDggMTMxLjQ3OCA3My43OTNDMTMxLjIyIDczLjUzNTIgMTMxLjA5MSA3My4yMTI5IDEzMS4wOTEgNzIuODI2MlpNMTQyLjM3IDc1Ljg3N1Y3Ny43Njc2SDEzNS44MTdWNzUuODc3SDE0Mi4zN1pNMTM3LjcwOCA3My4wMzAzSDE0MC4yOTdWODQuMjg4MUMxNDAuMjk3IDg0LjY0NjIgMTQwLjM0NyA4NC45MjE5IDE0MC40NDcgODUuMTE1MkMxNDAuNTU1IDg1LjMwMTQgMTQwLjcwMSA4NS40MjY4IDE0MC44ODggODUuNDkxMkMxNDEuMDc0IDg1LjU1NTcgMTQxLjI5MiA4NS41ODc5IDE0MS41NDMgODUuNTg3OUMxNDEuNzIyIDg1LjU4NzkgMTQxLjg5NCA4NS41NzcxIDE0Mi4wNTkgODUuNTU1N0MxNDIuMjIzIDg1LjUzNDIgMTQyLjM1NiA4NS41MTI3IDE0Mi40NTYgODUuNDkxMkwxNDIuNDY3IDg3LjQ2NzhDMTQyLjI1MiA4Ny41MzIyIDE0Mi4wMDEgODcuNTg5NSAxNDEuNzE1IDg3LjYzOTZDMTQxLjQzNiA4Ny42ODk4IDE0MS4xMTMgODcuNzE0OCAxNDAuNzQ4IDg3LjcxNDhDMTQwLjE1NCA4Ny43MTQ4IDEzOS42MjcgODcuNjExIDEzOS4xNjkgODcuNDAzM0MxMzguNzExIDg3LjE4ODUgMTM4LjM1MyA4Ni44NDExIDEzOC4wOTUgODYuMzYxM0MxMzcuODM3IDg1Ljg4MTUgMTM3LjcwOCA4NS4yNDQxIDEzNy43MDggODQuNDQ5MlY3My4wMzAzWk0xNDkuNDYgODUuNjUyM0MxNDkuODgyIDg1LjY1MjMgMTUwLjI2MiA4NS41NyAxNTAuNTk5IDg1LjQwNTNDMTUwLjk0MiA4NS4yMzM0IDE1MS4yMTggODQuOTk3MSAxNTEuNDI2IDg0LjY5NjNDMTUxLjY0MSA4NC4zOTU1IDE1MS43NTkgODQuMDQ4MiAxNTEuNzggODMuNjU0M0gxNTQuMjE5QzE1NC4yMDQgODQuNDA2MiAxNTMuOTgyIDg1LjA5MDIgMTUzLjU1MyA4NS43MDYxQzE1My4xMjMgODYuMzIxOSAxNTIuNTU0IDg2LjgxMjUgMTUxLjg0NSA4Ny4xNzc3QzE1MS4xMzYgODcuNTM1OCAxNTAuMzUyIDg3LjcxNDggMTQ5LjQ5MiA4Ny43MTQ4QzE0OC42MDQgODcuNzE0OCAxNDcuODMxIDg3LjU2NDUgMTQ3LjE3MiA4Ny4yNjM3QzE0Ni41MTMgODYuOTU1NyAxNDUuOTY1IDg2LjUzMzIgMTQ1LjUyOCA4NS45OTYxQzE0NS4wOTEgODUuNDU5IDE0NC43NjIgODQuODM5NSAxNDQuNTQgODQuMTM3N0MxNDQuMzI1IDgzLjQzNTkgMTQ0LjIxOCA4Mi42ODM5IDE0NC4yMTggODEuODgxOFY4MS41MDU5QzE0NC4yMTggODAuNzAzOCAxNDQuMzI1IDc5Ljk1MTggMTQ0LjU0IDc5LjI1QzE0NC43NjIgNzguNTQxIDE0NS4wOTEgNzcuOTE4IDE0NS41MjggNzcuMzgwOUMxNDUuOTY1IDc2Ljg0MzggMTQ2LjUxMyA3Ni40MjQ4IDE0Ny4xNzIgNzYuMTI0QzE0Ny44MzEgNzUuODE2MSAxNDguNjAxIDc1LjY2MjEgMTQ5LjQ4MSA3NS42NjIxQzE1MC40MTIgNzUuNjYyMSAxNTEuMjI5IDc1Ljg0ODMgMTUxLjkzMSA3Ni4yMjA3QzE1Mi42MzIgNzYuNTg1OSAxNTMuMTg0IDc3LjA5OCAxNTMuNTg1IDc3Ljc1NjhDMTUzLjk5MyA3OC40MDg1IDE1NC4yMDQgNzkuMTY3NiAxNTQuMjE5IDgwLjAzNDJIMTUxLjc4QzE1MS43NTkgNzkuNjA0NSAxNTEuNjUxIDc5LjIxNzggMTUxLjQ1OCA3OC44NzRDMTUxLjI3MiA3OC41MjMxIDE1MS4wMDcgNzguMjQzOCAxNTAuNjYzIDc4LjAzNjFDMTUwLjMyNiA3Ny44Mjg1IDE0OS45MjIgNzcuNzI0NiAxNDkuNDQ5IDc3LjcyNDZDMTQ4LjkyNiA3Ny43MjQ2IDE0OC40OTMgNzcuODMyIDE0OC4xNDkgNzguMDQ2OUMxNDcuODA2IDc4LjI1NDYgMTQ3LjUzNyA3OC41NDEgMTQ3LjM0NCA3OC45MDYyQzE0Ny4xNSA3OS4yNjQzIDE0Ny4wMTEgNzkuNjY4OSAxNDYuOTI1IDgwLjEyMDFDMTQ2Ljg0NiA4MC41NjQxIDE0Ni44MDcgODEuMDI2IDE0Ni44MDcgODEuNTA1OVY4MS44ODE4QzE0Ni44MDcgODIuMzYxNyAxNDYuODQ2IDgyLjgyNzEgMTQ2LjkyNSA4My4yNzgzQzE0Ny4wMDQgODMuNzI5NSAxNDcuMTQgODQuMTM0MSAxNDcuMzMzIDg0LjQ5MjJDMTQ3LjUzNCA4NC44NDMxIDE0Ny44MDYgODUuMTI2IDE0OC4xNDkgODUuMzQwOEMxNDguNDkzIDg1LjU0ODUgMTQ4LjkzIDg1LjY1MjMgMTQ5LjQ2IDg1LjY1MjNaTTE1OS4xMDYgNzFWODcuNUgxNTYuNTI4VjcxSDE1OS4xMDZaTTE1OC42NTUgODEuMjU4OEwxNTcuODE3IDgxLjI0OEMxNTcuODI1IDgwLjQ0NiAxNTcuOTM2IDc5LjcwNDggMTU4LjE1IDc5LjAyNDRDMTU4LjM3MiA3OC4zNDQxIDE1OC42OCA3Ny43NTMzIDE1OS4wNzQgNzcuMjUyQzE1OS40NzUgNzYuNzQzNSAxNTkuOTU1IDc2LjM1MzIgMTYwLjUxNCA3Ni4wODExQzE2MS4wNzIgNzUuODAxOCAxNjEuNjkyIDc1LjY2MjEgMTYyLjM3MiA3NS42NjIxQzE2Mi45NDUgNzUuNjYyMSAxNjMuNDYxIDc1Ljc0MDkgMTYzLjkxOSA3NS44OTg0QzE2NC4zODQgNzYuMDU2IDE2NC43ODUgNzYuMzEwMiAxNjUuMTIyIDc2LjY2MTFDMTY1LjQ1OSA3Ny4wMDQ5IDE2NS43MTMgNzcuNDU2MSAxNjUuODg1IDc4LjAxNDZDMTY2LjA2NCA3OC41NjYxIDE2Ni4xNTMgNzkuMjM5MyAxNjYuMTUzIDgwLjAzNDJWODcuNUgxNjMuNTU0VjgwLjAxMjdDMTYzLjU1NCA3OS40NTQxIDE2My40NzEgNzkuMDEwMSAxNjMuMzA3IDc4LjY4MDdDMTYzLjE0OSA3OC4zNTEyIDE2Mi45MTYgNzguMTE0OSAxNjIuNjA4IDc3Ljk3MTdDMTYyLjMgNzcuODIxMyAxNjEuOTI0IDc3Ljc0NjEgMTYxLjQ4IDc3Ljc0NjFDMTYxLjAxNSA3Ny43NDYxIDE2MC42MDMgNzcuODM5MiAxNjAuMjQ1IDc4LjAyNTRDMTU5Ljg5NCA3OC4yMTE2IDE1OS42MDEgNzguNDY1OCAxNTkuMzY0IDc4Ljc4ODFDMTU5LjEyOCA3OS4xMTA0IDE1OC45NDkgNzkuNDgyNyAxNTguODI3IDc5LjkwNTNDMTU4LjcxMyA4MC4zMjc4IDE1OC42NTUgODAuNzc5IDE1OC42NTUgODEuMjU4OFoiIGZpbGw9ImJsYWNrIiBmaWxsLW9wYWNpdHk9IjAuNzYiLz4KPC9zdmc+Cg==", - "description": "Sends the command to the device or updates attribute/time-series when the user toggles the slider. Widget settings will enable you to configure behavior how to fetch the initial state and what to trigger when turn on/off states.", + "description": "Allows users to toggle a slider to send commands to devices or update attributes/time-series data. Configurable settings let users define how to retrieve the initial state and specify actions for the on/off toggle.", "descriptor": { "type": "rpc", "sizeX": 3.5, @@ -30,6 +30,9 @@ "interface", "subroutine call", "inter-process communication", - "server request" + "server request", + "update attribute", + "set attribute", + "add time-series" ] } \ No newline at end of file diff --git a/ui-ngx/src/assets/locale/locale.constant-en_US.json b/ui-ngx/src/assets/locale/locale.constant-en_US.json index 4160b50024..92e4ab9895 100644 --- a/ui-ngx/src/assets/locale/locale.constant-en_US.json +++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json @@ -5185,7 +5185,7 @@ "action-button": { "behavior": "Behavior", "on-click": "On click", - "on-click-hint": "Action performed when the button is clicked." + "on-click-hint": "Action triggered when the button is clicked" }, "command-button": { "behavior": "Behavior", @@ -5214,9 +5214,9 @@ }, "button-state": { "activated-state": "Activated state", - "activated-state-hint": "Condition under which the button is active.", + "activated-state-hint": "Configure condition under which the button is active.", "disabled-state": "Disabled state", - "disabled-state-hint": "Condition under which the button is disabled.", + "disabled-state-hint": "Configure condition under which the button is disabled.", "enabled": "Enabled", "hovered": "Hovered", "pressed": "Pressed", @@ -6526,13 +6526,13 @@ }, "rpc-state": { "initial-state": "Initial state", - "initial-state-hint": "Action to get the initial value of the component.", + "initial-state-hint": "Action to get the initial state (On/Off) of the component.", "disabled-state": "Disabled state", - "disabled-state-hint": "Condition under which the component is disabled.", + "disabled-state-hint": "Configure condition under which the component is disabled.", "turn-on": "Turn 'On'", - "turn-on-hint": "Action performed to turn ON the component.", + "turn-on-hint": "Action triggered when the slider is switched to 'On'", "turn-off": "Turn 'Off'", - "turn-off-hint": "Action performed to turn OFF the component.", + "turn-off-hint": "Action triggered when the slider is switched to 'Off'", "on": "On", "off": "Off", "disabled": "Disabled" From 2faf63bf81c82a6e352015c82e311d7b36d12335 Mon Sep 17 00:00:00 2001 From: Igor Kulikov Date: Thu, 8 Feb 2024 19:48:32 +0200 Subject: [PATCH 177/179] UI: Implement power button widget --- .../json/system/widget_bundles/buttons.json | 3 +- .../widget_bundles/control_widgets.json | 2 + .../system/widget_types/power_button.json | 36 + .../basic/basic-widget-config.module.ts | 12 +- .../power-button-basic-config.component.html | 197 ++++ .../power-button-basic-config.component.ts | 195 ++++ .../widget/lib/action/action-widget.models.ts | 2 + .../rpc/power-button-widget.component.html | 32 + .../rpc/power-button-widget.component.scss | 64 ++ .../lib/rpc/power-button-widget.component.ts | 200 ++++ .../lib/rpc/power-button-widget.models.ts | 912 ++++++++++++++++++ ...ower-button-widget-settings.component.html | 142 +++ .../power-button-widget-settings.component.ts | 88 ++ .../lib/settings/widget-settings.module.ts | 12 +- .../widget/widget-components.module.ts | 7 +- .../assets/locale/locale.constant-en_US.json | 22 + .../widget/power-button/default-layout.svg | 22 + .../power-button/default-volume-layout.svg | 50 + .../widget/power-button/outlined-layout.svg | 23 + .../power-button/outlined-volume-layout.svg | 37 + .../widget/power-button/simplified-layout.svg | 20 + .../power-button/simplified-volume-layout.svg | 33 + 22 files changed, 2102 insertions(+), 9 deletions(-) create mode 100644 application/src/main/data/json/system/widget_types/power_button.json create mode 100644 ui-ngx/src/app/modules/home/components/widget/config/basic/button/power-button-basic-config.component.html create mode 100644 ui-ngx/src/app/modules/home/components/widget/config/basic/button/power-button-basic-config.component.ts create mode 100644 ui-ngx/src/app/modules/home/components/widget/lib/rpc/power-button-widget.component.html create mode 100644 ui-ngx/src/app/modules/home/components/widget/lib/rpc/power-button-widget.component.scss create mode 100644 ui-ngx/src/app/modules/home/components/widget/lib/rpc/power-button-widget.component.ts create mode 100644 ui-ngx/src/app/modules/home/components/widget/lib/rpc/power-button-widget.models.ts create mode 100644 ui-ngx/src/app/modules/home/components/widget/lib/settings/button/power-button-widget-settings.component.html create mode 100644 ui-ngx/src/app/modules/home/components/widget/lib/settings/button/power-button-widget-settings.component.ts create mode 100644 ui-ngx/src/assets/widget/power-button/default-layout.svg create mode 100644 ui-ngx/src/assets/widget/power-button/default-volume-layout.svg create mode 100644 ui-ngx/src/assets/widget/power-button/outlined-layout.svg create mode 100644 ui-ngx/src/assets/widget/power-button/outlined-volume-layout.svg create mode 100644 ui-ngx/src/assets/widget/power-button/simplified-layout.svg create mode 100644 ui-ngx/src/assets/widget/power-button/simplified-volume-layout.svg diff --git a/application/src/main/data/json/system/widget_bundles/buttons.json b/application/src/main/data/json/system/widget_bundles/buttons.json index a48fba892b..00036a0cba 100644 --- a/application/src/main/data/json/system/widget_bundles/buttons.json +++ b/application/src/main/data/json/system/widget_bundles/buttons.json @@ -9,6 +9,7 @@ }, "widgetTypeFqns": [ "action_button", - "command_button" + "command_button", + "power_button" ] } \ No newline at end of file diff --git a/application/src/main/data/json/system/widget_bundles/control_widgets.json b/application/src/main/data/json/system/widget_bundles/control_widgets.json index 5dce630e64..568a144874 100644 --- a/application/src/main/data/json/system/widget_bundles/control_widgets.json +++ b/application/src/main/data/json/system/widget_bundles/control_widgets.json @@ -9,6 +9,8 @@ }, "widgetTypeFqns": [ "single_switch", + "command_button", + "power_button", "control_widgets.switch_control", "control_widgets.slide_toggle_control", "control_widgets.round_switch", diff --git a/application/src/main/data/json/system/widget_types/power_button.json b/application/src/main/data/json/system/widget_types/power_button.json new file mode 100644 index 0000000000..2f825c9e74 --- /dev/null +++ b/application/src/main/data/json/system/widget_types/power_button.json @@ -0,0 +1,36 @@ +{ + "fqn": "power_button", + "name": "Power button", + "deprecated": false, + "image": "tb-image:cG93ZXItYnV0dG9uLnN2Zw==:IlBvd2VyIGJ1dHRvbiIgc3lzdGVtIHdpZGdldCBpbWFnZQ==;data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAwIiBoZWlnaHQ9IjE2MCIgdmlld0JveD0iMCAwIDIwMCAxNjAiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxnIGZpbHRlcj0idXJsKCNmaWx0ZXIwX2lfNDU4OF84ODQyMCkiPgo8cGF0aCBkPSJNMTQ2LjUgODBDMTQ2LjUgMTA1LjEyOSAxMjUuNjgxIDEyNS41IDEwMCAxMjUuNUM3NC4zMTg4IDEyNS41IDUzLjUgMTA1LjEyOSA1My41IDgwQzUzLjUgNTQuODcxIDc0LjMxODggMzQuNSAxMDAgMzQuNUMxMjUuNjgxIDM0LjUgMTQ2LjUgNTQuODcxIDE0Ni41IDgwWiIgZmlsbD0iIzNGNTJERCIvPgo8L2c+CjxwYXRoIGQ9Ik0xNDUuNSA4MEMxNDUuNSAxMDQuNTU2IDEyNS4xNSAxMjQuNSAxMDAgMTI0LjVDNzQuODUwNCAxMjQuNSA1NC41IDEwNC41NTYgNTQuNSA4MEM1NC41IDU1LjQ0MzcgNzQuODUwNCAzNS41IDEwMCAzNS41QzEyNS4xNSAzNS41IDE0NS41IDU1LjQ0MzcgMTQ1LjUgODBaIiBzdHJva2U9IndoaXRlIiBzdHJva2Utd2lkdGg9IjIiLz4KPGcgZmlsdGVyPSJ1cmwoI2ZpbHRlcjFfZF80NTg4Xzg4NDIwKSI+CjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNMTAwIDEzNS41QzEzMS4yMDQgMTM1LjUgMTU2LjUgMTEwLjY1MiAxNTYuNSA4MEMxNTYuNSA0OS4zNDgyIDEzMS4yMDQgMjQuNSAxMDAgMjQuNUM2OC43OTU5IDI0LjUgNDMuNSA0OS4zNDgyIDQzLjUgODBDNDMuNSAxMTAuNjUyIDY4Ljc5NTkgMTM1LjUgMTAwIDEzNS41Wk0xMDAgMTI1LjVDMTI1LjY4MSAxMjUuNSAxNDYuNSAxMDUuMTI5IDE0Ni41IDgwQzE0Ni41IDU0Ljg3MSAxMjUuNjgxIDM0LjUgMTAwIDM0LjVDNzQuMzE4OCAzNC41IDUzLjUgNTQuODcxIDUzLjUgODBDNTMuNSAxMDUuMTI5IDc0LjMxODggMTI1LjUgMTAwIDEyNS41WiIgZmlsbD0idXJsKCNwYWludDBfbGluZWFyXzQ1ODhfODg0MjApIi8+CjwvZz4KPHBhdGggZD0iTTk4LjM1NzQgNzkuMTg1NVY4MC4xNzM4Qzk4LjM1NzQgODEuMzQ4MyA5OC4yMTA2IDgyLjQwMSA5Ny45MTcgODMuMzMyQzk3LjYyMzQgODQuMjYzIDk3LjIwMDggODUuMDU0NCA5Ni42NDk0IDg1LjcwNjFDOTYuMDk4IDg2LjM1NzcgOTUuNDM1NSA4Ni44NTU1IDk0LjY2MjEgODcuMTk5MkM5My44OTU4IDg3LjU0MyA5My4wMzY1IDg3LjcxNDggOTIuMDg0IDg3LjcxNDhDOTEuMTYwMiA4Ny43MTQ4IDkwLjMxMTUgODcuNTQzIDg5LjUzODEgODcuMTk5MkM4OC43NzE4IDg2Ljg1NTUgODguMTA1OCA4Ni4zNTc3IDg3LjU0IDg1LjcwNjFDODYuOTgxNCA4NS4wNTQ0IDg2LjU0ODIgODQuMjYzIDg2LjI0MDIgODMuMzMyQzg1LjkzMjMgODIuNDAxIDg1Ljc3ODMgODEuMzQ4MyA4NS43NzgzIDgwLjE3MzhWNzkuMTg1NUM4NS43NzgzIDc4LjAxMTEgODUuOTI4NyA3Ni45NjE5IDg2LjIyOTUgNzYuMDM4MUM4Ni41Mzc0IDc1LjEwNzEgODYuOTcwNyA3NC4zMTU4IDg3LjUyOTMgNzMuNjY0MUM4OC4wODc5IDczLjAwNTIgODguNzUwMyA3Mi41MDM5IDg5LjUxNjYgNzIuMTYwMkM5MC4yOSA3MS44MTY0IDkxLjEzODcgNzEuNjQ0NSA5Mi4wNjI1IDcxLjY0NDVDOTMuMDE1IDcxLjY0NDUgOTMuODc0MyA3MS44MTY0IDk0LjY0MDYgNzIuMTYwMkM5NS40MTQxIDcyLjUwMzkgOTYuMDc2NSA3My4wMDUyIDk2LjYyNzkgNzMuNjY0MUM5Ny4xODY1IDc0LjMxNTggOTcuNjEyNiA3NS4xMDcxIDk3LjkwNjIgNzYuMDM4MUM5OC4yMDcgNzYuOTYxOSA5OC4zNTc0IDc4LjAxMTEgOTguMzU3NCA3OS4xODU1Wk05Ni4zMDU3IDgwLjE3MzhWNzkuMTY0MUM5Ni4zMDU3IDc4LjIzMzEgOTYuMjA5IDc3LjQwOTUgOTYuMDE1NiA3Ni42OTM0Qzk1LjgyOTQgNzUuOTc3MiA5NS41NTM3IDc1LjM3NTcgOTUuMTg4NSA3NC44ODg3Qzk0LjgyMzIgNzQuNDAxNyA5NC4zNzU3IDc0LjAzMjkgOTMuODQ1NyA3My43ODIyQzkzLjMyMjkgNzMuNTMxNiA5Mi43Mjg1IDczLjQwNjIgOTIuMDYyNSA3My40MDYyQzkxLjQxOCA3My40MDYyIDkwLjgzNDMgNzMuNTMxNiA5MC4zMTE1IDczLjc4MjJDODkuNzk1OSA3NC4wMzI5IDg5LjM1MTkgNzQuNDAxNyA4OC45Nzk1IDc0Ljg4ODdDODguNjE0MyA3NS4zNzU3IDg4LjMzMTQgNzUuOTc3MiA4OC4xMzA5IDc2LjY5MzRDODcuOTMwMyA3Ny40MDk1IDg3LjgzMDEgNzguMjMzMSA4Ny44MzAxIDc5LjE2NDFWODAuMTczOEM4Ny44MzAxIDgxLjExMiA4Ny45MzAzIDgxLjk0MjcgODguMTMwOSA4Mi42NjZDODguMzMxNCA4My4zODIyIDg4LjYxNzggODMuOTg3MyA4OC45OTAyIDg0LjQ4MTRDODkuMzY5OCA4NC45Njg0IDg5LjgxNzQgODUuMzM3MiA5MC4zMzMgODUuNTg3OUM5MC44NTU4IDg1LjgzODUgOTEuNDM5NSA4NS45NjM5IDkyLjA4NCA4NS45NjM5QzkyLjc1NzIgODUuOTYzOSA5My4zNTUxIDg1LjgzODUgOTMuODc3OSA4NS41ODc5Qzk0LjQwMDcgODUuMzM3MiA5NC44NDExIDg0Ljk2ODQgOTUuMTk5MiA4NC40ODE0Qzk1LjU2NDUgODMuOTg3MyA5NS44NDAyIDgzLjM4MjIgOTYuMDI2NCA4Mi42NjZDOTYuMjEyNiA4MS45NDI3IDk2LjMwNTcgODEuMTEyIDk2LjMwNTcgODAuMTczOFpNMTEzLjQ5MyA3MS44NTk0Vjg3LjVIMTExLjQwOUwxMDMuNTM1IDc1LjQzNjVWODcuNUgxMDEuNDYyVjcxLjg1OTRIMTAzLjUzNUwxMTEuNDQxIDgzLjk1NTFWNzEuODU5NEgxMTMuNDkzWiIgZmlsbD0id2hpdGUiLz4KPGRlZnM+CjxmaWx0ZXIgaWQ9ImZpbHRlcjBfaV80NTg4Xzg4NDIwIiB4PSI0OC41IiB5PSIzNC41IiB3aWR0aD0iOTgiIGhlaWdodD0iOTYiIGZpbHRlclVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgY29sb3ItaW50ZXJwb2xhdGlvbi1maWx0ZXJzPSJzUkdCIj4KPGZlRmxvb2QgZmxvb2Qtb3BhY2l0eT0iMCIgcmVzdWx0PSJCYWNrZ3JvdW5kSW1hZ2VGaXgiLz4KPGZlQmxlbmQgbW9kZT0ibm9ybWFsIiBpbj0iU291cmNlR3JhcGhpYyIgaW4yPSJCYWNrZ3JvdW5kSW1hZ2VGaXgiIHJlc3VsdD0ic2hhcGUiLz4KPGZlQ29sb3JNYXRyaXggaW49IlNvdXJjZUFscGhhIiB0eXBlPSJtYXRyaXgiIHZhbHVlcz0iMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMTI3IDAiIHJlc3VsdD0iaGFyZEFscGhhIi8+CjxmZU9mZnNldCBkeD0iLTUiIGR5PSI1Ii8+CjxmZUdhdXNzaWFuQmx1ciBzdGREZXZpYXRpb249IjQiLz4KPGZlQ29tcG9zaXRlIGluMj0iaGFyZEFscGhhIiBvcGVyYXRvcj0iYXJpdGhtZXRpYyIgazI9Ii0xIiBrMz0iMSIvPgo8ZmVDb2xvck1hdHJpeCB0eXBlPSJtYXRyaXgiIHZhbHVlcz0iMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMC4xNSAwIi8+CjxmZUJsZW5kIG1vZGU9Im5vcm1hbCIgaW4yPSJzaGFwZSIgcmVzdWx0PSJlZmZlY3QxX2lubmVyU2hhZG93XzQ1ODhfODg0MjAiLz4KPC9maWx0ZXI+CjxmaWx0ZXIgaWQ9ImZpbHRlcjFfZF80NTg4Xzg4NDIwIiB4PSIzNS41IiB5PSIyMC41IiB3aWR0aD0iMTI5IiBoZWlnaHQ9IjEyNyIgZmlsdGVyVW5pdHM9InVzZXJTcGFjZU9uVXNlIiBjb2xvci1pbnRlcnBvbGF0aW9uLWZpbHRlcnM9InNSR0IiPgo8ZmVGbG9vZCBmbG9vZC1vcGFjaXR5PSIwIiByZXN1bHQ9IkJhY2tncm91bmRJbWFnZUZpeCIvPgo8ZmVDb2xvck1hdHJpeCBpbj0iU291cmNlQWxwaGEiIHR5cGU9Im1hdHJpeCIgdmFsdWVzPSIwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAxMjcgMCIgcmVzdWx0PSJoYXJkQWxwaGEiLz4KPGZlT2Zmc2V0IGR5PSI0Ii8+CjxmZUdhdXNzaWFuQmx1ciBzdGREZXZpYXRpb249IjQiLz4KPGZlQ29tcG9zaXRlIGluMj0iaGFyZEFscGhhIiBvcGVyYXRvcj0ib3V0Ii8+CjxmZUNvbG9yTWF0cml4IHR5cGU9Im1hdHJpeCIgdmFsdWVzPSIwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwLjA4IDAiLz4KPGZlQmxlbmQgbW9kZT0ibm9ybWFsIiBpbjI9IkJhY2tncm91bmRJbWFnZUZpeCIgcmVzdWx0PSJlZmZlY3QxX2Ryb3BTaGFkb3dfNDU4OF84ODQyMCIvPgo8ZmVCbGVuZCBtb2RlPSJub3JtYWwiIGluPSJTb3VyY2VHcmFwaGljIiBpbjI9ImVmZmVjdDFfZHJvcFNoYWRvd180NTg4Xzg4NDIwIiByZXN1bHQ9InNoYXBlIi8+CjwvZmlsdGVyPgo8bGluZWFyR3JhZGllbnQgaWQ9InBhaW50MF9saW5lYXJfNDU4OF84ODQyMCIgeDE9IjY1Ljg5NjQiIHkxPSIxMjQuNSIgeDI9IjEyOS41MTkiIHkyPSIzMy45MjQ4IiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+CjxzdG9wIHN0b3AtY29sb3I9IiNDQ0NDQ0MiLz4KPHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSJ3aGl0ZSIvPgo8L2xpbmVhckdyYWRpZW50Pgo8L2RlZnM+Cjwvc3ZnPgo=", + "description": "Sends the command to the device or updates attribute/time-series when the user pushes the button. Widget settings will enable you to configure behavior how to fetch the initial state and what to trigger when power on/off states.", + "descriptor": { + "type": "rpc", + "sizeX": 3.5, + "sizeY": 3.5, + "resources": [], + "templateHtml": "\n", + "templateCss": "", + "controllerScript": "self.onInit = function() {\n self.ctx.$scope.actionWidget.onInit();\n}\n\nself.typeParameters = function() {\n return {\n previewWidth: '280px',\n previewHeight: '280px',\n embedTitlePanel: true,\n displayRpcMessageToast: false\n };\n};\n\nself.onDestroy = function() {\n}\n", + "settingsSchema": "", + "dataKeySettingsSchema": "{}\n", + "settingsDirective": "tb-power-button-widget-settings", + "hasBasicMode": true, + "basicModeDirective": "tb-power-button-basic-config", + "defaultConfig": "{\"showTitle\":true,\"backgroundColor\":\"#ffffff\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"0px\",\"settings\":{\"initialState\":{\"action\":\"EXECUTE_RPC\",\"defaultValue\":false,\"executeRpc\":{\"method\":\"getState\",\"requestTimeout\":5000,\"requestPersistent\":false,\"persistentPollingInterval\":1000},\"getAttribute\":{\"key\":\"state\",\"scope\":null},\"getTimeSeries\":{\"key\":\"state\"},\"dataToValue\":{\"type\":\"NONE\",\"compareToValue\":true,\"dataToValueFunction\":\"/* Should return boolean value */\\nreturn data;\"}},\"onUpdateState\":{\"action\":\"EXECUTE_RPC\",\"executeRpc\":{\"method\":\"setState\",\"requestTimeout\":5000,\"requestPersistent\":false,\"persistentPollingInterval\":1000},\"setAttribute\":{\"key\":\"state\",\"scope\":\"SHARED_SCOPE\"},\"putTimeSeries\":{\"key\":\"state\"},\"valueToData\":{\"type\":\"CONSTANT\",\"constantValue\":true,\"valueToDataFunction\":\"/* Convert input boolean value to RPC parameters or attribute/time-series value */\\nreturn value;\"}},\"offUpdateState\":{\"action\":\"EXECUTE_RPC\",\"executeRpc\":{\"method\":\"setState\",\"requestTimeout\":5000,\"requestPersistent\":false,\"persistentPollingInterval\":1000},\"setAttribute\":{\"key\":\"state\",\"scope\":\"SHARED_SCOPE\"},\"putTimeSeries\":{\"key\":\"state\"},\"valueToData\":{\"type\":\"CONSTANT\",\"constantValue\":false,\"valueToDataFunction\":\"/* Convert input boolean value to RPC parameters or attribute/time-series value */ \\n return value;\"}},\"disabledState\":{\"action\":\"DO_NOTHING\",\"defaultValue\":false,\"getAttribute\":{\"key\":\"state\",\"scope\":null},\"getTimeSeries\":{\"key\":\"state\"},\"dataToValue\":{\"type\":\"NONE\",\"compareToValue\":true,\"dataToValueFunction\":\"/* Should return boolean value */\\nreturn data;\"}},\"layout\":\"default\",\"mainColorOn\":\"#3F52DD\",\"backgroundColorOn\":\"#FFFFFF\",\"mainColorOff\":\"#A2A2A2\",\"backgroundColorOff\":\"#FFFFFF\",\"mainColorDisabled\":\"rgba(0,0,0,0.12)\",\"backgroundColorDisabled\":\"#FFFFFF\",\"background\":{\"type\":\"color\",\"color\":\"#fff\",\"overlay\":{\"enabled\":false,\"color\":\"rgba(255,255,255,0.72)\",\"blur\":3}}},\"title\":\"Power\",\"dropShadow\":true,\"enableFullscreen\":false,\"widgetStyle\":{},\"actions\":{},\"widgetCss\":\"\",\"noDataDisplayMessage\":\"\",\"titleFont\":{\"size\":16,\"sizeUnit\":\"px\",\"family\":\"Roboto\",\"weight\":\"500\",\"style\":null,\"lineHeight\":\"1.6\"},\"showTitleIcon\":false,\"titleTooltip\":\"\",\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"pageSize\":1024,\"titleIcon\":\"mdi:lightbulb-outline\",\"iconColor\":\"rgba(0, 0, 0, 0.87)\",\"iconSize\":\"24px\",\"configMode\":\"basic\",\"targetDevice\":null,\"titleColor\":null,\"borderRadius\":null}" + }, + "tags": [ + "command", + "downlink", + "device configuration", + "device control", + "invocation", + "remote method", + "remote function", + "interface", + "subroutine call", + "inter-process communication", + "server request", + "power" + ] +} \ No newline at end of file diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/basic-widget-config.module.ts b/ui-ngx/src/app/modules/home/components/widget/config/basic/basic-widget-config.module.ts index bb31daf7bb..c268be7bcd 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/basic/basic-widget-config.module.ts +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/basic-widget-config.module.ts @@ -100,6 +100,9 @@ import { import { CommandButtonBasicConfigComponent } from '@home/components/widget/config/basic/button/command-button-basic-config.component'; +import { + PowerButtonBasicConfigComponent +} from '@home/components/widget/config/basic/button/power-button-basic-config.component'; @NgModule({ declarations: [ @@ -131,7 +134,8 @@ import { BarChartWithLabelsBasicConfigComponent, SingleSwitchBasicConfigComponent, ActionButtonBasicConfigComponent, - CommandButtonBasicConfigComponent + CommandButtonBasicConfigComponent, + PowerButtonBasicConfigComponent ], imports: [ CommonModule, @@ -167,7 +171,8 @@ import { BarChartWithLabelsBasicConfigComponent, SingleSwitchBasicConfigComponent, ActionButtonBasicConfigComponent, - CommandButtonBasicConfigComponent + CommandButtonBasicConfigComponent, + PowerButtonBasicConfigComponent ] }) export class BasicWidgetConfigModule { @@ -197,5 +202,6 @@ export const basicWidgetConfigComponentsMap: {[key: string]: Type + + +
+
widgets.power-button.behavior
+
+
widgets.rpc-state.initial-state
+ +
+
+
widgets.power-button.power-on
+ +
+
+
widgets.power-button.power-off
+ +
+
+
widgets.rpc-state.disabled-state
+ +
+
+
+
widget-config.appearance
+ + + {{ powerButtonLayoutTranslationMap.get(layout) | translate }} + + +
+ + {{ 'widget-config.title' | translate }} + +
+ + + + + + + +
+
+
+ + {{ 'widget-config.card-icon' | translate }} + +
+ + + + + + + + +
+
+
+
{{ 'widgets.power-button.power-on-colors' | translate }}
+
+
+
widgets.power-button.main
+ + +
+ +
+
widgets.power-button.background
+ + +
+
+
+
+
{{ 'widgets.power-button.power-off-colors' | translate }}
+
+
+
widgets.power-button.main
+ + +
+ +
+
widgets.power-button.background
+ + +
+
+
+
+
{{ 'widgets.power-button.disabled-colors' | translate }}
+
+
+
widgets.power-button.main
+ + +
+ +
+
widgets.power-button.background
+ + +
+
+
+
+
+
widget-config.card-appearance
+
+
{{ 'widgets.background.background' | translate }}
+ + +
+
+
widget-config.show-card-buttons
+ + {{ 'fullscreen.fullscreen' | translate }} + +
+
+
{{ 'widget-config.card-border-radius' | translate }}
+ + + +
+
+ + +
diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/button/power-button-basic-config.component.ts b/ui-ngx/src/app/modules/home/components/widget/config/basic/button/power-button-basic-config.component.ts new file mode 100644 index 0000000000..174ded9ed3 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/button/power-button-basic-config.component.ts @@ -0,0 +1,195 @@ +/// +/// Copyright © 2016-2024 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 { Component } from '@angular/core'; +import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms'; +import { Store } from '@ngrx/store'; +import { AppState } from '@core/core.state'; +import { BasicWidgetConfigComponent } from '@home/components/widget/config/widget-config.component.models'; +import { WidgetConfigComponentData } from '@home/models/widget-component.models'; +import { TargetDevice, WidgetConfig, } from '@shared/models/widget.models'; +import { WidgetConfigComponent } from '@home/components/widget/widget-config.component'; +import { isUndefined } from '@core/utils'; +import { ValueType } from '@shared/models/constants'; +import { + powerButtonDefaultSettings, + powerButtonLayoutImages, + powerButtonLayouts, + powerButtonLayoutTranslations, + PowerButtonWidgetSettings +} from '@home/components/widget/lib/rpc/power-button-widget.models'; +import { cssSizeToStrSize, resolveCssSize } from '@shared/models/widget-settings.models'; + +@Component({ + selector: 'tb-power-button-basic-config', + templateUrl: './power-button-basic-config.component.html', + styleUrls: ['../basic-config.scss'] +}) +export class PowerButtonBasicConfigComponent extends BasicWidgetConfigComponent { + + get targetDevice(): TargetDevice { + return this.powerButtonWidgetConfigForm.get('targetDevice').value; + } + + powerButtonLayouts = powerButtonLayouts; + + powerButtonLayoutTranslationMap = powerButtonLayoutTranslations; + powerButtonLayoutImageMap = powerButtonLayoutImages; + + valueType = ValueType; + + powerButtonWidgetConfigForm: UntypedFormGroup; + + constructor(protected store: Store, + protected widgetConfigComponent: WidgetConfigComponent, + private fb: UntypedFormBuilder) { + super(store, widgetConfigComponent); + } + + protected configForm(): UntypedFormGroup { + return this.powerButtonWidgetConfigForm; + } + + protected onConfigSet(configData: WidgetConfigComponentData) { + const settings: PowerButtonWidgetSettings = {...powerButtonDefaultSettings, ...(configData.config.settings || {})}; + const iconSize = resolveCssSize(configData.config.iconSize); + this.powerButtonWidgetConfigForm = this.fb.group({ + targetDevice: [configData.config.targetDevice, []], + + initialState: [settings.initialState, []], + onUpdateState: [settings.onUpdateState, []], + offUpdateState: [settings.offUpdateState, []], + disabledState: [settings.disabledState, []], + + layout: [settings.layout, []], + + showTitle: [configData.config.showTitle, []], + title: [configData.config.title, []], + titleFont: [configData.config.titleFont, []], + titleColor: [configData.config.titleColor, []], + + showIcon: [configData.config.showTitleIcon, []], + iconSize: [iconSize[0], [Validators.min(0)]], + iconSizeUnit: [iconSize[1], []], + icon: [configData.config.titleIcon, []], + iconColor: [configData.config.iconColor, []], + + mainColorOn: [settings.mainColorOn, []], + backgroundColorOn: [settings.backgroundColorOn, []], + + mainColorOff: [settings.mainColorOff, []], + backgroundColorOff: [settings.backgroundColorOff, []], + + mainColorDisabled: [settings.mainColorDisabled, []], + backgroundColorDisabled: [settings.backgroundColorDisabled, []], + + background: [settings.background, []], + + cardButtons: [this.getCardButtons(configData.config), []], + borderRadius: [configData.config.borderRadius, []], + + actions: [configData.config.actions || {}, []] + }); + } + + protected prepareOutputConfig(config: any): WidgetConfigComponentData { + this.widgetConfig.config.targetDevice = config.targetDevice; + + this.widgetConfig.config.showTitle = config.showTitle; + this.widgetConfig.config.title = config.title; + this.widgetConfig.config.titleFont = config.titleFont; + this.widgetConfig.config.titleColor = config.titleColor; + + this.widgetConfig.config.showTitleIcon = config.showIcon; + this.widgetConfig.config.iconSize = cssSizeToStrSize(config.iconSize, config.iconSizeUnit); + this.widgetConfig.config.titleIcon = config.icon; + this.widgetConfig.config.iconColor = config.iconColor; + + this.widgetConfig.config.settings = this.widgetConfig.config.settings || {}; + + this.widgetConfig.config.settings.initialState = config.initialState; + this.widgetConfig.config.settings.onUpdateState = config.onUpdateState; + this.widgetConfig.config.settings.offUpdateState = config.offUpdateState; + this.widgetConfig.config.settings.disabledState = config.disabledState; + + this.widgetConfig.config.settings.layout = config.layout; + + this.widgetConfig.config.settings.mainColorOn = config.mainColorOn; + this.widgetConfig.config.settings.backgroundColorOn = config.backgroundColorOn; + + this.widgetConfig.config.settings.mainColorOff = config.mainColorOff; + this.widgetConfig.config.settings.backgroundColorOff = config.backgroundColorOff; + + this.widgetConfig.config.settings.mainColorDisabled = config.mainColorDisabled; + this.widgetConfig.config.settings.backgroundColorDisabled = config.backgroundColorDisabled; + + this.widgetConfig.config.settings.background = config.background; + + this.setCardButtons(config.cardButtons, this.widgetConfig.config); + this.widgetConfig.config.borderRadius = config.borderRadius; + + this.widgetConfig.config.actions = config.actions; + return this.widgetConfig; + } + + protected validatorTriggers(): string[] { + return ['showTitle', 'showIcon']; + } + + protected updateValidators(emitEvent: boolean, trigger?: string) { + const showTitle: boolean = this.powerButtonWidgetConfigForm.get('showTitle').value; + const showIcon: boolean = this.powerButtonWidgetConfigForm.get('showIcon').value; + if (showTitle) { + this.powerButtonWidgetConfigForm.get('title').enable(); + this.powerButtonWidgetConfigForm.get('titleFont').enable(); + this.powerButtonWidgetConfigForm.get('titleColor').enable(); + this.powerButtonWidgetConfigForm.get('showIcon').enable({emitEvent: false}); + if (showIcon) { + this.powerButtonWidgetConfigForm.get('iconSize').enable(); + this.powerButtonWidgetConfigForm.get('iconSizeUnit').enable(); + this.powerButtonWidgetConfigForm.get('icon').enable(); + this.powerButtonWidgetConfigForm.get('iconColor').enable(); + } else { + this.powerButtonWidgetConfigForm.get('iconSize').disable(); + this.powerButtonWidgetConfigForm.get('iconSizeUnit').disable(); + this.powerButtonWidgetConfigForm.get('icon').disable(); + this.powerButtonWidgetConfigForm.get('iconColor').disable(); + } + } else { + this.powerButtonWidgetConfigForm.get('title').disable(); + this.powerButtonWidgetConfigForm.get('titleFont').disable(); + this.powerButtonWidgetConfigForm.get('titleColor').disable(); + this.powerButtonWidgetConfigForm.get('showIcon').disable({emitEvent: false}); + this.powerButtonWidgetConfigForm.get('iconSize').disable(); + this.powerButtonWidgetConfigForm.get('iconSizeUnit').disable(); + this.powerButtonWidgetConfigForm.get('icon').disable(); + this.powerButtonWidgetConfigForm.get('iconColor').disable(); + } + } + + private getCardButtons(config: WidgetConfig): string[] { + const buttons: string[] = []; + if (isUndefined(config.enableFullscreen) || config.enableFullscreen) { + buttons.push('fullscreen'); + } + return buttons; + } + + private setCardButtons(buttons: string[], config: WidgetConfig) { + config.enableFullscreen = buttons.includes('fullscreen'); + } + +} diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/action/action-widget.models.ts b/ui-ngx/src/app/modules/home/components/widget/lib/action/action-widget.models.ts index 26dc76866a..dc56a1e992 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/action/action-widget.models.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/action/action-widget.models.ts @@ -91,6 +91,8 @@ export abstract class BasicActionWidgetComponent implements OnInit, OnDestroy, A ngOnDestroy() { this.valueActions.forEach(v => v.destroy()); + this.loadingSubject.complete(); + this.loadingSubject.unsubscribe(); } public onInit() { diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/rpc/power-button-widget.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/rpc/power-button-widget.component.html new file mode 100644 index 0000000000..93e394ac5e --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/lib/rpc/power-button-widget.component.html @@ -0,0 +1,32 @@ + +
+
+ +
+
+
+
+ +
+
+
+ +
+
+
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/rpc/power-button-widget.component.scss b/ui-ngx/src/app/modules/home/components/widget/lib/rpc/power-button-widget.component.scss new file mode 100644 index 0000000000..e0192630f9 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/lib/rpc/power-button-widget.component.scss @@ -0,0 +1,64 @@ +/** + * Copyright © 2016-2024 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +.tb-power-button-panel { + width: 100%; + height: 100%; + position: relative; + display: flex; + flex-direction: column; + gap: 16px; + padding: 20px 24px 24px 24px; + > div:not(.tb-power-button-overlay) { + z-index: 1; + } + .tb-power-button-overlay { + position: absolute; + top: 12px; + left: 12px; + bottom: 12px; + right: 12px; + } + div.tb-widget-title { + padding: 0; + } + .tb-power-button-content { + flex: 1; + min-width: 0; + min-height: 0; + .tb-power-button-shape { + width: 100%; + height: 100%; + display: flex; + align-items: center; + justify-content: center; + svg { + .tb-small-shadow { + filter: drop-shadow(0px 4px 6px rgba(0, 0, 0, 0.08)); + } + .tb-shadow { + filter: drop-shadow(8px 8px 8px rgba(0, 0, 0, 0.1)); + } + } + &.tb-power-button-pointer { + svg { + .tb-hover-circle { + cursor: pointer; + } + } + } + } + } +} diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/rpc/power-button-widget.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/rpc/power-button-widget.component.ts new file mode 100644 index 0000000000..e68a2e4baa --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/lib/rpc/power-button-widget.component.ts @@ -0,0 +1,200 @@ +/// +/// Copyright © 2016-2024 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 { + AfterViewInit, + ChangeDetectorRef, + Component, + ElementRef, + OnDestroy, + OnInit, + Renderer2, + ViewChild, + ViewEncapsulation +} from '@angular/core'; +import { BasicActionWidgetComponent, ValueSetter } from '@home/components/widget/lib/action/action-widget.models'; +import { backgroundStyle, ComponentStyle, overlayStyle } from '@shared/models/widget-settings.models'; +import { Observable } from 'rxjs'; +import { ResizeObserver } from '@juggle/resize-observer'; +import { ImagePipe } from '@shared/pipe/image.pipe'; +import { DomSanitizer } from '@angular/platform-browser'; +import { ValueType } from '@shared/models/constants'; +import { + powerButtonDefaultSettings, + PowerButtonShape, + powerButtonShapeSize, + PowerButtonWidgetSettings +} from '@home/components/widget/lib/rpc/power-button-widget.models'; +import { SVG, Svg } from '@svgdotjs/svg.js'; + +@Component({ + selector: 'tb-power-button-widget', + templateUrl: './power-button-widget.component.html', + styleUrls: ['../action/action-widget.scss', './power-button-widget.component.scss'], + encapsulation: ViewEncapsulation.None +}) +export class PowerButtonWidgetComponent extends + BasicActionWidgetComponent implements OnInit, AfterViewInit, OnDestroy { + + @ViewChild('powerButtonShape', {static: false}) + powerButtonShape: ElementRef; + + settings: PowerButtonWidgetSettings; + + backgroundStyle$: Observable; + overlayStyle: ComponentStyle = {}; + + value = false; + disabled = false; + + private shapeResize$: ResizeObserver; + private drawSvgShapePending = false; + private svgShape: Svg; + private powerButtonSvgShape: PowerButtonShape; + private disabledState = false; + + private onValueSetter: ValueSetter; + private offValueSetter: ValueSetter; + + constructor(protected imagePipe: ImagePipe, + protected sanitizer: DomSanitizer, + private renderer: Renderer2, + protected cd: ChangeDetectorRef) { + super(cd); + } + + ngOnInit(): void { + super.ngOnInit(); + this.settings = {...powerButtonDefaultSettings, ...this.ctx.settings}; + + this.backgroundStyle$ = backgroundStyle(this.settings.background, this.imagePipe, this.sanitizer); + this.overlayStyle = overlayStyle(this.settings.background.overlay); + + const getInitialStateSettings = + {...this.settings.initialState, actionLabel: this.ctx.translate.instant('widgets.rpc-state.initial-state')}; + this.createValueGetter(getInitialStateSettings, ValueType.BOOLEAN, { + next: (value) => this.onValue(value) + }); + + const disabledStateSettings = + {...this.settings.disabledState, actionLabel: this.ctx.translate.instant('widgets.rpc-state.disabled-state')}; + this.createValueGetter(disabledStateSettings, ValueType.BOOLEAN, { + next: (value) => this.onDisabled(value) + }); + + const onUpdateStateSettings = {...this.settings.onUpdateState, + actionLabel: this.ctx.translate.instant('widgets.power-button.power-on')}; + this.onValueSetter = this.createValueSetter(onUpdateStateSettings); + + const offUpdateStateSettings = {...this.settings.offUpdateState, + actionLabel: this.ctx.translate.instant('widgets.power-button.power-off')}; + this.offValueSetter = this.createValueSetter(offUpdateStateSettings); + + this.loading$.subscribe((loading) => { + this.updateDisabledState(loading || this.disabled); + }); + } + + ngAfterViewInit(): void { + if (this.drawSvgShapePending) { + this.drawSvg(); + } + super.ngAfterViewInit(); + } + + ngOnDestroy() { + if (this.shapeResize$) { + this.shapeResize$.disconnect(); + } + super.ngOnDestroy(); + } + + public onInit() { + super.onInit(); + const borderRadius = this.ctx.$widgetElement.css('borderRadius'); + this.overlayStyle = {...this.overlayStyle, ...{borderRadius}}; + if (this.powerButtonShape) { + this.drawSvg(); + } else { + this.drawSvgShapePending = true; + } + this.cd.detectChanges(); + } + + private onValue(value: boolean): void { + const newValue = !!value; + if (this.value !== newValue) { + this.value = newValue; + this.powerButtonSvgShape?.setValue(this.value); + } + } + + private onDisabled(value: boolean): void { + const newDisabled = !!value; + if (this.disabled !== newDisabled) { + this.disabled = newDisabled; + this.updateDisabledState(this.disabled); + } + } + + private onClick() { + if (!this.ctx.isEdit && !this.ctx.isPreview && !this.disabledState) { + this.onValue(!this.value); + const targetValue = this.value; + const targetSetter = targetValue ? this.onValueSetter : this.offValueSetter; + this.powerButtonSvgShape?.setPressed(true); + this.updateValue(targetSetter, targetValue, { + next: () => { + this.powerButtonSvgShape?.setPressed(false); + this.onValue(targetValue); + }, + error: () => { + this.powerButtonSvgShape?.setPressed(false); + this.onValue(!targetValue); + } + }); + } + } + + private drawSvg() { + this.svgShape = SVG().addTo(this.powerButtonShape.nativeElement).size(powerButtonShapeSize, powerButtonShapeSize); + this.renderer.setStyle(this.svgShape.node, 'overflow', 'visible'); + this.renderer.setStyle(this.svgShape.node, 'user-select', 'none'); + + this.powerButtonSvgShape = PowerButtonShape.fromSettings(this.ctx, this.svgShape, + this.settings, this.value, this.disabledState, () => this.onClick()); + + this.shapeResize$ = new ResizeObserver(() => { + this.onResize(); + }); + this.shapeResize$.observe(this.powerButtonShape.nativeElement); + this.onResize(); + } + + private updateDisabledState(disabled: boolean) { + this.disabledState = disabled; + this.powerButtonSvgShape?.setDisabled(this.disabledState); + } + + private onResize() { + const shapeWidth = this.powerButtonShape.nativeElement.getBoundingClientRect().width; + const shapeHeight = this.powerButtonShape.nativeElement.getBoundingClientRect().height; + const size = Math.min(shapeWidth, shapeHeight); + const scale = size / powerButtonShapeSize; + this.renderer.setStyle(this.svgShape.node, 'transform', `scale(${scale})`); + } + +} diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/rpc/power-button-widget.models.ts b/ui-ngx/src/app/modules/home/components/widget/lib/rpc/power-button-widget.models.ts new file mode 100644 index 0000000000..b1372a9660 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/lib/rpc/power-button-widget.models.ts @@ -0,0 +1,912 @@ +/// +/// Copyright © 2016-2024 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 { BackgroundSettings, BackgroundType } from '@shared/models/widget-settings.models'; +import { AttributeScope } from '@shared/models/telemetry/telemetry.models'; +import { + DataToValueType, + GetValueAction, + GetValueSettings, + SetValueAction, + SetValueSettings, + ValueToDataType +} from '@shared/models/action-widget-settings.models'; +import { Circle, Element, G, Gradient, Runner, Stop, Svg, Text, Timeline } from '@svgdotjs/svg.js'; +import tinycolor from 'tinycolor2'; +import { WidgetContext } from '@home/models/widget-component.models'; + +export enum PowerButtonLayout { + default = 'default', + simplified = 'simplified', + outlined = 'outlined', + default_volume = 'default_volume', + simplified_volume = 'simplified_volume', + outlined_volume = 'outlined_volume' +} + +export const powerButtonLayouts = Object.keys(PowerButtonLayout) as PowerButtonLayout[]; + +export const powerButtonLayoutTranslations = new Map( + [ + [PowerButtonLayout.default, 'widgets.power-button.layout-default'], + [PowerButtonLayout.simplified, 'widgets.power-button.layout-simplified'], + [PowerButtonLayout.outlined, 'widgets.power-button.layout-outlined'], + [PowerButtonLayout.default_volume, 'widgets.power-button.layout-default-volume'], + [PowerButtonLayout.simplified_volume, 'widgets.power-button.layout-simplified-volume'], + [PowerButtonLayout.outlined_volume, 'widgets.power-button.layout-outlined-volume'] + ] +); + +export const powerButtonLayoutImages = new Map( + [ + [PowerButtonLayout.default, 'assets/widget/power-button/default-layout.svg'], + [PowerButtonLayout.simplified, 'assets/widget/power-button/simplified-layout.svg'], + [PowerButtonLayout.outlined, 'assets/widget/power-button/outlined-layout.svg'], + [PowerButtonLayout.default_volume, 'assets/widget/power-button/default-volume-layout.svg'], + [PowerButtonLayout.simplified_volume, 'assets/widget/power-button/simplified-volume-layout.svg'], + [PowerButtonLayout.outlined_volume, 'assets/widget/power-button/outlined-volume-layout.svg'] + ] +); + +export interface PowerButtonWidgetSettings { + initialState: GetValueSettings; + disabledState: GetValueSettings; + onUpdateState: SetValueSettings; + offUpdateState: SetValueSettings; + layout: PowerButtonLayout; + mainColorOn: string; + backgroundColorOn: string; + mainColorOff: string; + backgroundColorOff: string; + mainColorDisabled: string; + backgroundColorDisabled: string; + background: BackgroundSettings; +} + +export const powerButtonDefaultSettings: PowerButtonWidgetSettings = { + initialState: { + action: GetValueAction.EXECUTE_RPC, + defaultValue: false, + executeRpc: { + method: 'getState', + requestTimeout: 5000, + requestPersistent: false, + persistentPollingInterval: 1000 + }, + getAttribute: { + key: 'state', + scope: null + }, + getTimeSeries: { + key: 'state' + }, + dataToValue: { + type: DataToValueType.NONE, + compareToValue: true, + dataToValueFunction: '/* Should return boolean value */\nreturn data;' + } + }, + disabledState: { + action: GetValueAction.DO_NOTHING, + defaultValue: false, + getAttribute: { + key: 'state', + scope: null + }, + getTimeSeries: { + key: 'state' + }, + dataToValue: { + type: DataToValueType.NONE, + compareToValue: true, + dataToValueFunction: '/* Should return boolean value */\nreturn data;' + } + }, + onUpdateState: { + action: SetValueAction.EXECUTE_RPC, + executeRpc: { + method: 'setState', + requestTimeout: 5000, + requestPersistent: false, + persistentPollingInterval: 1000 + }, + setAttribute: { + key: 'state', + scope: AttributeScope.SHARED_SCOPE + }, + putTimeSeries: { + key: 'state' + }, + valueToData: { + type: ValueToDataType.CONSTANT, + constantValue: true, + valueToDataFunction: '/* Convert input boolean value to RPC parameters or attribute/time-series value */\nreturn value;' + } + }, + offUpdateState: { + action: SetValueAction.EXECUTE_RPC, + executeRpc: { + method: 'setState', + requestTimeout: 5000, + requestPersistent: false, + persistentPollingInterval: 1000 + }, + setAttribute: { + key: 'state', + scope: AttributeScope.SHARED_SCOPE + }, + putTimeSeries: { + key: 'state' + }, + valueToData: { + type: ValueToDataType.CONSTANT, + constantValue: false, + valueToDataFunction: '/* Convert input boolean value to RPC parameters or attribute/time-series value */ \n return value;' + } + }, + layout: PowerButtonLayout.default, + mainColorOn: '#3F52DD', + backgroundColorOn: '#FFFFFF', + mainColorOff: '#A2A2A2', + backgroundColorOff: '#FFFFFF', + mainColorDisabled: 'rgba(0,0,0,0.12)', + backgroundColorDisabled: '#FFFFFF', + background: { + type: BackgroundType.color, + color: '#fff', + overlay: { + enabled: false, + color: 'rgba(255,255,255,0.72)', + blur: 3 + } + } +}; + +interface PowerButtonColor { + hex: string; + opacity: number; +} + +type PowerButtonState = 'on' | 'off' | 'disabled'; + +interface PowerButtonColorState { + mainColor: PowerButtonColor; + backgroundColor: PowerButtonColor; +} + +type PowerButtonShapeColors = Record; + +const createPowerButtonShapeColors = (settings: PowerButtonWidgetSettings): PowerButtonShapeColors => { + const mainColorOn = tinycolor(settings.mainColorOn); + const backgroundColorOn = tinycolor(settings.backgroundColorOn); + const mainColorOff = tinycolor(settings.mainColorOff); + const backgroundColorOff = tinycolor(settings.backgroundColorOff); + const mainColorDisabled = tinycolor(settings.mainColorDisabled); + const backgroundColorDisabled = tinycolor(settings.backgroundColorDisabled); + return { + on: { + mainColor: {hex: mainColorOn.toHexString(), opacity: mainColorOn.getAlpha()}, + backgroundColor: {hex: backgroundColorOn.toHexString(), opacity: backgroundColorOn.getAlpha()}, + }, + off: { + mainColor: {hex: mainColorOff.toHexString(), opacity: mainColorOff.getAlpha()}, + backgroundColor: {hex: backgroundColorOff.toHexString(), opacity: backgroundColorOff.getAlpha()}, + }, + disabled: { + mainColor: {hex: mainColorDisabled.toHexString(), opacity: mainColorDisabled.getAlpha()}, + backgroundColor: {hex: backgroundColorDisabled.toHexString(), opacity: backgroundColorDisabled.getAlpha()}, + } + }; +}; + +export const powerButtonShapeSize = 110; +const cx = powerButtonShapeSize / 2; +const cy = powerButtonShapeSize / 2; + +export abstract class PowerButtonShape { + + static fromSettings(ctx: WidgetContext, + svgShape: Svg, + settings: PowerButtonWidgetSettings, + value: boolean, + disabled: boolean, + onClick: () => void): PowerButtonShape { + switch (settings.layout) { + case PowerButtonLayout.default: + return new DefaultPowerButtonShape(ctx, svgShape, settings, value, disabled, onClick); + case PowerButtonLayout.simplified: + return new SimplifiedPowerButtonShape(ctx, svgShape, settings, value, disabled, onClick); + case PowerButtonLayout.outlined: + return new OutlinedPowerButtonShape(ctx, svgShape, settings, value, disabled, onClick); + case PowerButtonLayout.default_volume: + return new DefaultVolumePowerButtonShape(ctx, svgShape, settings, value, disabled, onClick); + case PowerButtonLayout.simplified_volume: + return new SimplifiedVolumePowerButtonShape(ctx, svgShape, settings, value, disabled, onClick); + case PowerButtonLayout.outlined_volume: + return new OutlinedVolumePowerButtonShape(ctx, svgShape, settings, value, disabled, onClick); + } + } + + protected readonly colors: PowerButtonShapeColors; + protected readonly onLabel: string; + protected readonly offLabel: string; + + protected backgroundShape: Circle; + protected hoverShape: Circle; + protected hovered = false; + protected pressed = false; + protected forcePressed = false; + + protected constructor(protected widgetContext: WidgetContext, + protected svgShape: Svg, + protected settings: PowerButtonWidgetSettings, + protected value: boolean, + protected disabled: boolean, + protected onClick: () => void) { + this.colors = createPowerButtonShapeColors(this.settings); + this.onLabel = this.widgetContext.translate.instant('widgets.power-button.on-label').toUpperCase(); + this.offLabel = this.widgetContext.translate.instant('widgets.power-button.off-label').toUpperCase(); + this._drawShape(); + } + + public setValue(value: boolean) { + if (this.value !== value) { + this.value = value; + this._drawState(); + } + } + + public setDisabled(disabled: boolean) { + if (this.disabled !== disabled) { + this.disabled = disabled; + this._drawState(); + } + } + + public setPressed(pressed: boolean) { + if (this.forcePressed !== pressed) { + this.forcePressed = pressed; + if (this.forcePressed && !this.pressed) { + this.onPressStart(); + } else if (!this.forcePressed && !this.pressed) { + this.onPressEnd(); + } + } + } + + private _drawShape() { + + this.backgroundShape = this.svgShape.circle(powerButtonShapeSize).center(cx, cy) + .fill({opacity: 0}).stroke({width: 0}); + + this.drawShape(); + + this.hoverShape = this.svgShape.circle(powerButtonShapeSize).center(cx, cy).addClass('tb-hover-circle') + .fill({color: '#000000', opacity: 0}); + this.hoverShape.on('mouseover', () => { + this.hovered = true; + if (!this.disabled) { + this.hoverShape.timeline().finish(); + this.hoverShape.animate(200).attr({'fill-opacity': 0.06}); + } + }); + this.hoverShape.on('mouseout', () => { + this.hovered = false; + this.hoverShape.timeline().finish(); + this.hoverShape.animate(200).attr({'fill-opacity': 0}); + this._cancelPressed(); + }); + this.hoverShape.on('touchmove', (event: TouchEvent) => { + const touch = event.touches[0]; + const element = document.elementFromPoint(touch.pageX,touch.pageY); + if (this.hoverShape.node !== element) { + this._cancelPressed(); + } + }); + this.hoverShape.on('touchcancel', () => { + this._cancelPressed(); + }); + this.hoverShape.on('mousedown touchstart', (event: Event) => { + if (event.type === 'mousedown') { + if ((event as MouseEvent).button !== 0) { + return; + } + } + if (!this.disabled && !this.pressed) { + this.pressed = true; + if (!this.forcePressed) { + this.onPressStart(); + } + } + }); + this.hoverShape.on('mouseup touchend touchcancel', () => { + if (this.pressed && !this.disabled) { + this.onClick(); + } + this._cancelPressed(); + }); + this._drawState(); + } + + private _cancelPressed() { + if (this.pressed) { + this.pressed = false; + if (!this.forcePressed) { + this.onPressEnd(); + } + } + } + + private _drawState() { + let colorState: PowerButtonColorState; + if (this.disabled) { + colorState = this.colors.disabled; + } else { + colorState = this.value ? this.colors.on : this.colors.off; + } + this.drawBackgroundState(colorState.backgroundColor); + this.drawColorState(colorState.mainColor); + if (this.value) { + this.drawOn(); + } else { + this.drawOff(); + } + if (this.disabled) { + this.hoverShape.timeline().finish(); + this.hoverShape.attr({'fill-opacity': 0}); + } else if (this.hovered) { + this.hoverShape.timeline().finish(); + this.hoverShape.animate(200).attr({'fill-opacity': 0.06}); + } + } + + private drawBackgroundState(backgroundColor: PowerButtonColor) { + this.backgroundShape.attr({ fill: backgroundColor.hex, 'fill-opacity': backgroundColor.opacity}); + } + + protected drawShape() {} + + protected drawColorState(_mainColor: PowerButtonColor) {} + + protected drawOff() {} + + protected drawOn() {} + + protected onPressStart() {} + + protected onPressEnd() {} + + protected createMask(shape: Element, maskElements: Element[]) { + const mask = + this.svgShape.mask().add(this.svgShape.rect().width('100%').height('100%').fill('#fff')); + maskElements.forEach(e => { + mask.add(e.fill('#000').attr({'fill-opacity': 1})); + }); + shape.maskWith(mask); + } + + protected createPressedShadow(diameter: number, rightElseLeft = true): Gradient { + const innerShadowGradient = this.svgShape.gradient('radial', (add) => { + add.stop(0.7, '#000000', 0); + add.stop(1, '#000000', 0.4); + }).attr({ cx: rightElseLeft ? '45%' : '55%', cy: '55%', r: '100%'}); + this.svgShape.circle(diameter).center(cx, cy) + .fill(innerShadowGradient).stroke({width: 0}); + return innerShadowGradient; + } + + protected pressedAnimation(element: Element): Runner { + return element.animate(200, 0, 'now'); + } + + protected createOnLabel(fontWeight = '500'): Text { + return this.createLabel(this.onLabel, fontWeight); + } + + protected createOffLabel(fontWeight = '500'): Text { + return this.createLabel(this.offLabel, fontWeight); + } + + private createLabel(text: string, fontWeight = '500'): Text { + return this.svgShape.text(text).font({ + family: 'Roboto', + weight: fontWeight, + style: 'normal', + size: '22px' + }).attr({x: '50%', y: '50%', 'text-anchor': 'middle', 'dominant-baseline': 'middle'}); + } + +} + +class DefaultPowerButtonShape extends PowerButtonShape { + + private outerBorder: Circle; + private outerBorderMask: Circle; + private offLabelShape: Text; + private onCircleShape: Circle; + private onLabelShape: Text; + private pressedShadow: Gradient; + private pressedTimeline: Timeline; + private centerGroup: G; + + protected drawShape() { + this.outerBorder = this.svgShape.circle(powerButtonShapeSize).center(cx, cy) + .fill({opacity: 0}).stroke({width: 0}); + this.outerBorderMask = this.svgShape.circle(powerButtonShapeSize - 20).center(cx, cy); + this.createMask(this.outerBorder, [this.outerBorderMask]); + this.centerGroup = this.svgShape.group(); + this.offLabelShape = this.createOffLabel().addTo(this.centerGroup); + this.onCircleShape = this.svgShape.circle(powerButtonShapeSize - 20) + .center(cx, cy); + this.onLabelShape = this.createOnLabel(); + this.createMask(this.onCircleShape, [this.onLabelShape]); + this.pressedShadow = this.createPressedShadow(powerButtonShapeSize - 20); + + this.pressedTimeline = new Timeline(); + this.centerGroup.timeline(this.pressedTimeline); + this.onLabelShape.timeline(this.pressedTimeline); + this.pressedShadow.timeline(this.pressedTimeline); + } + + protected drawColorState(mainColor: PowerButtonColor) { + this.outerBorder.attr({ fill: mainColor.hex, 'fill-opacity': mainColor.opacity}); + this.offLabelShape.attr({ fill: mainColor.hex, 'fill-opacity': mainColor.opacity}); + this.onCircleShape.attr({ fill: mainColor.hex, 'fill-opacity': mainColor.opacity}); + } + + protected drawOff() { + this.outerBorderMask.radius((powerButtonShapeSize - 20)/2); + this.onCircleShape.hide(); + this.centerGroup.show(); + } + + protected drawOn() { + this.outerBorderMask.radius((powerButtonShapeSize - 2)/2); + this.centerGroup.hide(); + this.onCircleShape.show(); + } + + protected onPressStart() { + this.pressedTimeline.finish(); + const pressedScale = 0.75; + this.pressedAnimation(this.centerGroup).transform({scale: pressedScale}); + this.pressedAnimation(this.onLabelShape).transform({scale: pressedScale}); + this.pressedAnimation(this.pressedShadow).attr({r: '62%'}); + } + + protected onPressEnd() { + this.pressedTimeline.finish(); + this.pressedAnimation(this.centerGroup).transform({scale: 1}); + this.pressedAnimation(this.onLabelShape).transform({scale: 1}); + this.pressedAnimation(this.pressedShadow).attr({r: '100%'}); + } + +} + +class SimplifiedPowerButtonShape extends PowerButtonShape { + + private outerBorder: Circle; + private outerBorderMask: Circle; + private onCircleShape: Circle; + private offLabelShape: Text; + private onLabelShape: Text; + private pressedShadow: Gradient; + private pressedTimeline: Timeline; + private centerGroup: G; + + protected drawShape() { + this.outerBorder = this.svgShape.circle(powerButtonShapeSize).center(cx, cy) + .fill({opacity: 0}).stroke({width: 0}); + this.outerBorderMask = this.svgShape.circle(powerButtonShapeSize - 4).center(cx, cy); + this.createMask(this.outerBorder, [this.outerBorderMask]); + this.centerGroup = this.svgShape.group(); + this.offLabelShape = this.createOffLabel().addTo(this.centerGroup); + this.onCircleShape = this.svgShape.circle(powerButtonShapeSize).center(cx, cy); + this.onLabelShape = this.createOnLabel(); + this.createMask(this.onCircleShape, [this.onLabelShape]); + this.pressedShadow = this.createPressedShadow(powerButtonShapeSize - 4); + + this.pressedTimeline = new Timeline(); + this.centerGroup.timeline(this.pressedTimeline); + this.onLabelShape.timeline(this.pressedTimeline); + this.pressedShadow.timeline(this.pressedTimeline); + } + + protected drawColorState(mainColor: PowerButtonColor) { + this.outerBorder.attr({ fill: mainColor.hex, 'fill-opacity': mainColor.opacity}); + this.onCircleShape.attr({ fill: mainColor.hex, 'fill-opacity': mainColor.opacity}); + this.offLabelShape.attr({ fill: mainColor.hex, 'fill-opacity': mainColor.opacity}); + } + + protected drawOff() { + this.onCircleShape.hide(); + this.outerBorder.show(); + this.centerGroup.show(); + } + + protected drawOn() { + this.centerGroup.hide(); + this.outerBorder.hide(); + this.onCircleShape.show(); + } + + protected onPressStart() { + this.pressedTimeline.finish(); + const pressedScale = 0.75; + this.pressedAnimation(this.centerGroup).transform({scale: pressedScale}); + this.pressedAnimation(this.onLabelShape).transform({scale: pressedScale}); + this.pressedAnimation(this.pressedShadow).attr({r: '62%'}); + } + + protected onPressEnd() { + this.pressedTimeline.finish(); + this.pressedAnimation(this.centerGroup).transform({scale: 1}); + this.pressedAnimation(this.onLabelShape).transform({scale: 1}); + this.pressedAnimation(this.pressedShadow).attr({r: '100%'}); + } +} + +class OutlinedPowerButtonShape extends PowerButtonShape { + private outerBorder: Circle; + private outerBorderMask: Circle; + private innerBorder: Circle; + private innerBorderMask: Circle; + private offLabelShape: Text; + private onCircleShape: Circle; + private onLabelShape: Text; + private pressedShadow: Gradient; + private pressedTimeline: Timeline; + private centerGroup: G; + private onCenterGroup: G; + + protected drawShape() { + this.outerBorder = this.svgShape.circle(powerButtonShapeSize).center(cx, cy) + .fill({opacity: 0}).stroke({width: 0}); + this.outerBorderMask = this.svgShape.circle(powerButtonShapeSize - 2).center(cx, cy); + this.createMask(this.outerBorder, [this.outerBorderMask]); + this.innerBorder = this.svgShape.circle(powerButtonShapeSize - 20).center(cx, cy) + .fill({opacity: 0}).stroke({width: 0}); + this.innerBorderMask = this.svgShape.circle(powerButtonShapeSize - 24).center(cx, cy); + this.createMask(this.innerBorder, [this.innerBorderMask]); + this.centerGroup = this.svgShape.group(); + this.offLabelShape = this.createOffLabel().addTo(this.centerGroup); + this.onCenterGroup = this.svgShape.group(); + this.onCircleShape = this.svgShape.circle(powerButtonShapeSize - 28).center(cx, cy) + .addTo(this.onCenterGroup); + this.onLabelShape = this.createOnLabel(); + this.createMask(this.onCircleShape, [this.onLabelShape]); + this.pressedShadow = this.createPressedShadow(powerButtonShapeSize - 24); + + this.pressedTimeline = new Timeline(); + this.centerGroup.timeline(this.pressedTimeline); + this.onCenterGroup.timeline(this.pressedTimeline); + this.onLabelShape.timeline(this.pressedTimeline); + this.pressedShadow.timeline(this.pressedTimeline); + } + + protected drawColorState(mainColor: PowerButtonColor) { + this.outerBorder.attr({ fill: mainColor.hex, 'fill-opacity': mainColor.opacity}); + this.innerBorder.attr({ fill: mainColor.hex, 'fill-opacity': mainColor.opacity}); + this.offLabelShape.attr({ fill: mainColor.hex, 'fill-opacity': mainColor.opacity}); + this.onCircleShape.attr({ fill: mainColor.hex, 'fill-opacity': mainColor.opacity}); + } + + protected drawOff() { + this.onCenterGroup.hide(); + this.centerGroup.show(); + } + + protected drawOn() { + this.centerGroup.hide(); + this.onCenterGroup.show(); + } + + protected onPressStart() { + this.pressedTimeline.finish(); + const pressedScale = 0.75; + this.pressedAnimation(this.centerGroup).transform({scale: pressedScale}); + this.pressedAnimation(this.onCenterGroup).transform({scale: 0.98}); + this.pressedAnimation(this.onLabelShape).transform({scale: pressedScale / 0.98}); + this.pressedAnimation(this.pressedShadow).attr({r: '62%'}); + } + + protected onPressEnd() { + this.pressedTimeline.finish(); + this.pressedAnimation(this.centerGroup).transform({scale: 1}); + this.pressedAnimation(this.onCenterGroup).transform({scale: 1}); + this.pressedAnimation(this.onLabelShape).transform({scale: 1}); + this.pressedAnimation(this.pressedShadow).attr({r: '100%'}); + } +} + +class DefaultVolumePowerButtonShape extends PowerButtonShape { + private outerBorder: Circle; + private outerBorderMask: Circle; + private outerBorderGradient: Gradient; + private innerBorder: Circle; + private innerBorderMask: Circle; + private innerBorderGradient: Gradient; + private innerShadow: Circle; + private innerShadowGradient: Gradient; + private innerShadowGradientStop: Stop; + private offLabelShape: Text; + private onCircleShape: Circle; + private onLabelShape: Text; + private pressedTimeline: Timeline; + private centerGroup: G; + + protected drawShape() { + this.outerBorder = this.svgShape.circle(powerButtonShapeSize).center(cx, cy) + .fill({opacity: 0}).stroke({width: 0}); + this.outerBorderMask = this.svgShape.circle(powerButtonShapeSize - 20).center(cx, cy); + this.createMask(this.outerBorder, [this.outerBorderMask]); + this.outerBorderGradient = this.svgShape.gradient('linear', (add) => { + add.stop(0, '#CCCCCC', 1); + add.stop(1, '#FFFFFF', 1); + }).from(0.268, 0.92).to(0.832, 0.1188); + this.innerBorder = this.svgShape.circle(powerButtonShapeSize - 20).center(cx, cy) + .fill({opacity: 0}).stroke({width: 0}); + this.innerBorderMask = this.svgShape.circle(powerButtonShapeSize - 24).center(cx, cy); + this.createMask(this.innerBorder, [this.innerBorderMask]); + this.innerBorderGradient = this.svgShape.gradient('linear', (add) => { + add.stop(0, '#CCCCCC', 1); + add.stop(1, '#FFFFFF', 1); + }).from(0.832, 0.1188).to(0.268, 0.92); + this.centerGroup = this.svgShape.group(); + this.offLabelShape = this.createOffLabel('400').addTo(this.centerGroup); + this.onCircleShape = this.svgShape.circle(powerButtonShapeSize - 24).center(cx, cy); + this.onLabelShape = this.createOnLabel('400'); + this.createMask(this.onCircleShape, [this.onLabelShape]); + this.innerShadow = this.svgShape.circle(powerButtonShapeSize - 24).center(cx, cy); + this.innerShadowGradient = this.svgShape.gradient('radial', (add) => { + add.stop(0.7, '#000000', 0); + this.innerShadowGradientStop = add.stop(1, '#000000', 0.2); + }).attr({ cx: '45%', cy: '55%', r: '65%'}); + this.innerShadow.fill(this.innerShadowGradient); + + this.pressedTimeline = new Timeline(); + this.centerGroup.timeline(this.pressedTimeline); + this.onLabelShape.timeline(this.pressedTimeline); + this.innerShadowGradient.timeline(this.pressedTimeline); + this.innerShadowGradientStop.timeline(this.pressedTimeline); + } + + protected drawColorState(mainColor: PowerButtonColor){ + if (this.disabled) { + this.backgroundShape.removeClass('tb-small-shadow'); + if (!this.forcePressed) { + this.innerShadow.hide(); + } + this.outerBorder.attr({ fill: mainColor.hex, 'fill-opacity': mainColor.opacity}); + this.innerBorder.attr({fill: mainColor.hex, 'fill-opacity': mainColor.opacity}); + } else { + this.backgroundShape.addClass('tb-small-shadow'); + this.innerShadow.show(); + this.outerBorder.fill(this.outerBorderGradient); + this.outerBorder.attr({ 'fill-opacity': 1 }); + this.innerBorder.fill(this.innerBorderGradient); + this.innerBorder.attr({ 'fill-opacity': 1 }); + } + this.offLabelShape.attr({ fill: mainColor.hex, 'fill-opacity': mainColor.opacity}); + this.onCircleShape.attr({ fill: mainColor.hex, 'fill-opacity': mainColor.opacity}); + } + + protected drawOff() { + this.onCircleShape.hide(); + this.centerGroup.show(); + this.innerBorder.show(); + } + + protected drawOn() { + if (this.disabled) { + this.innerBorder.hide(); + } else { + this.innerBorder.show(); + } + this.centerGroup.hide(); + this.onCircleShape.show(); + } + + protected onPressStart() { + this.pressedTimeline.finish(); + this.innerShadow.show(); + const pressedScale = 0.75; + this.pressedAnimation(this.centerGroup).transform({scale: pressedScale}); + this.pressedAnimation(this.onLabelShape).transform({scale: pressedScale}); + this.pressedAnimation(this.innerShadowGradient).attr({ r: '60%'}); + this.pressedAnimation(this.innerShadowGradientStop).update({ opacity: 0.4 }); + } + + protected onPressEnd() { + this.pressedTimeline.finish(); + this.pressedAnimation(this.centerGroup).transform({scale: 1}); + this.pressedAnimation(this.onLabelShape).transform({scale: 1}); + this.pressedAnimation(this.innerShadowGradient).attr({ r: '65%'}).after(() => { + if (this.disabled) { + this.innerShadow.hide(); + } + }); + this.pressedAnimation(this.innerShadowGradientStop).update({ opacity: 0.2 }); + } + +} + +class SimplifiedVolumePowerButtonShape extends PowerButtonShape { + + private outerBorder: Circle; + private outerBorderMask: Circle; + private offLabelShape: Text; + private onLabelShape: Text; + private innerShadow: Circle; + private pressedShadow: Gradient; + private pressedTimeline: Timeline; + private centerGroup: G; + private onCenterGroup: G; + + + protected drawShape() { + this.outerBorder = this.svgShape.circle(powerButtonShapeSize).center(cx, cy) + .fill({color: '#FAFAFA', opacity: 1}).stroke({width: 0}); + this.outerBorderMask = this.svgShape.circle(powerButtonShapeSize - 4).center(cx, cy); + this.createMask(this.outerBorder, [this.outerBorderMask]); + this.centerGroup = this.svgShape.group(); + this.offLabelShape = this.createOffLabel().addTo(this.centerGroup); + this.onCenterGroup = this.svgShape.group(); + this.onLabelShape = this.createOnLabel().addTo(this.onCenterGroup); + this.innerShadow = this.svgShape.circle(powerButtonShapeSize - 4).center(cx, cy); + const innerShadowGradient = this.svgShape.gradient('radial', (add) => { + add.stop(0.7, '#000000', 0); + add.stop(1, '#000000', 0.2); + }).attr({ cx: '55%', cy: '55%', r: '65%'}); + this.innerShadow.fill(innerShadowGradient); + this.pressedShadow = this.createPressedShadow(powerButtonShapeSize - 4, false); + + this.pressedTimeline = new Timeline(); + this.centerGroup.timeline(this.pressedTimeline); + this.onCenterGroup.timeline(this.pressedTimeline); + this.pressedShadow.timeline(this.pressedTimeline); + } + + protected drawColorState(mainColor: PowerButtonColor){ + this.offLabelShape.attr({ fill: mainColor.hex, 'fill-opacity': mainColor.opacity}); + this.onLabelShape.attr({ fill: mainColor.hex, 'fill-opacity': mainColor.opacity}); + } + + protected drawOff() { + if (!this.pressed) { + this.backgroundShape.addClass('tb-shadow'); + } + this.innerShadow.hide(); + this.onCenterGroup.hide(); + this.centerGroup.show(); + } + + protected drawOn() { + this.backgroundShape.removeClass('tb-shadow'); + this.centerGroup.hide(); + this.onCenterGroup.show(); + this.innerShadow.show(); + } + + protected onPressStart() { + this.pressedTimeline.finish(); + const pressedScale = 0.75; + if (!this.value) { + this.backgroundShape.removeClass('tb-shadow'); + } + this.pressedAnimation(this.centerGroup).transform({scale: pressedScale}); + this.pressedAnimation(this.onCenterGroup).transform({scale: pressedScale}); + this.pressedAnimation(this.pressedShadow).attr({r: '62%'}); + } + + protected onPressEnd() { + this.pressedTimeline.finish(); + this.pressedAnimation(this.centerGroup).transform({scale: 1}); + this.pressedAnimation(this.onCenterGroup).transform({scale: 1}); + this.pressedAnimation(this.pressedShadow).attr({r: '100%'}).after(() => { + if (!this.value) { + this.backgroundShape.addClass('tb-shadow'); + } + }); + } +} + +class OutlinedVolumePowerButtonShape extends PowerButtonShape { + private outerBorder: Circle; + private outerBorderMask: Circle; + private outerBorderGradient: Gradient; + private innerBorder: Circle; + private innerBorderMask: Circle; + private offLabelShape: Text; + private onCircleShape: Circle; + private onLabelShape: Text; + private pressedShadow: Gradient; + private pressedTimeline: Timeline; + private centerGroup: G; + private onCenterGroup: G; + + protected drawShape() { + this.outerBorder = this.svgShape.circle(powerButtonShapeSize).center(cx, cy) + .fill({opacity: 0}).stroke({width: 0}); + this.outerBorderMask = this.svgShape.circle(powerButtonShapeSize - 20).center(cx, cy); + this.createMask(this.outerBorder, [this.outerBorderMask]); + this.outerBorderGradient = this.svgShape.gradient('linear', (add) => { + add.stop(0, '#CCCCCC', 1); + add.stop(1, '#FFFFFF', 1); + }).from(0.268, 0.92).to(0.832, 0.1188); + this.innerBorder = this.svgShape.circle(powerButtonShapeSize - 20).center(cx, cy) + .fill({opacity: 0}).stroke({width: 0}); + this.innerBorderMask = this.svgShape.circle(powerButtonShapeSize - 30).center(cx, cy); + this.createMask(this.innerBorder, [this.innerBorderMask]); + this.centerGroup = this.svgShape.group(); + this.offLabelShape = this.createOffLabel('800').addTo(this.centerGroup); + this.onCenterGroup = this.svgShape.group(); + this.onCircleShape = this.svgShape.circle(powerButtonShapeSize - 30).center(cx, cy) + .addTo(this.onCenterGroup); + this.onLabelShape = this.createOnLabel('800'); + this.createMask(this.onCircleShape, [this.onLabelShape]); + this.pressedShadow = this.createPressedShadow(powerButtonShapeSize - 30); + this.backgroundShape.addClass('tb-small-shadow'); + + this.pressedTimeline = new Timeline(); + this.centerGroup.timeline(this.pressedTimeline); + this.onCenterGroup.timeline(this.pressedTimeline); + this.onLabelShape.timeline(this.pressedTimeline); + this.pressedShadow.timeline(this.pressedTimeline); + } + + protected drawColorState(mainColor: PowerButtonColor){ + if (this.disabled) { + this.outerBorder.attr({ fill: '#000000', 'fill-opacity': 0.03}); + } else { + this.outerBorder.fill(this.outerBorderGradient); + this.outerBorder.attr({ 'fill-opacity': 1 }); + } + this.innerBorder.attr({fill: mainColor.hex, 'fill-opacity': mainColor.opacity}); + this.offLabelShape.attr({ fill: mainColor.hex, 'fill-opacity': mainColor.opacity}); + this.onCircleShape.attr({ fill: mainColor.hex, 'fill-opacity': mainColor.opacity}); + } + + protected drawOff() { + this.onCenterGroup.hide(); + this.centerGroup.show(); + this.innerBorder.show(); + } + + protected drawOn() { + this.innerBorder.hide(); + this.centerGroup.hide(); + this.onCenterGroup.show(); + } + + protected onPressStart() { + this.pressedTimeline.finish(); + const pressedScale = 0.75; + this.pressedAnimation(this.centerGroup).transform({scale: pressedScale}); + this.pressedAnimation(this.onCenterGroup).transform({scale: 0.98}); + this.pressedAnimation(this.onLabelShape).transform({scale: pressedScale / 0.98}); + this.pressedAnimation(this.pressedShadow).attr({r: '62%'}); + } + + protected onPressEnd() { + this.pressedTimeline.finish(); + this.pressedAnimation(this.centerGroup).transform({scale: 1}); + this.pressedAnimation(this.onCenterGroup).transform({scale: 1}); + this.pressedAnimation(this.onLabelShape).transform({scale: 1}); + this.pressedAnimation(this.pressedShadow).attr({r: '100%'}); + } + +} diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/button/power-button-widget-settings.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/button/power-button-widget-settings.component.html new file mode 100644 index 0000000000..ced9bf9575 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/button/power-button-widget-settings.component.html @@ -0,0 +1,142 @@ + + +
+
widgets.power-button.behavior
+
+
widgets.rpc-state.initial-state
+ +
+
+
widgets.power-button.power-on
+ +
+
+
widgets.power-button.power-off
+ +
+
+
widgets.rpc-state.disabled-state
+ +
+
+
+
widget-config.card-style
+ + + {{ powerButtonLayoutTranslationMap.get(layout) | translate }} + + +
+
{{ 'widgets.background.background' | translate }}
+ + +
+
+
+
widgets.power-button.button
+
+
{{ 'widgets.power-button.power-on-colors' | translate }}
+
+
+
widgets.power-button.main
+ + +
+ +
+
widgets.power-button.background
+ + +
+
+
+
+
{{ 'widgets.power-button.power-off-colors' | translate }}
+
+
+
widgets.power-button.main
+ + +
+ +
+
widgets.power-button.background
+ + +
+
+
+
+
{{ 'widgets.power-button.disabled-colors' | translate }}
+
+
+
widgets.power-button.main
+ + +
+ +
+
widgets.power-button.background
+ + +
+
+
+
+
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/button/power-button-widget-settings.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/button/power-button-widget-settings.component.ts new file mode 100644 index 0000000000..c1d9f98460 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/button/power-button-widget-settings.component.ts @@ -0,0 +1,88 @@ +/// +/// Copyright © 2016-2024 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 { Component } from '@angular/core'; +import { TargetDevice, WidgetSettings, WidgetSettingsComponent, widgetType } from '@shared/models/widget.models'; +import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms'; +import { Store } from '@ngrx/store'; +import { AppState } from '@core/core.state'; +import { ValueType } from '@shared/models/constants'; +import { + powerButtonDefaultSettings, + powerButtonLayoutImages, + powerButtonLayouts, + powerButtonLayoutTranslations +} from '@home/components/widget/lib/rpc/power-button-widget.models'; + +@Component({ + selector: 'tb-power-button-widget-settings', + templateUrl: './power-button-widget-settings.component.html', + styleUrls: ['./../widget-settings.scss'] +}) +export class PowerButtonWidgetSettingsComponent extends WidgetSettingsComponent { + + get targetDevice(): TargetDevice { + return this.widgetConfig?.config?.targetDevice; + } + + get widgetType(): widgetType { + return this.widgetConfig?.widgetType; + } + + powerButtonLayouts = powerButtonLayouts; + + powerButtonLayoutTranslationMap = powerButtonLayoutTranslations; + powerButtonLayoutImageMap = powerButtonLayoutImages; + + valueType = ValueType; + + powerButtonWidgetSettingsForm: UntypedFormGroup; + + constructor(protected store: Store, + private fb: UntypedFormBuilder) { + super(store); + } + + protected settingsForm(): UntypedFormGroup { + return this.powerButtonWidgetSettingsForm; + } + + protected defaultSettings(): WidgetSettings { + return {...powerButtonDefaultSettings}; + } + + protected onSettingsSet(settings: WidgetSettings) { + this.powerButtonWidgetSettingsForm = this.fb.group({ + initialState: [settings.initialState, []], + onUpdateState: [settings.onUpdateState, []], + offUpdateState: [settings.offUpdateState, []], + disabledState: [settings.disabledState, []], + + layout: [settings.layout, []], + + mainColorOn: [settings.mainColorOn, []], + backgroundColorOn: [settings.backgroundColorOn, []], + + mainColorOff: [settings.mainColorOff, []], + backgroundColorOff: [settings.backgroundColorOff, []], + + mainColorDisabled: [settings.mainColorDisabled, []], + backgroundColorDisabled: [settings.backgroundColorDisabled, []], + + background: [settings.background, []] + }); + } +} diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/widget-settings.module.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/widget-settings.module.ts index 3f4a619c49..d3fe9dac3e 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/widget-settings.module.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/widget-settings.module.ts @@ -321,6 +321,9 @@ import { import { CommandButtonWidgetSettingsComponent } from '@home/components/widget/lib/settings/button/command-button-widget-settings.component'; +import { + PowerButtonWidgetSettingsComponent +} from '@home/components/widget/lib/settings/button/power-button-widget-settings.component'; @NgModule({ declarations: [ @@ -436,7 +439,8 @@ import { BarChartWithLabelsWidgetSettingsComponent, SingleSwitchWidgetSettingsComponent, ActionButtonWidgetSettingsComponent, - CommandButtonWidgetSettingsComponent + CommandButtonWidgetSettingsComponent, + PowerButtonWidgetSettingsComponent ], imports: [ CommonModule, @@ -557,7 +561,8 @@ import { BarChartWithLabelsWidgetSettingsComponent, SingleSwitchWidgetSettingsComponent, ActionButtonWidgetSettingsComponent, - CommandButtonWidgetSettingsComponent + CommandButtonWidgetSettingsComponent, + PowerButtonWidgetSettingsComponent ] }) export class WidgetSettingsModule { @@ -645,5 +650,6 @@ export const widgetSettingsComponentsMap: {[key: string]: Type + + + + + + + + + + + + + + + + + + + + + diff --git a/ui-ngx/src/assets/widget/power-button/default-volume-layout.svg b/ui-ngx/src/assets/widget/power-button/default-volume-layout.svg new file mode 100644 index 0000000000..9a502cc8f0 --- /dev/null +++ b/ui-ngx/src/assets/widget/power-button/default-volume-layout.svg @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ui-ngx/src/assets/widget/power-button/outlined-layout.svg b/ui-ngx/src/assets/widget/power-button/outlined-layout.svg new file mode 100644 index 0000000000..9510d68721 --- /dev/null +++ b/ui-ngx/src/assets/widget/power-button/outlined-layout.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ui-ngx/src/assets/widget/power-button/outlined-volume-layout.svg b/ui-ngx/src/assets/widget/power-button/outlined-volume-layout.svg new file mode 100644 index 0000000000..9e511892b3 --- /dev/null +++ b/ui-ngx/src/assets/widget/power-button/outlined-volume-layout.svg @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ui-ngx/src/assets/widget/power-button/simplified-layout.svg b/ui-ngx/src/assets/widget/power-button/simplified-layout.svg new file mode 100644 index 0000000000..eecb1e9cbe --- /dev/null +++ b/ui-ngx/src/assets/widget/power-button/simplified-layout.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/ui-ngx/src/assets/widget/power-button/simplified-volume-layout.svg b/ui-ngx/src/assets/widget/power-button/simplified-volume-layout.svg new file mode 100644 index 0000000000..500d9a0c97 --- /dev/null +++ b/ui-ngx/src/assets/widget/power-button/simplified-volume-layout.svg @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 753f502891b8d1cfddd7d14c639b09267639bf5f Mon Sep 17 00:00:00 2001 From: Igor Kulikov Date: Thu, 8 Feb 2024 19:57:47 +0200 Subject: [PATCH 178/179] UI: Update power button widget default settings. --- .../src/main/data/json/system/widget_types/power_button.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/application/src/main/data/json/system/widget_types/power_button.json b/application/src/main/data/json/system/widget_types/power_button.json index 2f825c9e74..d90439d82f 100644 --- a/application/src/main/data/json/system/widget_types/power_button.json +++ b/application/src/main/data/json/system/widget_types/power_button.json @@ -17,7 +17,7 @@ "settingsDirective": "tb-power-button-widget-settings", "hasBasicMode": true, "basicModeDirective": "tb-power-button-basic-config", - "defaultConfig": "{\"showTitle\":true,\"backgroundColor\":\"#ffffff\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"0px\",\"settings\":{\"initialState\":{\"action\":\"EXECUTE_RPC\",\"defaultValue\":false,\"executeRpc\":{\"method\":\"getState\",\"requestTimeout\":5000,\"requestPersistent\":false,\"persistentPollingInterval\":1000},\"getAttribute\":{\"key\":\"state\",\"scope\":null},\"getTimeSeries\":{\"key\":\"state\"},\"dataToValue\":{\"type\":\"NONE\",\"compareToValue\":true,\"dataToValueFunction\":\"/* Should return boolean value */\\nreturn data;\"}},\"onUpdateState\":{\"action\":\"EXECUTE_RPC\",\"executeRpc\":{\"method\":\"setState\",\"requestTimeout\":5000,\"requestPersistent\":false,\"persistentPollingInterval\":1000},\"setAttribute\":{\"key\":\"state\",\"scope\":\"SHARED_SCOPE\"},\"putTimeSeries\":{\"key\":\"state\"},\"valueToData\":{\"type\":\"CONSTANT\",\"constantValue\":true,\"valueToDataFunction\":\"/* Convert input boolean value to RPC parameters or attribute/time-series value */\\nreturn value;\"}},\"offUpdateState\":{\"action\":\"EXECUTE_RPC\",\"executeRpc\":{\"method\":\"setState\",\"requestTimeout\":5000,\"requestPersistent\":false,\"persistentPollingInterval\":1000},\"setAttribute\":{\"key\":\"state\",\"scope\":\"SHARED_SCOPE\"},\"putTimeSeries\":{\"key\":\"state\"},\"valueToData\":{\"type\":\"CONSTANT\",\"constantValue\":false,\"valueToDataFunction\":\"/* Convert input boolean value to RPC parameters or attribute/time-series value */ \\n return value;\"}},\"disabledState\":{\"action\":\"DO_NOTHING\",\"defaultValue\":false,\"getAttribute\":{\"key\":\"state\",\"scope\":null},\"getTimeSeries\":{\"key\":\"state\"},\"dataToValue\":{\"type\":\"NONE\",\"compareToValue\":true,\"dataToValueFunction\":\"/* Should return boolean value */\\nreturn data;\"}},\"layout\":\"default\",\"mainColorOn\":\"#3F52DD\",\"backgroundColorOn\":\"#FFFFFF\",\"mainColorOff\":\"#A2A2A2\",\"backgroundColorOff\":\"#FFFFFF\",\"mainColorDisabled\":\"rgba(0,0,0,0.12)\",\"backgroundColorDisabled\":\"#FFFFFF\",\"background\":{\"type\":\"color\",\"color\":\"#fff\",\"overlay\":{\"enabled\":false,\"color\":\"rgba(255,255,255,0.72)\",\"blur\":3}}},\"title\":\"Power\",\"dropShadow\":true,\"enableFullscreen\":false,\"widgetStyle\":{},\"actions\":{},\"widgetCss\":\"\",\"noDataDisplayMessage\":\"\",\"titleFont\":{\"size\":16,\"sizeUnit\":\"px\",\"family\":\"Roboto\",\"weight\":\"500\",\"style\":null,\"lineHeight\":\"1.6\"},\"showTitleIcon\":false,\"titleTooltip\":\"\",\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"pageSize\":1024,\"titleIcon\":\"mdi:lightbulb-outline\",\"iconColor\":\"rgba(0, 0, 0, 0.87)\",\"iconSize\":\"24px\",\"configMode\":\"basic\",\"targetDevice\":null,\"titleColor\":null,\"borderRadius\":null}" + "defaultConfig": "{\"showTitle\":true,\"backgroundColor\":\"#ffffff\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"0px\",\"settings\":{},\"title\":\"Power\",\"dropShadow\":true,\"enableFullscreen\":false,\"widgetStyle\":{},\"actions\":{},\"widgetCss\":\"\",\"noDataDisplayMessage\":\"\",\"titleFont\":{\"size\":16,\"sizeUnit\":\"px\",\"family\":\"Roboto\",\"weight\":\"500\",\"style\":null,\"lineHeight\":\"1.6\"},\"showTitleIcon\":false,\"titleTooltip\":\"\",\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"pageSize\":1024,\"titleIcon\":\"mdi:lightbulb-outline\",\"iconColor\":\"rgba(0, 0, 0, 0.87)\",\"iconSize\":\"24px\",\"configMode\":\"basic\",\"targetDevice\":null,\"titleColor\":null,\"borderRadius\":null}" }, "tags": [ "command", From 6943ead99de9e43e19dcc549a77c82e51247c94a Mon Sep 17 00:00:00 2001 From: Igor Kulikov Date: Fri, 9 Feb 2024 19:32:58 +0200 Subject: [PATCH 179/179] UI: Power button widget pressed state improvements. --- ui-ngx/package.json | 1 + .../rpc/power-button-widget.component.scss | 4 +- .../lib/rpc/power-button-widget.component.ts | 3 + .../lib/rpc/power-button-widget.models.ts | 213 +++++++++++------- ui-ngx/yarn.lock | 9 +- 5 files changed, 141 insertions(+), 89 deletions(-) diff --git a/ui-ngx/package.json b/ui-ngx/package.json index 4bbe817fcf..ab60ebd525 100644 --- a/ui-ngx/package.json +++ b/ui-ngx/package.json @@ -44,6 +44,7 @@ "@ngrx/store-devtools": "^15.4.0", "@ngx-translate/core": "^14.0.0", "@ngx-translate/http-loader": "^7.0.0", + "@svgdotjs/svg.filter.js": "^3.0.8", "@svgdotjs/svg.js": "^3.2.0", "@tinymce/tinymce-angular": "^7.0.0", "ace-builds": "1.4.13", diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/rpc/power-button-widget.component.scss b/ui-ngx/src/app/modules/home/components/widget/lib/rpc/power-button-widget.component.scss index e0192630f9..d65341a7ba 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/rpc/power-button-widget.component.scss +++ b/ui-ngx/src/app/modules/home/components/widget/lib/rpc/power-button-widget.component.scss @@ -46,10 +46,10 @@ justify-content: center; svg { .tb-small-shadow { - filter: drop-shadow(0px 4px 6px rgba(0, 0, 0, 0.08)); + filter: drop-shadow(0px 0px 4px rgba(0, 0, 0, 0.2)); } .tb-shadow { - filter: drop-shadow(8px 8px 8px rgba(0, 0, 0, 0.1)); + filter: drop-shadow(0px 0px 10px rgba(0, 0, 0, 0.15)); } } &.tb-power-button-pointer { diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/rpc/power-button-widget.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/rpc/power-button-widget.component.ts index e68a2e4baa..02c58b3e9a 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/rpc/power-button-widget.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/rpc/power-button-widget.component.ts @@ -105,6 +105,7 @@ export class PowerButtonWidgetComponent extends this.loading$.subscribe((loading) => { this.updateDisabledState(loading || this.disabled); + this.cd.markForCheck(); }); } @@ -139,6 +140,7 @@ export class PowerButtonWidgetComponent extends if (this.value !== newValue) { this.value = newValue; this.powerButtonSvgShape?.setValue(this.value); + this.cd.markForCheck(); } } @@ -147,6 +149,7 @@ export class PowerButtonWidgetComponent extends if (this.disabled !== newDisabled) { this.disabled = newDisabled; this.updateDisabledState(this.disabled); + this.cd.markForCheck(); } } diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/rpc/power-button-widget.models.ts b/ui-ngx/src/app/modules/home/components/widget/lib/rpc/power-button-widget.models.ts index b1372a9660..2e8ca0de6d 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/rpc/power-button-widget.models.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/rpc/power-button-widget.models.ts @@ -24,7 +24,8 @@ import { SetValueSettings, ValueToDataType } from '@shared/models/action-widget-settings.models'; -import { Circle, Element, G, Gradient, Runner, Stop, Svg, Text, Timeline } from '@svgdotjs/svg.js'; +import { Circle, Effect, Element, G, Gradient, Runner, Svg, Text, Timeline } from '@svgdotjs/svg.js'; +import '@svgdotjs/svg.filter.js'; import tinycolor from 'tinycolor2'; import { WidgetContext } from '@home/models/widget-component.models'; @@ -216,6 +217,8 @@ export const powerButtonShapeSize = 110; const cx = powerButtonShapeSize / 2; const cy = powerButtonShapeSize / 2; +const powerButtonAnimation = (element: Element): Runner => element.animate(200, 0, 'now'); + export abstract class PowerButtonShape { static fromSettings(ctx: WidgetContext, @@ -398,20 +401,6 @@ export abstract class PowerButtonShape { shape.maskWith(mask); } - protected createPressedShadow(diameter: number, rightElseLeft = true): Gradient { - const innerShadowGradient = this.svgShape.gradient('radial', (add) => { - add.stop(0.7, '#000000', 0); - add.stop(1, '#000000', 0.4); - }).attr({ cx: rightElseLeft ? '45%' : '55%', cy: '55%', r: '100%'}); - this.svgShape.circle(diameter).center(cx, cy) - .fill(innerShadowGradient).stroke({width: 0}); - return innerShadowGradient; - } - - protected pressedAnimation(element: Element): Runner { - return element.animate(200, 0, 'now'); - } - protected createOnLabel(fontWeight = '500'): Text { return this.createLabel(this.onLabel, fontWeight); } @@ -431,6 +420,72 @@ export abstract class PowerButtonShape { } +class InnerShadowCircle { + + private shadowCircle: Circle; + private blurEffect: Effect; + private offsetEffect: Effect; + private floodEffect: Effect; + + constructor(private svgShape: Svg, + private diameter: number, + private centerX: number, + private centerY: number, + private blur = 6, + private shadowOpacity = 0.6, + private dx = 0, + private dy = 0, + private shadowColor = '#000') { + + this.shadowCircle = this.svgShape.circle(this.diameter).center(this.centerX, this.centerY) + .fill({color: '#fff', opacity: 1}).stroke({width: 0}); + + this.shadowCircle.filterWith(add => { + add.x('-50%').y('-50%').width('200%').height('200%'); + let effect: Effect = add.componentTransfer(components => { + components.funcA({ type: 'table', tableValues: '1 0' }); + }).in(add.$fill); + effect = effect.gaussianBlur(this.blur, this.blur).attr({stdDeviation: this.blur}); + this.blurEffect = effect; + effect = effect.offset(this.dx, this.dy); + this.offsetEffect = effect; + effect = effect.flood(this.shadowColor, this.shadowOpacity); + this.floodEffect = effect; + effect = effect.composite(this.offsetEffect, 'in'); + effect.composite(add.$sourceAlpha, 'in'); + add.merge(m => { + m.mergeNode(add.$fill); + m.mergeNode(); + }); + }); + } + + public timeline(tl: Timeline): void { + this.blurEffect.timeline(tl); + this.offsetEffect.timeline(tl); + this.floodEffect.timeline(tl); + } + + public animate(blur: number, opacity: number, dx = 0, dy = 0): Runner { + powerButtonAnimation(this.blurEffect).attr({stdDeviation: blur}); + powerButtonAnimation(this.offsetEffect).attr({dx, dy}); + return powerButtonAnimation(this.floodEffect).attr({'flood-opacity': opacity}); + } + + public animateRestore(): Runner { + return this.animate(this.blur, this.shadowOpacity, this.dx, this.dy); + } + + public show(): void { + this.shadowCircle.show(); + } + + public hide(): void { + this.shadowCircle.hide(); + } + +} + class DefaultPowerButtonShape extends PowerButtonShape { private outerBorder: Circle; @@ -438,7 +493,7 @@ class DefaultPowerButtonShape extends PowerButtonShape { private offLabelShape: Text; private onCircleShape: Circle; private onLabelShape: Text; - private pressedShadow: Gradient; + private pressedShadow: InnerShadowCircle; private pressedTimeline: Timeline; private centerGroup: G; @@ -453,7 +508,7 @@ class DefaultPowerButtonShape extends PowerButtonShape { .center(cx, cy); this.onLabelShape = this.createOnLabel(); this.createMask(this.onCircleShape, [this.onLabelShape]); - this.pressedShadow = this.createPressedShadow(powerButtonShapeSize - 20); + this.pressedShadow = new InnerShadowCircle(this.svgShape, powerButtonShapeSize - 20, cx, cy, 0, 0); this.pressedTimeline = new Timeline(); this.centerGroup.timeline(this.pressedTimeline); @@ -482,16 +537,16 @@ class DefaultPowerButtonShape extends PowerButtonShape { protected onPressStart() { this.pressedTimeline.finish(); const pressedScale = 0.75; - this.pressedAnimation(this.centerGroup).transform({scale: pressedScale}); - this.pressedAnimation(this.onLabelShape).transform({scale: pressedScale}); - this.pressedAnimation(this.pressedShadow).attr({r: '62%'}); + powerButtonAnimation(this.centerGroup).transform({scale: pressedScale}); + powerButtonAnimation(this.onLabelShape).transform({scale: pressedScale}); + this.pressedShadow.animate(6, 0.6); } protected onPressEnd() { this.pressedTimeline.finish(); - this.pressedAnimation(this.centerGroup).transform({scale: 1}); - this.pressedAnimation(this.onLabelShape).transform({scale: 1}); - this.pressedAnimation(this.pressedShadow).attr({r: '100%'}); + powerButtonAnimation(this.centerGroup).transform({scale: 1}); + powerButtonAnimation(this.onLabelShape).transform({scale: 1}); + this.pressedShadow.animateRestore(); } } @@ -503,7 +558,7 @@ class SimplifiedPowerButtonShape extends PowerButtonShape { private onCircleShape: Circle; private offLabelShape: Text; private onLabelShape: Text; - private pressedShadow: Gradient; + private pressedShadow: InnerShadowCircle; private pressedTimeline: Timeline; private centerGroup: G; @@ -517,7 +572,7 @@ class SimplifiedPowerButtonShape extends PowerButtonShape { this.onCircleShape = this.svgShape.circle(powerButtonShapeSize).center(cx, cy); this.onLabelShape = this.createOnLabel(); this.createMask(this.onCircleShape, [this.onLabelShape]); - this.pressedShadow = this.createPressedShadow(powerButtonShapeSize - 4); + this.pressedShadow = new InnerShadowCircle(this.svgShape, powerButtonShapeSize - 4, cx, cy, 0, 0); this.pressedTimeline = new Timeline(); this.centerGroup.timeline(this.pressedTimeline); @@ -546,16 +601,16 @@ class SimplifiedPowerButtonShape extends PowerButtonShape { protected onPressStart() { this.pressedTimeline.finish(); const pressedScale = 0.75; - this.pressedAnimation(this.centerGroup).transform({scale: pressedScale}); - this.pressedAnimation(this.onLabelShape).transform({scale: pressedScale}); - this.pressedAnimation(this.pressedShadow).attr({r: '62%'}); + powerButtonAnimation(this.centerGroup).transform({scale: pressedScale}); + powerButtonAnimation(this.onLabelShape).transform({scale: pressedScale}); + this.pressedShadow.animate(6, 0.6); } protected onPressEnd() { this.pressedTimeline.finish(); - this.pressedAnimation(this.centerGroup).transform({scale: 1}); - this.pressedAnimation(this.onLabelShape).transform({scale: 1}); - this.pressedAnimation(this.pressedShadow).attr({r: '100%'}); + powerButtonAnimation(this.centerGroup).transform({scale: 1}); + powerButtonAnimation(this.onLabelShape).transform({scale: 1}); + this.pressedShadow.animateRestore(); } } @@ -567,7 +622,7 @@ class OutlinedPowerButtonShape extends PowerButtonShape { private offLabelShape: Text; private onCircleShape: Circle; private onLabelShape: Text; - private pressedShadow: Gradient; + private pressedShadow: InnerShadowCircle; private pressedTimeline: Timeline; private centerGroup: G; private onCenterGroup: G; @@ -588,7 +643,7 @@ class OutlinedPowerButtonShape extends PowerButtonShape { .addTo(this.onCenterGroup); this.onLabelShape = this.createOnLabel(); this.createMask(this.onCircleShape, [this.onLabelShape]); - this.pressedShadow = this.createPressedShadow(powerButtonShapeSize - 24); + this.pressedShadow = new InnerShadowCircle(this.svgShape, powerButtonShapeSize - 24, cx, cy, 0, 0); this.pressedTimeline = new Timeline(); this.centerGroup.timeline(this.pressedTimeline); @@ -617,18 +672,18 @@ class OutlinedPowerButtonShape extends PowerButtonShape { protected onPressStart() { this.pressedTimeline.finish(); const pressedScale = 0.75; - this.pressedAnimation(this.centerGroup).transform({scale: pressedScale}); - this.pressedAnimation(this.onCenterGroup).transform({scale: 0.98}); - this.pressedAnimation(this.onLabelShape).transform({scale: pressedScale / 0.98}); - this.pressedAnimation(this.pressedShadow).attr({r: '62%'}); + powerButtonAnimation(this.centerGroup).transform({scale: pressedScale}); + powerButtonAnimation(this.onCenterGroup).transform({scale: 0.98}); + powerButtonAnimation(this.onLabelShape).transform({scale: pressedScale / 0.98}); + this.pressedShadow.animate(6, 0.6); } protected onPressEnd() { this.pressedTimeline.finish(); - this.pressedAnimation(this.centerGroup).transform({scale: 1}); - this.pressedAnimation(this.onCenterGroup).transform({scale: 1}); - this.pressedAnimation(this.onLabelShape).transform({scale: 1}); - this.pressedAnimation(this.pressedShadow).attr({r: '100%'}); + powerButtonAnimation(this.centerGroup).transform({scale: 1}); + powerButtonAnimation(this.onCenterGroup).transform({scale: 1}); + powerButtonAnimation(this.onLabelShape).transform({scale: 1}); + this.pressedShadow.animateRestore(); } } @@ -639,9 +694,9 @@ class DefaultVolumePowerButtonShape extends PowerButtonShape { private innerBorder: Circle; private innerBorderMask: Circle; private innerBorderGradient: Gradient; - private innerShadow: Circle; - private innerShadowGradient: Gradient; - private innerShadowGradientStop: Stop; + private innerShadow: InnerShadowCircle; + //private innerShadowGradient: Gradient; + //private innerShadowGradientStop: Stop; private offLabelShape: Text; private onCircleShape: Circle; private onLabelShape: Text; @@ -670,18 +725,12 @@ class DefaultVolumePowerButtonShape extends PowerButtonShape { this.onCircleShape = this.svgShape.circle(powerButtonShapeSize - 24).center(cx, cy); this.onLabelShape = this.createOnLabel('400'); this.createMask(this.onCircleShape, [this.onLabelShape]); - this.innerShadow = this.svgShape.circle(powerButtonShapeSize - 24).center(cx, cy); - this.innerShadowGradient = this.svgShape.gradient('radial', (add) => { - add.stop(0.7, '#000000', 0); - this.innerShadowGradientStop = add.stop(1, '#000000', 0.2); - }).attr({ cx: '45%', cy: '55%', r: '65%'}); - this.innerShadow.fill(this.innerShadowGradient); + this.innerShadow = new InnerShadowCircle(this.svgShape, powerButtonShapeSize - 24, cx, cy, 3, 0.3); this.pressedTimeline = new Timeline(); this.centerGroup.timeline(this.pressedTimeline); this.onLabelShape.timeline(this.pressedTimeline); - this.innerShadowGradient.timeline(this.pressedTimeline); - this.innerShadowGradientStop.timeline(this.pressedTimeline); + this.innerShadow.timeline(this.pressedTimeline); } protected drawColorState(mainColor: PowerButtonColor){ @@ -724,22 +773,20 @@ class DefaultVolumePowerButtonShape extends PowerButtonShape { this.pressedTimeline.finish(); this.innerShadow.show(); const pressedScale = 0.75; - this.pressedAnimation(this.centerGroup).transform({scale: pressedScale}); - this.pressedAnimation(this.onLabelShape).transform({scale: pressedScale}); - this.pressedAnimation(this.innerShadowGradient).attr({ r: '60%'}); - this.pressedAnimation(this.innerShadowGradientStop).update({ opacity: 0.4 }); + powerButtonAnimation(this.centerGroup).transform({scale: pressedScale}); + powerButtonAnimation(this.onLabelShape).transform({scale: pressedScale}); + this.innerShadow.animate(6, 0.6); } protected onPressEnd() { this.pressedTimeline.finish(); - this.pressedAnimation(this.centerGroup).transform({scale: 1}); - this.pressedAnimation(this.onLabelShape).transform({scale: 1}); - this.pressedAnimation(this.innerShadowGradient).attr({ r: '65%'}).after(() => { + powerButtonAnimation(this.centerGroup).transform({scale: 1}); + powerButtonAnimation(this.onLabelShape).transform({scale: 1}); + this.innerShadow.animateRestore().after(() => { if (this.disabled) { this.innerShadow.hide(); } }); - this.pressedAnimation(this.innerShadowGradientStop).update({ opacity: 0.2 }); } } @@ -750,8 +797,8 @@ class SimplifiedVolumePowerButtonShape extends PowerButtonShape { private outerBorderMask: Circle; private offLabelShape: Text; private onLabelShape: Text; - private innerShadow: Circle; - private pressedShadow: Gradient; + private innerShadow: InnerShadowCircle; + private pressedShadow: InnerShadowCircle; private pressedTimeline: Timeline; private centerGroup: G; private onCenterGroup: G; @@ -766,14 +813,8 @@ class SimplifiedVolumePowerButtonShape extends PowerButtonShape { this.offLabelShape = this.createOffLabel().addTo(this.centerGroup); this.onCenterGroup = this.svgShape.group(); this.onLabelShape = this.createOnLabel().addTo(this.onCenterGroup); - this.innerShadow = this.svgShape.circle(powerButtonShapeSize - 4).center(cx, cy); - const innerShadowGradient = this.svgShape.gradient('radial', (add) => { - add.stop(0.7, '#000000', 0); - add.stop(1, '#000000', 0.2); - }).attr({ cx: '55%', cy: '55%', r: '65%'}); - this.innerShadow.fill(innerShadowGradient); - this.pressedShadow = this.createPressedShadow(powerButtonShapeSize - 4, false); - + this.innerShadow = new InnerShadowCircle(this.svgShape, powerButtonShapeSize - 4, cx, cy, 3, 0.3); + this.pressedShadow = new InnerShadowCircle(this.svgShape, powerButtonShapeSize - 4, cx, cy, 0, 0); this.pressedTimeline = new Timeline(); this.centerGroup.timeline(this.pressedTimeline); this.onCenterGroup.timeline(this.pressedTimeline); @@ -807,16 +848,16 @@ class SimplifiedVolumePowerButtonShape extends PowerButtonShape { if (!this.value) { this.backgroundShape.removeClass('tb-shadow'); } - this.pressedAnimation(this.centerGroup).transform({scale: pressedScale}); - this.pressedAnimation(this.onCenterGroup).transform({scale: pressedScale}); - this.pressedAnimation(this.pressedShadow).attr({r: '62%'}); + powerButtonAnimation(this.centerGroup).transform({scale: pressedScale}); + powerButtonAnimation(this.onCenterGroup).transform({scale: pressedScale}); + this.pressedShadow.animate(8, 0.4); } protected onPressEnd() { this.pressedTimeline.finish(); - this.pressedAnimation(this.centerGroup).transform({scale: 1}); - this.pressedAnimation(this.onCenterGroup).transform({scale: 1}); - this.pressedAnimation(this.pressedShadow).attr({r: '100%'}).after(() => { + powerButtonAnimation(this.centerGroup).transform({scale: 1}); + powerButtonAnimation(this.onCenterGroup).transform({scale: 1}); + this.pressedShadow.animateRestore().after(() => { if (!this.value) { this.backgroundShape.addClass('tb-shadow'); } @@ -833,7 +874,7 @@ class OutlinedVolumePowerButtonShape extends PowerButtonShape { private offLabelShape: Text; private onCircleShape: Circle; private onLabelShape: Text; - private pressedShadow: Gradient; + private pressedShadow: InnerShadowCircle; private pressedTimeline: Timeline; private centerGroup: G; private onCenterGroup: G; @@ -858,7 +899,7 @@ class OutlinedVolumePowerButtonShape extends PowerButtonShape { .addTo(this.onCenterGroup); this.onLabelShape = this.createOnLabel('800'); this.createMask(this.onCircleShape, [this.onLabelShape]); - this.pressedShadow = this.createPressedShadow(powerButtonShapeSize - 30); + this.pressedShadow = new InnerShadowCircle(this.svgShape, powerButtonShapeSize - 30, cx, cy, 0, 0); this.backgroundShape.addClass('tb-small-shadow'); this.pressedTimeline = new Timeline(); @@ -895,18 +936,18 @@ class OutlinedVolumePowerButtonShape extends PowerButtonShape { protected onPressStart() { this.pressedTimeline.finish(); const pressedScale = 0.75; - this.pressedAnimation(this.centerGroup).transform({scale: pressedScale}); - this.pressedAnimation(this.onCenterGroup).transform({scale: 0.98}); - this.pressedAnimation(this.onLabelShape).transform({scale: pressedScale / 0.98}); - this.pressedAnimation(this.pressedShadow).attr({r: '62%'}); + powerButtonAnimation(this.centerGroup).transform({scale: pressedScale}); + powerButtonAnimation(this.onCenterGroup).transform({scale: 0.98}); + powerButtonAnimation(this.onLabelShape).transform({scale: pressedScale / 0.98}); + this.pressedShadow.animate(6, 0.6); } protected onPressEnd() { this.pressedTimeline.finish(); - this.pressedAnimation(this.centerGroup).transform({scale: 1}); - this.pressedAnimation(this.onCenterGroup).transform({scale: 1}); - this.pressedAnimation(this.onLabelShape).transform({scale: 1}); - this.pressedAnimation(this.pressedShadow).attr({r: '100%'}); + powerButtonAnimation(this.centerGroup).transform({scale: 1}); + powerButtonAnimation(this.onCenterGroup).transform({scale: 1}); + powerButtonAnimation(this.onLabelShape).transform({scale: 1}); + this.pressedShadow.animateRestore(); } } diff --git a/ui-ngx/yarn.lock b/ui-ngx/yarn.lock index 2c60a7f009..d78a9a52d6 100644 --- a/ui-ngx/yarn.lock +++ b/ui-ngx/yarn.lock @@ -2747,7 +2747,14 @@ resolved "https://registry.yarnpkg.com/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz#96116f2a912e0c02817345b3c10751069920d553" integrity sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg== -"@svgdotjs/svg.js@^3.2.0": +"@svgdotjs/svg.filter.js@^3.0.8": + version "3.0.8" + resolved "https://registry.yarnpkg.com/@svgdotjs/svg.filter.js/-/svg.filter.js-3.0.8.tgz#998cb2481a871fa70d7dbaa891c886b335c562d7" + integrity sha512-YshF2YDaeRA2StyzAs5nUPrev7npQ38oWD0eTRwnsciSL2KrRPMoUw8BzjIXItb3+dccKGTX3IQOd2NFzmHkog== + dependencies: + "@svgdotjs/svg.js" "^3.1.1" + +"@svgdotjs/svg.js@^3.1.1", "@svgdotjs/svg.js@^3.2.0": version "3.2.0" resolved "https://registry.yarnpkg.com/@svgdotjs/svg.js/-/svg.js-3.2.0.tgz#6baa8cef6778a93818ac18faa2055222e60aa644" integrity sha512-Tr8p+QVP7y+QT1GBlq1Tt57IvedVH8zCPoYxdHLX0Oof3a/PqnC/tXAkVufv1JQJfsDHlH/UrjcDfgxSofqSNA==