diff --git a/application/pom.xml b/application/pom.xml index 7f11d0dcc3..0e65c7683e 100644 --- a/application/pom.xml +++ b/application/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 2.0.3 + 2.1.0-SNAPSHOT thingsboard application diff --git a/application/src/main/conf/thingsboard.conf b/application/src/main/conf/thingsboard.conf index a569549aef..2a80158748 100644 --- a/application/src/main/conf/thingsboard.conf +++ b/application/src/main/conf/thingsboard.conf @@ -15,7 +15,7 @@ # export JAVA_OPTS="$JAVA_OPTS -Dplatform=@pkg.platform@ -Dinstall.data_dir=@pkg.installFolder@/data" -export JAVA_OPTS="$JAVA_OPTS -Xloggc:@pkg.logFolder@/gc.log -XX:+HeapDumpOnOutOfMemoryError -XX:+PrintGCDetails -XX:+PrintGCDateStamps" +export JAVA_OPTS="$JAVA_OPTS -Xloggc:@pkg.logFolder@/gc.log -XX:+IgnoreUnrecognizedVMOptions -XX:+HeapDumpOnOutOfMemoryError -XX:+PrintGCDetails -XX:+PrintGCDateStamps" export JAVA_OPTS="$JAVA_OPTS -XX:+PrintHeapAtGC -XX:+PrintTenuringDistribution -XX:+PrintGCApplicationStoppedTime -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10" export JAVA_OPTS="$JAVA_OPTS -XX:GCLogFileSize=10M -XX:-UseBiasedLocking -XX:+UseTLAB -XX:+ResizeTLAB -XX:+PerfDisableSharedMem -XX:+UseCondCardMark" export JAVA_OPTS="$JAVA_OPTS -XX:CMSWaitDuration=10000 -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:+CMSParallelRemarkEnabled -XX:+CMSParallelInitialMarkEnabled" diff --git a/application/src/main/java/org/thingsboard/server/actors/app/AppActor.java b/application/src/main/java/org/thingsboard/server/actors/app/AppActor.java index d453e594ba..8e7a9ae7e1 100644 --- a/application/src/main/java/org/thingsboard/server/actors/app/AppActor.java +++ b/application/src/main/java/org/thingsboard/server/actors/app/AppActor.java @@ -111,6 +111,7 @@ public class AppActor extends RuleChainManagerActor { case DEVICE_NAME_OR_TYPE_UPDATE_TO_DEVICE_ACTOR_MSG: case DEVICE_RPC_REQUEST_TO_DEVICE_ACTOR_MSG: case SERVER_RPC_RESPONSE_TO_DEVICE_ACTOR_MSG: + case REMOTE_TO_RULE_CHAIN_TELL_NEXT_MSG: onToDeviceActorMsg((TenantAwareMsg) msg); break; case ACTOR_SYSTEM_TO_DEVICE_SESSION_ACTOR_MSG: diff --git a/application/src/main/java/org/thingsboard/server/actors/rpc/RpcManagerActor.java b/application/src/main/java/org/thingsboard/server/actors/rpc/RpcManagerActor.java index 3f3f70b424..9e38c17aff 100644 --- a/application/src/main/java/org/thingsboard/server/actors/rpc/RpcManagerActor.java +++ b/application/src/main/java/org/thingsboard/server/actors/rpc/RpcManagerActor.java @@ -29,11 +29,7 @@ import org.thingsboard.server.common.msg.cluster.ServerAddress; import org.thingsboard.server.gen.cluster.ClusterAPIProtos; import org.thingsboard.server.service.cluster.discovery.ServerInstance; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.Map; -import java.util.Queue; -import java.util.UUID; +import java.util.*; /** * @author Andrew Shvayka @@ -88,7 +84,17 @@ public class RpcManagerActor extends ContextAwareActor { private void onMsg(RpcBroadcastMsg msg) { log.debug("Forwarding msg to session actors {}", msg); - sessionActors.keySet().forEach(address -> onMsg(msg.getMsg())); + sessionActors.keySet().forEach(address -> { + ClusterAPIProtos.ClusterMessage msgWithServerAddress = msg.getMsg() + .toBuilder() + .setServerAddress(ClusterAPIProtos.ServerAddress + .newBuilder() + .setHost(address.getHost()) + .setPort(address.getPort()) + .build()) + .build(); + onMsg(msgWithServerAddress); + }); pendingMsgs.values().forEach(queue -> queue.add(msg.getMsg())); } diff --git a/application/src/main/java/org/thingsboard/server/actors/ruleChain/RemoteToRuleChainTellNextMsg.java b/application/src/main/java/org/thingsboard/server/actors/ruleChain/RemoteToRuleChainTellNextMsg.java new file mode 100644 index 0000000000..fe0c2efae1 --- /dev/null +++ b/application/src/main/java/org/thingsboard/server/actors/ruleChain/RemoteToRuleChainTellNextMsg.java @@ -0,0 +1,48 @@ +/** + * Copyright © 2016-2018 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.actors.ruleChain; + +import lombok.Data; +import org.thingsboard.server.common.data.id.RuleChainId; +import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.common.msg.MsgType; +import org.thingsboard.server.common.msg.aware.RuleChainAwareMsg; +import org.thingsboard.server.common.msg.aware.TenantAwareMsg; + +import java.io.Serializable; + +/** + * Created by ashvayka on 19.03.18. + */ +@Data +final class RemoteToRuleChainTellNextMsg extends RuleNodeToRuleChainTellNextMsg implements TenantAwareMsg, RuleChainAwareMsg, Serializable { + + private static final long serialVersionUID = 2459605482321657447L; + private final TenantId tenantId; + private final RuleChainId ruleChainId; + + public RemoteToRuleChainTellNextMsg(RuleNodeToRuleChainTellNextMsg original, TenantId tenantId, RuleChainId ruleChainId) { + super(original.getOriginator(), original.getRelationTypes(), original.getMsg()); + this.tenantId = tenantId; + this.ruleChainId = ruleChainId; + } + + @Override + public MsgType getMsgType() { + return MsgType.REMOTE_TO_RULE_CHAIN_TELL_NEXT_MSG; + } + +} diff --git a/application/src/main/java/org/thingsboard/server/actors/ruleChain/RuleChainActor.java b/application/src/main/java/org/thingsboard/server/actors/ruleChain/RuleChainActor.java index 3ba646aaf8..c1a55fbdad 100644 --- a/application/src/main/java/org/thingsboard/server/actors/ruleChain/RuleChainActor.java +++ b/application/src/main/java/org/thingsboard/server/actors/ruleChain/RuleChainActor.java @@ -49,6 +49,7 @@ public class RuleChainActor extends ComponentActor relations = nodeRoutes.get(originator).stream() - .filter(r -> contains(envelope.getRelationTypes(), r.getType())) - .collect(Collectors.toList()); + TbMsg msg = envelope.getMsg(); + EntityId originatorEntityId = msg.getOriginator(); + Optional address = systemContext.getRoutingService().resolveById(originatorEntityId); + + if (address.isPresent()) { + onRemoteTellNext(address.get(), envelope); + } else { + onLocalTellNext(envelope); + } + } + + private void onRemoteTellNext(ServerAddress serverAddress, RuleNodeToRuleChainTellNextMsg envelope) { + TbMsg msg = envelope.getMsg(); + logger.debug("Forwarding [{}] msg to remote server [{}] due to changed originator id: [{}]", msg.getId(), serverAddress, msg.getOriginator()); + envelope = new RemoteToRuleChainTellNextMsg(envelope, tenantId, entityId); + systemContext.getRpcService().tell(systemContext.getEncodingService().convertToProtoDataMessage(serverAddress, envelope)); + } + private void onLocalTellNext(RuleNodeToRuleChainTellNextMsg envelope) { TbMsg msg = envelope.getMsg(); + RuleNodeId originatorNodeId = envelope.getOriginator(); + List relations = nodeRoutes.get(originatorNodeId).stream() + .filter(r -> contains(envelope.getRelationTypes(), r.getType())) + .collect(Collectors.toList()); int relationsCount = relations.size(); EntityId ackId = msg.getRuleNodeId() != null ? msg.getRuleNodeId() : msg.getRuleChainId(); if (relationsCount == 0) { - queue.ack(tenantId, msg, ackId.getId(), msg.getClusterPartition()); + if (ackId != null) { + queue.ack(tenantId, msg, ackId.getId(), msg.getClusterPartition()); + } } else if (relationsCount == 1) { for (RuleNodeRelation relation : relations) { pushToTarget(msg, relation.getOut(), relation.getType()); @@ -244,7 +268,9 @@ public class RuleChainActorMessageProcessor extends ComponentMsgProcessor relationTypes; diff --git a/application/src/main/java/org/thingsboard/server/actors/tenant/TenantActor.java b/application/src/main/java/org/thingsboard/server/actors/tenant/TenantActor.java index 7a3127dd36..b4ab0d2cb2 100644 --- a/application/src/main/java/org/thingsboard/server/actors/tenant/TenantActor.java +++ b/application/src/main/java/org/thingsboard/server/actors/tenant/TenantActor.java @@ -35,6 +35,7 @@ import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.rule.RuleChain; import org.thingsboard.server.common.msg.TbActorMsg; import org.thingsboard.server.common.msg.aware.DeviceAwareMsg; +import org.thingsboard.server.common.msg.aware.RuleChainAwareMsg; import org.thingsboard.server.common.msg.plugin.ComponentLifecycleMsg; import org.thingsboard.server.common.msg.system.ServiceToRuleEngineMsg; import scala.concurrent.duration.Duration; @@ -94,7 +95,8 @@ public class TenantActor extends RuleChainManagerActor { onToDeviceActorMsg((DeviceAwareMsg) msg); break; case RULE_CHAIN_TO_RULE_CHAIN_MSG: - onRuleChainMsg((RuleChainToRuleChainMsg) msg); + case REMOTE_TO_RULE_CHAIN_TELL_NEXT_MSG: + onRuleChainMsg((RuleChainAwareMsg) msg); break; default: return false; @@ -109,15 +111,19 @@ public class TenantActor extends RuleChainManagerActor { } private void onServiceToRuleEngineMsg(ServiceToRuleEngineMsg msg) { + if (ruleChainManager.getRootChainActor()!=null) ruleChainManager.getRootChainActor().tell(msg, self()); + else logger.info("[{}] No Root Chain", msg); } private void onDeviceActorToRuleEngineMsg(DeviceActorToRuleEngineMsg msg) { + if (ruleChainManager.getRootChainActor()!=null) ruleChainManager.getRootChainActor().tell(msg, self()); + else logger.info("[{}] No Root Chain", msg); } - private void onRuleChainMsg(RuleChainToRuleChainMsg msg) { - ruleChainManager.getOrCreateActor(context(), msg.getTarget()).tell(msg, self()); + private void onRuleChainMsg(RuleChainAwareMsg msg) { + ruleChainManager.getOrCreateActor(context(), msg.getRuleChainId()).tell(msg, self()); } diff --git a/application/src/main/java/org/thingsboard/server/controller/AlarmController.java b/application/src/main/java/org/thingsboard/server/controller/AlarmController.java index 28cc2fdf09..51ef5668bd 100644 --- a/application/src/main/java/org/thingsboard/server/controller/AlarmController.java +++ b/application/src/main/java/org/thingsboard/server/controller/AlarmController.java @@ -26,6 +26,7 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; +import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.alarm.Alarm; import org.thingsboard.server.common.data.alarm.AlarmId; import org.thingsboard.server.common.data.alarm.AlarmInfo; @@ -33,6 +34,7 @@ import org.thingsboard.server.common.data.alarm.AlarmQuery; import org.thingsboard.server.common.data.alarm.AlarmSearchStatus; import org.thingsboard.server.common.data.alarm.AlarmSeverity; import org.thingsboard.server.common.data.alarm.AlarmStatus; +import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.exception.ThingsboardErrorCode; import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.id.EntityId; @@ -53,7 +55,6 @@ public class AlarmController extends BaseController { checkParameter(ALARM_ID, strAlarmId); try { AlarmId alarmId = new AlarmId(toUUID(strAlarmId)); - return checkAlarmId(alarmId); } catch (Exception e) { throw handleException(e); @@ -79,8 +80,14 @@ public class AlarmController extends BaseController { public Alarm saveAlarm(@RequestBody Alarm alarm) throws ThingsboardException { try { alarm.setTenantId(getCurrentUser().getTenantId()); - return checkNotNull(alarmService.createOrUpdateAlarm(alarm)); + Alarm savedAlarm = checkNotNull(alarmService.createOrUpdateAlarm(alarm)); + logEntityAction(savedAlarm.getId(), savedAlarm, + getCurrentUser().getCustomerId(), + savedAlarm.getId() == null ? ActionType.ADDED : ActionType.UPDATED, null); + return savedAlarm; } catch (Exception e) { + logEntityAction(emptyId(EntityType.ASSET), alarm, + null, alarm.getId() == null ? ActionType.ADDED : ActionType.UPDATED, e); throw handleException(e); } } @@ -92,8 +99,9 @@ public class AlarmController extends BaseController { checkParameter(ALARM_ID, strAlarmId); try { AlarmId alarmId = new AlarmId(toUUID(strAlarmId)); - checkAlarmId(alarmId); + Alarm alarm = checkAlarmId(alarmId); alarmService.ackAlarm(alarmId, System.currentTimeMillis()).get(); + logEntityAction(alarmId, alarm, getCurrentUser().getCustomerId(), ActionType.ALARM_ACK, null); } catch (Exception e) { throw handleException(e); } @@ -106,8 +114,9 @@ public class AlarmController extends BaseController { checkParameter(ALARM_ID, strAlarmId); try { AlarmId alarmId = new AlarmId(toUUID(strAlarmId)); - checkAlarmId(alarmId); + Alarm alarm = checkAlarmId(alarmId); alarmService.clearAlarm(alarmId, null, System.currentTimeMillis()).get(); + logEntityAction(alarmId, alarm, getCurrentUser().getCustomerId(), ActionType.ALARM_CLEAR, null); } catch (Exception e) { throw handleException(e); } diff --git a/application/src/main/java/org/thingsboard/server/controller/BaseController.java b/application/src/main/java/org/thingsboard/server/controller/BaseController.java index f04422898c..de73fe0796 100644 --- a/application/src/main/java/org/thingsboard/server/controller/BaseController.java +++ b/application/src/main/java/org/thingsboard/server/controller/BaseController.java @@ -529,18 +529,16 @@ public abstract class BaseController { return baseUrl; } - protected I emptyId(EntityType entityType) { + protected I emptyId(EntityType entityType) { return (I)EntityIdFactory.getByTypeAndUuid(entityType, ModelConstants.NULL_UUID); } - protected & HasName, - I extends UUIDBased & EntityId> void logEntityAction(I entityId, E entity, CustomerId customerId, + protected void logEntityAction(I entityId, E entity, CustomerId customerId, ActionType actionType, Exception e, Object... additionalInfo) throws ThingsboardException { logEntityAction(getCurrentUser(), entityId, entity, customerId, actionType, e, additionalInfo); } - protected & HasName, - I extends UUIDBased & EntityId> void logEntityAction(User user, I entityId, E entity, CustomerId customerId, + protected void logEntityAction(User user, I entityId, E entity, CustomerId customerId, ActionType actionType, Exception e, Object... additionalInfo) throws ThingsboardException { if (customerId == null || customerId.isNullUid()) { customerId = user.getCustomerId(); @@ -556,8 +554,7 @@ public abstract class BaseController { return error != null ? (Exception.class.isInstance(error) ? (Exception) error : new Exception(error)) : null; } - private & HasName, - I extends UUIDBased & EntityId> void pushEntityActionToRuleEngine(I entityId, E entity, User user, CustomerId customerId, + private void pushEntityActionToRuleEngine(I entityId, E entity, User user, CustomerId customerId, ActionType actionType, Object... additionalInfo) { String msgType = null; switch (actionType) { diff --git a/application/src/main/java/org/thingsboard/server/controller/EntityRelationController.java b/application/src/main/java/org/thingsboard/server/controller/EntityRelationController.java index 844dbd35a9..70dd8a643e 100644 --- a/application/src/main/java/org/thingsboard/server/controller/EntityRelationController.java +++ b/application/src/main/java/org/thingsboard/server/controller/EntityRelationController.java @@ -24,10 +24,13 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; +import org.thingsboard.server.common.data.alarm.Alarm; +import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.exception.ThingsboardErrorCode; import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.EntityIdFactory; +import org.thingsboard.server.common.data.id.UUIDBased; import org.thingsboard.server.common.data.relation.EntityRelation; import org.thingsboard.server.common.data.relation.EntityRelationInfo; import org.thingsboard.server.common.data.relation.EntityRelationsQuery; @@ -58,7 +61,15 @@ public class EntityRelationController extends BaseController { relation.setTypeGroup(RelationTypeGroup.COMMON); } relationService.saveRelation(relation); + logEntityAction(relation.getFrom(), null, getCurrentUser().getCustomerId(), + ActionType.RELATION_ADD_OR_UPDATE, null, relation); + logEntityAction(relation.getTo(), null, getCurrentUser().getCustomerId(), + ActionType.RELATION_ADD_OR_UPDATE, null, relation); } catch (Exception e) { + logEntityAction(relation.getFrom(), null, getCurrentUser().getCustomerId(), + ActionType.RELATION_ADD_OR_UPDATE, e, relation); + logEntityAction(relation.getTo(), null, getCurrentUser().getCustomerId(), + ActionType.RELATION_ADD_OR_UPDATE, e, relation); throw handleException(e); } } @@ -81,12 +92,21 @@ public class EntityRelationController extends BaseController { checkEntityId(fromId); checkEntityId(toId); RelationTypeGroup relationTypeGroup = parseRelationTypeGroup(strRelationTypeGroup, RelationTypeGroup.COMMON); + EntityRelation relation = new EntityRelation(fromId, toId, strRelationType, relationTypeGroup); try { Boolean found = relationService.deleteRelation(fromId, toId, strRelationType, relationTypeGroup); if (!found) { throw new ThingsboardException("Requested item wasn't found!", ThingsboardErrorCode.ITEM_NOT_FOUND); } + logEntityAction(relation.getFrom(), null, getCurrentUser().getCustomerId(), + ActionType.RELATION_DELETED, null, relation); + logEntityAction(relation.getTo(), null, getCurrentUser().getCustomerId(), + ActionType.RELATION_DELETED, null, relation); } catch (Exception e) { + logEntityAction(relation.getFrom(), null, getCurrentUser().getCustomerId(), + ActionType.RELATION_DELETED, e, relation); + logEntityAction(relation.getTo(), null, getCurrentUser().getCustomerId(), + ActionType.RELATION_DELETED, e, relation); throw handleException(e); } } @@ -102,7 +122,9 @@ public class EntityRelationController extends BaseController { checkEntityId(entityId); try { relationService.deleteEntityRelations(entityId); + logEntityAction(entityId, null, getCurrentUser().getCustomerId(), ActionType.RELATIONS_DELETED, null); } catch (Exception e) { + logEntityAction(entityId, null, getCurrentUser().getCustomerId(), ActionType.RELATIONS_DELETED, e); throw handleException(e); } } @@ -210,8 +232,8 @@ public class EntityRelationController extends BaseController { @RequestMapping(value = "/relations/info", method = RequestMethod.GET, params = {TO_ID, TO_TYPE}) @ResponseBody public List findInfoByTo(@RequestParam(TO_ID) String strToId, - @RequestParam(TO_TYPE) String strToType, - @RequestParam(value = "relationTypeGroup", required = false) String strRelationTypeGroup) throws ThingsboardException { + @RequestParam(TO_TYPE) String strToType, + @RequestParam(value = "relationTypeGroup", required = false) String strRelationTypeGroup) throws ThingsboardException { checkParameter(TO_ID, strToId); checkParameter(TO_TYPE, strToType); EntityId entityId = EntityIdFactory.getByTypeAndId(strToType, strToId); @@ -276,10 +298,11 @@ public class EntityRelationController extends BaseController { private RelationTypeGroup parseRelationTypeGroup(String strRelationTypeGroup, RelationTypeGroup defaultValue) { RelationTypeGroup result = defaultValue; - if (strRelationTypeGroup != null && strRelationTypeGroup.trim().length()>0) { + if (strRelationTypeGroup != null && strRelationTypeGroup.trim().length() > 0) { try { result = RelationTypeGroup.valueOf(strRelationTypeGroup); - } catch (IllegalArgumentException e) { } + } catch (IllegalArgumentException e) { + } } return result; } 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 b771ee2c25..136bbfdb05 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 @@ -46,7 +46,6 @@ public class TbWebSocketHandler extends TextWebSocketHandler implements Telemetr private static final ConcurrentMap externalSessionMap = new ConcurrentHashMap<>(); @Autowired - @Lazy private TelemetryWebSocketService webSocketService; @Override diff --git a/application/src/main/java/org/thingsboard/server/service/rpc/DefaultDeviceRpcService.java b/application/src/main/java/org/thingsboard/server/service/rpc/DefaultDeviceRpcService.java index 8e866612f2..64f5213d65 100644 --- a/application/src/main/java/org/thingsboard/server/service/rpc/DefaultDeviceRpcService.java +++ b/application/src/main/java/org/thingsboard/server/service/rpc/DefaultDeviceRpcService.java @@ -22,6 +22,7 @@ import com.fasterxml.jackson.databind.node.ObjectNode; import com.google.protobuf.InvalidProtocolBufferException; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.thingsboard.rule.engine.api.RpcError; import org.thingsboard.rule.engine.api.msg.ToDeviceActorNotificationMsg; @@ -67,6 +68,7 @@ public class DefaultDeviceRpcService implements DeviceRpcService { private ClusterRpcService rpcService; @Autowired + @Lazy private ActorService actorService; private ScheduledExecutorService rpcCallBackExecutor; diff --git a/application/src/main/java/org/thingsboard/server/service/state/DefaultDeviceStateService.java b/application/src/main/java/org/thingsboard/server/service/state/DefaultDeviceStateService.java index a41fdee250..f4e37db971 100644 --- a/application/src/main/java/org/thingsboard/server/service/state/DefaultDeviceStateService.java +++ b/application/src/main/java/org/thingsboard/server/service/state/DefaultDeviceStateService.java @@ -28,6 +28,7 @@ import lombok.Getter; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.thingsboard.rule.engine.api.RpcError; import org.thingsboard.server.actors.service.ActorService; @@ -102,6 +103,7 @@ public class DefaultDeviceStateService implements DeviceStateService { private AttributesService attributesService; @Autowired + @Lazy private ActorService actorService; @Autowired diff --git a/application/src/main/java/org/thingsboard/server/service/telemetry/DefaultTelemetrySubscriptionService.java b/application/src/main/java/org/thingsboard/server/service/telemetry/DefaultTelemetrySubscriptionService.java index ef1606a3a3..263b4849fa 100644 --- a/application/src/main/java/org/thingsboard/server/service/telemetry/DefaultTelemetrySubscriptionService.java +++ b/application/src/main/java/org/thingsboard/server/service/telemetry/DefaultTelemetrySubscriptionService.java @@ -432,7 +432,7 @@ public class DefaultTelemetrySubscriptionService implements TelemetrySubscriptio deviceSubscriptions.stream().filter(filter).forEach(s -> { String sessionId = s.getWsSessionId(); List subscriptionUpdate = f.apply(s); - if (subscriptionUpdate == null || !subscriptionUpdate.isEmpty()) { + if (subscriptionUpdate != null && !subscriptionUpdate.isEmpty()) { SubscriptionUpdate update = new SubscriptionUpdate(s.getSubscriptionId(), subscriptionUpdate); if (s.isLocal()) { updateSubscriptionState(sessionId, s, update); diff --git a/application/src/main/resources/thingsboard.yml b/application/src/main/resources/thingsboard.yml index 5653193d27..9f6192b51d 100644 --- a/application/src/main/resources/thingsboard.yml +++ b/application/src/main/resources/thingsboard.yml @@ -225,7 +225,7 @@ sql: # Actor system parameters actors: tenant: - create_components_on_init: true + create_components_on_init: "${ACTORS_TENANT_CREATE_COMPONENTS_ON_INIT:true}" session: max_concurrent_sessions_per_device: "${ACTORS_MAX_CONCURRENT_SESSION_PER_DEVICE:1}" sync: @@ -328,6 +328,13 @@ spring.mvc.cors: max-age: "1800" allow-credentials: "true" +# spring serve gzip compressed static resources +spring.resources.chain: + gzipped: "true" + strategy: + content: + enabled: "true" + # HSQLDB DAO Configuration spring: data: @@ -378,6 +385,7 @@ audit_log: "customer": "${AUDIT_LOG_MASK_CUSTOMER:W}" "user": "${AUDIT_LOG_MASK_USER:W}" "rule_chain": "${AUDIT_LOG_MASK_RULE_CHAIN:W}" + "alarm": "${AUDIT_LOG_MASK_ALARM:W}" sink: # Type of external sink. possible options: none, elasticsearch type: "${AUDIT_LOG_SINK_TYPE:none}" diff --git a/application/src/main/scripts/install/install_dev_db.sh b/application/src/main/scripts/install/install_dev_db.sh index ba93479ed4..212a2accda 100644 --- a/application/src/main/scripts/install/install_dev_db.sh +++ b/application/src/main/scripts/install/install_dev_db.sh @@ -30,13 +30,13 @@ export SQL_DATA_FOLDER=${SQL_DATA_FOLDER:-/tmp} run_user=thingsboard -su -s /bin/sh -c "java -cp ${jarfile} $JAVA_OPTS -Dloader.main=org.thingsboard.server.ThingsboardInstallApplication \ +sudo -u "$run_user" -s /bin/sh -c "java -cp ${jarfile} $JAVA_OPTS -Dloader.main=org.thingsboard.server.ThingsboardInstallApplication \ -Dinstall.data_dir=${installDir} \ -Dinstall.load_demo=${loadDemo} \ -Dspring.jpa.hibernate.ddl-auto=none \ -Dinstall.upgrade=false \ -Dlogging.config=logback.xml \ - org.springframework.boot.loader.PropertiesLauncher" "$run_user" + org.springframework.boot.loader.PropertiesLauncher" if [ $? -ne 0 ]; then echo "ThingsBoard DB installation failed!" diff --git a/common/data/pom.xml b/common/data/pom.xml index 7953b48843..1cbd1b5593 100644 --- a/common/data/pom.xml +++ b/common/data/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 2.0.3 + 2.1.0-SNAPSHOT common org.thingsboard.common diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/audit/ActionType.java b/common/data/src/main/java/org/thingsboard/server/common/data/audit/ActionType.java index ea442f0c53..c37d4607c3 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/audit/ActionType.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/audit/ActionType.java @@ -31,7 +31,12 @@ public enum ActionType { ACTIVATED(false), // log string id SUSPENDED(false), // log string id CREDENTIALS_READ(true), // log device id - ATTRIBUTES_READ(true); // log attributes + ATTRIBUTES_READ(true), // log attributes + RELATION_ADD_OR_UPDATE (false), + RELATION_DELETED (false), + RELATIONS_DELETED (false), + ALARM_ACK (false), + ALARM_CLEAR (false); private final boolean isRead; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/id/EntityIdFactory.java b/common/data/src/main/java/org/thingsboard/server/common/data/id/EntityIdFactory.java index 0ecc7c639f..ed4cf2f784 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/id/EntityIdFactory.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/id/EntityIdFactory.java @@ -60,4 +60,5 @@ public class EntityIdFactory { } throw new IllegalArgumentException("EntityType " + type + " is not supported!"); } + } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/relation/RelationsSearchParameters.java b/common/data/src/main/java/org/thingsboard/server/common/data/relation/RelationsSearchParameters.java index 2e976f20a6..beccc04a48 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/relation/RelationsSearchParameters.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/relation/RelationsSearchParameters.java @@ -33,13 +33,19 @@ public class RelationsSearchParameters { private UUID rootId; private EntityType rootType; private EntitySearchDirection direction; + private RelationTypeGroup relationTypeGroup; private int maxLevel = 1; public RelationsSearchParameters(EntityId entityId, EntitySearchDirection direction, int maxLevel) { + this(entityId, direction, maxLevel, RelationTypeGroup.COMMON); + } + + public RelationsSearchParameters(EntityId entityId, EntitySearchDirection direction, int maxLevel, RelationTypeGroup relationTypeGroup) { this.rootId = entityId.getId(); this.rootType = entityId.getEntityType(); this.direction = direction; this.maxLevel = maxLevel; + this.relationTypeGroup = relationTypeGroup; } public EntityId getEntityId() { diff --git a/common/message/pom.xml b/common/message/pom.xml index 91e617e956..e1af6d101c 100644 --- a/common/message/pom.xml +++ b/common/message/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 2.0.3 + 2.1.0-SNAPSHOT common org.thingsboard.common diff --git a/common/message/src/main/java/org/thingsboard/server/common/msg/MsgType.java b/common/message/src/main/java/org/thingsboard/server/common/msg/MsgType.java index 7702788704..c8b5c4ee8d 100644 --- a/common/message/src/main/java/org/thingsboard/server/common/msg/MsgType.java +++ b/common/message/src/main/java/org/thingsboard/server/common/msg/MsgType.java @@ -62,6 +62,11 @@ public enum MsgType { */ RULE_TO_RULE_CHAIN_TELL_NEXT_MSG, + /** + * Message forwarded from original rule chain to remote rule chain due to change in the cluster structure or originator entity of the TbMsg. + */ + REMOTE_TO_RULE_CHAIN_TELL_NEXT_MSG, + /** * Message that is sent by RuleActor implementation to RuleActor itself to log the error. */ @@ -101,6 +106,10 @@ public enum MsgType { /** * Message that is sent from Rule Engine to the Device Actor when message is successfully pushed to queue. */ - RULE_ENGINE_QUEUE_PUT_ACK_MSG, ACTOR_SYSTEM_TO_DEVICE_SESSION_ACTOR_MSG, TRANSPORT_TO_DEVICE_SESSION_ACTOR_MSG, SESSION_TIMEOUT_MSG, SESSION_CTRL_MSG; + RULE_ENGINE_QUEUE_PUT_ACK_MSG, + ACTOR_SYSTEM_TO_DEVICE_SESSION_ACTOR_MSG, + TRANSPORT_TO_DEVICE_SESSION_ACTOR_MSG, + SESSION_TIMEOUT_MSG, + SESSION_CTRL_MSG; } diff --git a/common/message/src/main/java/org/thingsboard/server/common/msg/aware/RuleChainAwareMsg.java b/common/message/src/main/java/org/thingsboard/server/common/msg/aware/RuleChainAwareMsg.java new file mode 100644 index 0000000000..e261cbb771 --- /dev/null +++ b/common/message/src/main/java/org/thingsboard/server/common/msg/aware/RuleChainAwareMsg.java @@ -0,0 +1,24 @@ +/** + * Copyright © 2016-2018 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.common.msg.aware; + +import org.thingsboard.server.common.data.id.RuleChainId; + +public interface RuleChainAwareMsg { + + RuleChainId getRuleChainId(); + +} diff --git a/common/pom.xml b/common/pom.xml index 4f555e0847..8c2416d89c 100644 --- a/common/pom.xml +++ b/common/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 2.0.3 + 2.1.0-SNAPSHOT thingsboard org.thingsboard diff --git a/common/transport/pom.xml b/common/transport/pom.xml index b7a42555b9..07c4d34d8a 100644 --- a/common/transport/pom.xml +++ b/common/transport/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 2.0.3 + 2.1.0-SNAPSHOT common org.thingsboard.common diff --git a/dao/pom.xml b/dao/pom.xml index f6050d15fe..00173bdf86 100644 --- a/dao/pom.xml +++ b/dao/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 2.0.3 + 2.1.0-SNAPSHOT thingsboard dao diff --git a/dao/src/main/java/org/thingsboard/server/dao/audit/AuditLogService.java b/dao/src/main/java/org/thingsboard/server/dao/audit/AuditLogService.java index d2e6f056e0..b9db33810a 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/audit/AuditLogService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/audit/AuditLogService.java @@ -40,15 +40,14 @@ public interface AuditLogService { TimePageData findAuditLogsByTenantId(TenantId tenantId, TimePageLink pageLink); - & HasName, - I extends UUIDBased & EntityId> ListenableFuture> logEntityAction( - TenantId tenantId, - CustomerId customerId, - UserId userId, - String userName, - I entityId, - E entity, - ActionType actionType, - Exception e, Object... additionalInfo); + ListenableFuture> logEntityAction( + TenantId tenantId, + CustomerId customerId, + UserId userId, + String userName, + I entityId, + E entity, + ActionType actionType, + Exception e, Object... additionalInfo); } diff --git a/dao/src/main/java/org/thingsboard/server/dao/audit/AuditLogServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/audit/AuditLogServiceImpl.java index a30c1b453b..ecb2bd5a27 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/audit/AuditLogServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/audit/AuditLogServiceImpl.java @@ -43,6 +43,7 @@ import org.thingsboard.server.common.data.id.UserId; import org.thingsboard.server.common.data.kv.AttributeKvEntry; import org.thingsboard.server.common.data.page.TimePageData; import org.thingsboard.server.common.data.page.TimePageLink; +import org.thingsboard.server.common.data.relation.EntityRelation; import org.thingsboard.server.common.data.rule.RuleChainMetaData; import org.thingsboard.server.common.data.security.DeviceCredentials; import org.thingsboard.server.dao.audit.sink.AuditLogSink; @@ -115,7 +116,7 @@ public class AuditLogServiceImpl implements AuditLogService { } @Override - public & HasName, I extends UUIDBased & EntityId> ListenableFuture> + public ListenableFuture> logEntityAction(TenantId tenantId, CustomerId customerId, UserId userId, String userName, I entityId, E entity, ActionType actionType, Exception e, Object... additionalInfo) { if (canLog(entityId.getEntityType(), actionType)) { @@ -156,14 +157,16 @@ public class AuditLogServiceImpl implements AuditLogService { } } - private & HasName, I extends UUIDBased & EntityId> JsonNode constructActionData(I entityId, - E entity, + private JsonNode constructActionData(I entityId, E entity, ActionType actionType, Object... additionalInfo) { ObjectNode actionData = objectMapper.createObjectNode(); switch(actionType) { case ADDED: case UPDATED: + case ALARM_ACK: + case ALARM_CLEAR: + case RELATIONS_DELETED: if (entity != null) { ObjectNode entityNode = objectMapper.valueToTree(entity); if (entityId.getEntityType() == EntityType.DASHBOARD) { @@ -240,6 +243,11 @@ public class AuditLogServiceImpl implements AuditLogService { actionData.put("unassignedCustomerId", strCustomerId); actionData.put("unassignedCustomerName", strCustomerName); break; + case RELATION_ADD_OR_UPDATE: + case RELATION_DELETED: + EntityRelation relation = extractParameter(EntityRelation.class, 0, additionalInfo); + actionData.set("relation", objectMapper.valueToTree(relation)); + break; } return actionData; } diff --git a/dao/src/main/java/org/thingsboard/server/dao/audit/DummyAuditLogServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/audit/DummyAuditLogServiceImpl.java index b14d6b196d..6f9ea36222 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/audit/DummyAuditLogServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/audit/DummyAuditLogServiceImpl.java @@ -57,7 +57,7 @@ public class DummyAuditLogServiceImpl implements AuditLogService { } @Override - public & HasName, I extends UUIDBased & EntityId> ListenableFuture> logEntityAction(TenantId tenantId, CustomerId customerId, UserId userId, String userName, I entityId, E entity, ActionType actionType, Exception e, Object... additionalInfo) { + public ListenableFuture> logEntityAction(TenantId tenantId, CustomerId customerId, UserId userId, String userName, I entityId, E entity, ActionType actionType, Exception e, Object... additionalInfo) { return null; } diff --git a/dao/src/main/java/org/thingsboard/server/dao/cache/CaffeineCacheConfiguration.java b/dao/src/main/java/org/thingsboard/server/dao/cache/CaffeineCacheConfiguration.java index 2dc624faea..688dfb3f9f 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/cache/CaffeineCacheConfiguration.java +++ b/dao/src/main/java/org/thingsboard/server/dao/cache/CaffeineCacheConfiguration.java @@ -16,8 +16,10 @@ package org.thingsboard.server.dao.cache; import com.github.benmanes.caffeine.cache.Caffeine; +import com.github.benmanes.caffeine.cache.RemovalCause; import com.github.benmanes.caffeine.cache.Ticker; import lombok.Data; +import lombok.extern.slf4j.Slf4j; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.cache.CacheManager; @@ -28,6 +30,7 @@ import org.springframework.cache.support.SimpleCacheManager; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.concurrent.TimeUnit; @@ -38,12 +41,14 @@ import java.util.stream.Collectors; @ConfigurationProperties(prefix = "caffeine") @EnableCaching @Data +@Slf4j public class CaffeineCacheConfiguration { private Map specs; @Bean public CacheManager cacheManager() { + log.trace("Initializing cache: {}", Arrays.toString(RemovalCause.values())); SimpleCacheManager manager = new SimpleCacheManager(); if (specs != null) { List caches = diff --git a/dao/src/main/java/org/thingsboard/server/dao/relation/BaseRelationService.java b/dao/src/main/java/org/thingsboard/server/dao/relation/BaseRelationService.java index ea29f6fa77..9b89fe29f3 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/relation/BaseRelationService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/relation/BaseRelationService.java @@ -402,7 +402,7 @@ public class BaseRelationService implements RelationService { int maxLvl = params.getMaxLevel() > 0 ? params.getMaxLevel() : Integer.MAX_VALUE; try { - ListenableFuture> relationSet = findRelationsRecursively(params.getEntityId(), params.getDirection(), maxLvl, new ConcurrentHashMap<>()); + ListenableFuture> relationSet = findRelationsRecursively(params.getEntityId(), params.getDirection(), params.getRelationTypeGroup(), maxLvl, new ConcurrentHashMap<>()); return Futures.transform(relationSet, input -> { List relations = new ArrayList<>(); if (filters == null || filters.isEmpty()) { @@ -518,14 +518,15 @@ public class BaseRelationService implements RelationService { } } - private ListenableFuture> findRelationsRecursively(final EntityId rootId, final EntitySearchDirection direction, int lvl, + private ListenableFuture> findRelationsRecursively(final EntityId rootId, final EntitySearchDirection direction, + RelationTypeGroup relationTypeGroup, int lvl, final ConcurrentHashMap uniqueMap) throws Exception { if (lvl == 0) { return Futures.immediateFuture(Collections.emptySet()); } lvl--; //TODO: try to remove this blocking operation - Set children = new HashSet<>(findRelations(rootId, direction).get()); + Set children = new HashSet<>(findRelations(rootId, direction, relationTypeGroup).get()); Set childrenIds = new HashSet<>(); for (EntityRelation childRelation : children) { log.trace("Found Relation: {}", childRelation); @@ -544,7 +545,7 @@ public class BaseRelationService implements RelationService { } List>> futures = new ArrayList<>(); for (EntityId entityId : childrenIds) { - futures.add(findRelationsRecursively(entityId, direction, lvl, uniqueMap)); + futures.add(findRelationsRecursively(entityId, direction, relationTypeGroup, lvl, uniqueMap)); } //TODO: try to remove this blocking operation List> relations = Futures.successfulAsList(futures).get(); @@ -552,12 +553,15 @@ public class BaseRelationService implements RelationService { return Futures.immediateFuture(children); } - private ListenableFuture> findRelations(final EntityId rootId, final EntitySearchDirection direction) { + private ListenableFuture> findRelations(final EntityId rootId, final EntitySearchDirection direction, RelationTypeGroup relationTypeGroup) { ListenableFuture> relations; + if (relationTypeGroup == null) { + relationTypeGroup = RelationTypeGroup.COMMON; + } if (direction == EntitySearchDirection.FROM) { - relations = findByFromAsync(rootId, RelationTypeGroup.COMMON); + relations = findByFromAsync(rootId, relationTypeGroup); } else { - relations = findByToAsync(rootId, RelationTypeGroup.COMMON); + relations = findByToAsync(rootId, relationTypeGroup); } return relations; } diff --git a/docker/cassandra-setup/Makefile b/docker/cassandra-setup/Makefile index e0bb541711..7990a3e7e8 100644 --- a/docker/cassandra-setup/Makefile +++ b/docker/cassandra-setup/Makefile @@ -1,4 +1,4 @@ -VERSION=2.0.3 +VERSION=2.1.0 PROJECT=thingsboard APP=cassandra-setup diff --git a/docker/cassandra-upgrade/Dockerfile b/docker/cassandra-upgrade/Dockerfile new file mode 100644 index 0000000000..312db0d4e3 --- /dev/null +++ b/docker/cassandra-upgrade/Dockerfile @@ -0,0 +1,24 @@ +# +# Copyright © 2016-2018 The Thingsboard Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +FROM openjdk:8-jre + +ADD upgrade.sh /upgrade.sh +ADD thingsboard.deb /thingsboard.deb + +RUN apt-get update \ + && apt-get install -y nmap \ + && chmod +x /upgrade.sh diff --git a/docker/cassandra-upgrade/Makefile b/docker/cassandra-upgrade/Makefile new file mode 100644 index 0000000000..b2e8501a2b --- /dev/null +++ b/docker/cassandra-upgrade/Makefile @@ -0,0 +1,12 @@ +VERSION=2.1.0 +PROJECT=thingsboard +APP=cassandra-upgrade + +build: + cp ../../application/target/thingsboard.deb . + docker build --pull -t ${PROJECT}/${APP}:${VERSION} -t ${PROJECT}/${APP}:latest . + rm thingsboard.deb + +push: build + docker push ${PROJECT}/${APP}:${VERSION} + docker push ${PROJECT}/${APP}:latest diff --git a/docker/cassandra-upgrade/upgrade.sh b/docker/cassandra-upgrade/upgrade.sh new file mode 100755 index 0000000000..dac49191b2 --- /dev/null +++ b/docker/cassandra-upgrade/upgrade.sh @@ -0,0 +1,28 @@ +#!/bin/bash +# +# Copyright © 2016-2018 The Thingsboard Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + + +dpkg -i /thingsboard.deb + +until nmap $CASSANDRA_HOST -p $CASSANDRA_PORT | grep "$CASSANDRA_PORT/tcp open" +do + echo "Wait for cassandra db to start..." + sleep 10 +done + +echo "Upgrading 'Thingsboard' schema..." +/usr/share/thingsboard/bin/install/upgrade.sh --fromVersion=$UPGRADE_FROM_VERSION diff --git a/docker/cassandra/Makefile b/docker/cassandra/Makefile index 29941f5122..d1fb67705f 100644 --- a/docker/cassandra/Makefile +++ b/docker/cassandra/Makefile @@ -1,4 +1,4 @@ -VERSION=2.0.3 +VERSION=2.1.0 PROJECT=thingsboard APP=cassandra diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index 4b34e3a30a..89a83696f3 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -18,7 +18,7 @@ version: '2' services: tb: - image: "thingsboard/application:2.0.3" + image: "thingsboard/application:2.1.0" ports: - "8080:8080" - "1883:1883" diff --git a/docker/k8s/cassandra-setup.yaml b/docker/k8s/cassandra-setup.yaml index f3d2a43c3e..381df77e65 100644 --- a/docker/k8s/cassandra-setup.yaml +++ b/docker/k8s/cassandra-setup.yaml @@ -22,7 +22,7 @@ spec: containers: - name: cassandra-setup imagePullPolicy: Always - image: thingsboard/cassandra-setup:2.0.3 + image: thingsboard/cassandra-setup:2.1.0 env: - name: ADD_DEMO_DATA value: "true" diff --git a/docker/k8s/cassandra-upgrade.yaml b/docker/k8s/cassandra-upgrade.yaml new file mode 100644 index 0000000000..a78136ec41 --- /dev/null +++ b/docker/k8s/cassandra-upgrade.yaml @@ -0,0 +1,43 @@ +# +# Copyright © 2016-2018 The Thingsboard Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +apiVersion: v1 +kind: Pod +metadata: + name: cassandra-upgrade +spec: + containers: + - name: cassandra-upgrade + imagePullPolicy: Always + image: thingsboard/cassandra-upgrade:2.1.0 + env: + - name: ADD_DEMO_DATA + value: "true" + - name : CASSANDRA_HOST + value: "cassandra-headless" + - name : CASSANDRA_PORT + value: "9042" + - name : DATABASE_TYPE + value: "cassandra" + - name : CASSANDRA_URL + value: "cassandra-headless:9042" + - name : UPGRADE_FROM_VERSION + value: "1.4.0" + command: + - sh + - -c + - /upgrade.sh + restartPolicy: Never diff --git a/docker/k8s/cassandra.yaml b/docker/k8s/cassandra.yaml index 14ac8aa80f..3165bb1a7a 100644 --- a/docker/k8s/cassandra.yaml +++ b/docker/k8s/cassandra.yaml @@ -54,7 +54,7 @@ spec: topologyKey: "kubernetes.io/hostname" containers: - name: cassandra - image: thingsboard/cassandra:2.0.3 + image: thingsboard/cassandra:2.1.0 imagePullPolicy: Always ports: - containerPort: 7000 diff --git a/docker/k8s/tb.yaml b/docker/k8s/tb.yaml index 8f507e1b04..f38e1f12b1 100644 --- a/docker/k8s/tb.yaml +++ b/docker/k8s/tb.yaml @@ -84,7 +84,7 @@ spec: containers: - name: tb imagePullPolicy: Always - image: thingsboard/application:2.0.3 + image: thingsboard/application:2.1.0 ports: - containerPort: 8080 name: ui diff --git a/docker/k8s/zookeeper.yaml b/docker/k8s/zookeeper.yaml index f9948a89d7..ae33ea2efa 100644 --- a/docker/k8s/zookeeper.yaml +++ b/docker/k8s/zookeeper.yaml @@ -87,7 +87,7 @@ spec: containers: - name: zk imagePullPolicy: Always - image: thingsboard/zk:2.0.3 + image: thingsboard/zk:2.1.0 ports: - containerPort: 2181 name: client diff --git a/docker/tb/Makefile b/docker/tb/Makefile index 90793edce2..96803abf58 100644 --- a/docker/tb/Makefile +++ b/docker/tb/Makefile @@ -1,4 +1,4 @@ -VERSION=2.0.3 +VERSION=2.1.0 PROJECT=thingsboard APP=application diff --git a/docker/zookeeper/Makefile b/docker/zookeeper/Makefile index c96a6eabaa..5c58a74cf2 100644 --- a/docker/zookeeper/Makefile +++ b/docker/zookeeper/Makefile @@ -1,4 +1,4 @@ -VERSION=2.0.3 +VERSION=2.1.0 PROJECT=thingsboard APP=zk diff --git a/netty-mqtt/pom.xml b/netty-mqtt/pom.xml index a86fc58ac6..e5904fde81 100644 --- a/netty-mqtt/pom.xml +++ b/netty-mqtt/pom.xml @@ -19,12 +19,12 @@ 4.0.0 org.thingsboard - 2.0.3 + 2.1.0-SNAPSHOT thingsboard org.thingsboard netty-mqtt - 2.0.3 + 2.1.0-SNAPSHOT jar Netty MQTT Client diff --git a/pom.xml b/pom.xml index e8ed5ad64d..4be0a7fbc6 100755 --- a/pom.xml +++ b/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard thingsboard - 2.0.3 + 2.1.0-SNAPSHOT pom Thingsboard diff --git a/rule-engine/pom.xml b/rule-engine/pom.xml index f53eadfc95..7d769ce575 100644 --- a/rule-engine/pom.xml +++ b/rule-engine/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 2.0.3 + 2.1.0-SNAPSHOT thingsboard rule-engine diff --git a/rule-engine/rule-engine-api/pom.xml b/rule-engine/rule-engine-api/pom.xml index f067865a56..fce5562819 100644 --- a/rule-engine/rule-engine-api/pom.xml +++ b/rule-engine/rule-engine-api/pom.xml @@ -22,7 +22,7 @@ 4.0.0 org.thingsboard - 2.0.3 + 2.1.0-SNAPSHOT rule-engine org.thingsboard.rule-engine diff --git a/rule-engine/rule-engine-components/pom.xml b/rule-engine/rule-engine-components/pom.xml index 1759921a57..aed7efdffa 100644 --- a/rule-engine/rule-engine-components/pom.xml +++ b/rule-engine/rule-engine-components/pom.xml @@ -22,7 +22,7 @@ 4.0.0 org.thingsboard - 2.0.3 + 2.1.0-SNAPSHOT rule-engine org.thingsboard.rule-engine 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 5a30dcbe26..e7a54afac3 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,11 +47,12 @@ import static org.thingsboard.rule.engine.api.TbRelationTypes.SUCCESS; public class TbMsgGeneratorNode implements TbNode { - public static final String TB_MSG_GENERATOR_NODE_MSG = "TbMsgGeneratorNodeMsg"; + private static final String TB_MSG_GENERATOR_NODE_MSG = "TbMsgGeneratorNodeMsg"; private TbMsgGeneratorNodeConfiguration config; private ScriptEngine jsEngine; private long delay; + private long lastScheduledTs; private EntityId originatorId; private UUID nextTickId; private TbMsg prevMsg; @@ -66,28 +67,40 @@ public class TbMsgGeneratorNode implements TbNode { originatorId = ctx.getSelfId(); } this.jsEngine = ctx.createJsScriptEngine(config.getJsScript(), "prevMsg", "prevMetadata", "prevMsgType"); - sentTickMsg(ctx); + scheduleTickMsg(ctx); } @Override public void onMsg(TbContext ctx, TbMsg msg) { if (msg.getType().equals(TB_MSG_GENERATOR_NODE_MSG) && msg.getId().equals(nextTickId)) { withCallback(generate(ctx), - m -> {ctx.tellNext(m, SUCCESS); sentTickMsg(ctx);}, - t -> {ctx.tellFailure(msg, t); sentTickMsg(ctx);}); + m -> { + ctx.tellNext(m, SUCCESS); + scheduleTickMsg(ctx); + }, + t -> { + ctx.tellFailure(msg, t); + scheduleTickMsg(ctx); + }); } } - private void sentTickMsg(TbContext ctx) { + private void scheduleTickMsg(TbContext ctx) { + long curTs = System.currentTimeMillis(); + if (lastScheduledTs == 0L) { + lastScheduledTs = curTs; + } + lastScheduledTs = lastScheduledTs + delay; + long curDelay = Math.max(0L, (lastScheduledTs - curTs)); TbMsg tickMsg = ctx.newMsg(TB_MSG_GENERATOR_NODE_MSG, ctx.getSelfId(), new TbMsgMetaData(), ""); nextTickId = tickMsg.getId(); - ctx.tellSelf(tickMsg, delay); + ctx.tellSelf(tickMsg, curDelay); } private ListenableFuture generate(TbContext ctx) { return ctx.getJsExecutor().executeAsync(() -> { if (prevMsg == null) { - prevMsg = ctx.newMsg( "", originatorId, new TbMsgMetaData(), "{}"); + prevMsg = ctx.newMsg("", originatorId, new TbMsgMetaData(), "{}"); } TbMsg generated = jsEngine.executeGenerate(prevMsg); prevMsg = ctx.newMsg(generated.getType(), originatorId, generated.getMetaData(), generated.getData()); diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/delay/TbMsgDelayNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/delay/TbMsgDelayNode.java new file mode 100644 index 0000000000..702e10fb04 --- /dev/null +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/delay/TbMsgDelayNode.java @@ -0,0 +1,86 @@ +/** + * Copyright © 2016-2018 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.rule.engine.delay; + +import lombok.extern.slf4j.Slf4j; +import org.thingsboard.rule.engine.api.RuleNode; +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.api.util.TbNodeUtils; +import org.thingsboard.server.common.data.plugin.ComponentType; +import org.thingsboard.server.common.msg.TbMsg; +import org.thingsboard.server.common.msg.TbMsgMetaData; + +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.TimeUnit; + +import static org.thingsboard.rule.engine.api.TbRelationTypes.FAILURE; +import static org.thingsboard.rule.engine.api.TbRelationTypes.SUCCESS; + +@Slf4j +@RuleNode( + type = ComponentType.ACTION, + name = "delay", + configClazz = TbMsgDelayNodeConfiguration.class, + nodeDescription = "Delays incoming message", + nodeDetails = "Delays messages for configurable period.", + icon = "pause", + uiResources = {"static/rulenode/rulenode-core-config.js"}, + configDirective = "tbActionNodeMsgDelayConfig" +) + +public class TbMsgDelayNode implements TbNode { + + private static final String TB_MSG_DELAY_NODE_MSG = "TbMsgDelayNodeMsg"; + + private TbMsgDelayNodeConfiguration config; + private long delay; + private Map pendingMsgs; + + @Override + public void init(TbContext ctx, TbNodeConfiguration configuration) throws TbNodeException { + this.config = TbNodeUtils.convert(configuration, TbMsgDelayNodeConfiguration.class); + this.delay = TimeUnit.SECONDS.toMillis(config.getPeriodInSeconds()); + this.pendingMsgs = new HashMap<>(); + } + + @Override + public void onMsg(TbContext ctx, TbMsg msg) { + if (msg.getType().equals(TB_MSG_DELAY_NODE_MSG)) { + TbMsg pendingMsg = pendingMsgs.remove(UUID.fromString(msg.getData())); + if (pendingMsg != null) { + ctx.tellNext(pendingMsg, SUCCESS); + } + } else { + if(pendingMsgs.size() < config.getMaxPendingMsgs()) { + pendingMsgs.put(msg.getId(), msg); + TbMsg tickMsg = ctx.newMsg(TB_MSG_DELAY_NODE_MSG, ctx.getSelfId(), new TbMsgMetaData(), msg.getId().toString()); + ctx.tellSelf(tickMsg, delay); + } else { + ctx.tellNext(msg, FAILURE, new RuntimeException("Max limit of pending messages reached!")); + } + } + } + + @Override + public void destroy() { + pendingMsgs.clear(); + } +} diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/delay/TbMsgDelayNodeConfiguration.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/delay/TbMsgDelayNodeConfiguration.java new file mode 100644 index 0000000000..411a1a5eb5 --- /dev/null +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/delay/TbMsgDelayNodeConfiguration.java @@ -0,0 +1,35 @@ +/** + * Copyright © 2016-2018 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.rule.engine.delay; + +import lombok.Data; +import org.thingsboard.rule.engine.api.NodeConfiguration; +import org.thingsboard.server.common.data.EntityType; + +@Data +public class TbMsgDelayNodeConfiguration implements NodeConfiguration { + + private int periodInSeconds; + private int maxPendingMsgs; + + @Override + public TbMsgDelayNodeConfiguration defaultConfiguration() { + TbMsgDelayNodeConfiguration configuration = new TbMsgDelayNodeConfiguration(); + configuration.setPeriodInSeconds(60); + configuration.setMaxPendingMsgs(1000); + return configuration; + } +} diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbOriginatorTypeFilterNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbOriginatorTypeFilterNode.java new file mode 100644 index 0000000000..043cb80ddb --- /dev/null +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbOriginatorTypeFilterNode.java @@ -0,0 +1,54 @@ +/** + * Copyright © 2016-2018 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.rule.engine.filter; + +import lombok.extern.slf4j.Slf4j; +import org.thingsboard.rule.engine.api.util.TbNodeUtils; +import org.thingsboard.rule.engine.api.*; +import org.thingsboard.server.common.data.EntityType; +import org.thingsboard.server.common.data.plugin.ComponentType; +import org.thingsboard.server.common.msg.TbMsg; + +@Slf4j +@RuleNode( + type = ComponentType.FILTER, + name = "originator type", + configClazz = TbOriginatorTypeFilterNodeConfiguration.class, + relationTypes = {"True", "False"}, + nodeDescription = "Filter incoming messages by message Originator Type", + nodeDetails = "If Originator Type of incoming message is expected - send Message via True chain, otherwise False chain is used.", + uiResources = {"static/rulenode/rulenode-core-config.js", "static/rulenode/rulenode-core-config.css"}, + configDirective = "tbFilterNodeOriginatorTypeConfig") +public class TbOriginatorTypeFilterNode implements TbNode { + + TbOriginatorTypeFilterNodeConfiguration config; + + @Override + public void init(TbContext ctx, TbNodeConfiguration configuration) throws TbNodeException { + this.config = TbNodeUtils.convert(configuration, TbOriginatorTypeFilterNodeConfiguration.class); + } + + @Override + public void onMsg(TbContext ctx, TbMsg msg) throws TbNodeException { + EntityType originatorType = msg.getOriginator().getEntityType(); + ctx.tellNext(msg, config.getOriginatorTypes().contains(originatorType) ? "True" : "False"); + } + + @Override + public void destroy() { + + } +} diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbOriginatorTypeFilterNodeConfiguration.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbOriginatorTypeFilterNodeConfiguration.java new file mode 100644 index 0000000000..83d0a99545 --- /dev/null +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbOriginatorTypeFilterNodeConfiguration.java @@ -0,0 +1,38 @@ +/** + * Copyright © 2016-2018 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.rule.engine.filter; + +import lombok.Data; +import org.thingsboard.rule.engine.api.NodeConfiguration; +import org.thingsboard.server.common.data.EntityType; + +import java.util.Arrays; +import java.util.List; + +@Data +public class TbOriginatorTypeFilterNodeConfiguration implements NodeConfiguration { + + private List originatorTypes; + + @Override + public TbOriginatorTypeFilterNodeConfiguration defaultConfiguration() { + TbOriginatorTypeFilterNodeConfiguration configuration = new TbOriginatorTypeFilterNodeConfiguration(); + configuration.setOriginatorTypes(Arrays.asList( + EntityType.DEVICE + )); + return configuration; + } +} 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 c5e057ed79..e06d2536a7 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,4 +1,4 @@ -!function(e){function t(a){if(n[a])return n[a].exports;var r=n[a]={exports:{},id:a,loaded:!1};return e[a].call(r.exports,r,r.exports,t),r.loaded=!0,r.exports}var n={};return t.m=e,t.c=n,t.p="/static/",t(0)}(function(e){for(var t in e)if(Object.prototype.hasOwnProperty.call(e,t))switch(typeof e[t]){case"function":break;case"object":e[t]=function(t){var n=t.slice(1),a=e[t[0]];return function(e,t,r){a.apply(this,[e,t,r].concat(n))}}(e[t]);break;default:e[t]=e[e[t]]}return e}([function(e,t,n){e.exports=n(72)},function(e,t){},1,1,1,function(e,t){e.exports='
{{scope.name | translate}}
'},function(e,t){e.exports="
{{ 'tb.rulenode.test-details-function' | translate }}
tb.rulenode.alarm-type-required
"},function(e,t){e.exports="
{{ 'tb.rulenode.test-details-function' | translate }}
tb.rulenode.alarm-type-required
{{ severity.name | translate}}
tb.rulenode.alarm-severity-required
{{ 'tb.rulenode.propagate' | translate }}
"},function(e,t){e.exports="
tb.rulenode.message-count-required
tb.rulenode.min-message-count-message
tb.rulenode.period-seconds-required
tb.rulenode.min-period-seconds-message
{{ 'tb.rulenode.test-generator-function' | translate }}
"},function(e,t){e.exports='
tb.rulenode.topic-pattern-required
tb.rulenode.bootstrap-servers-required
tb.rulenode.min-retries-message
tb.rulenode.min-batch-size-bytes-message
tb.rulenode.min-linger-ms-message
tb.rulenode.min-buffer-memory-bytes-message
{{ ackValue }}
tb.rulenode.key-serializer-required
tb.rulenode.value-serializer-required
'},function(e,t){e.exports="
{{ 'tb.rulenode.test-to-string-function' | translate }}
"},function(e,t){e.exports='
tb.rulenode.topic-pattern-required
tb.rulenode.mqtt-topic-pattern-hint
tb.rulenode.host-required
tb.rulenode.port-required
tb.rulenode.port-range
tb.rulenode.port-range
tb.rulenode.connect-timeout-required
tb.rulenode.connect-timeout-range
tb.rulenode.connect-timeout-range
{{ \'tb.rulenode.clean-session\' | translate }} {{ \'tb.rulenode.enable-ssl\' | translate }}
{{ \'tb.rulenode.credentials\' | translate }}
{{ ruleNodeTypes.mqttCredentialTypes[configuration.credentials.type].name | translate }}
{{ \'tb.rulenode.credentials\' | translate }}
{{ ruleNodeTypes.mqttCredentialTypes[configuration.credentials.type].name | translate }}
{{credentialsValue.name | translate}}
tb.rulenode.credentials-type-required
tb.rulenode.username-required
tb.rulenode.password-required
'},function(e,t){e.exports='
{{ property }}
tb.rulenode.host-required
tb.rulenode.port-required
tb.rulenode.port-range
tb.rulenode.port-range
{{ \'tb.rulenode.automatic-recovery\' | translate }}
tb.rulenode.min-connection-timeout-ms-message
tb.rulenode.min-handshake-timeout-ms-message
'},function(e,t){e.exports='
tb.rulenode.endpoint-url-pattern-required
tb.rulenode.endpoint-url-pattern-hint
{{ type }}
tb.rulenode.headers-hint
'},function(e,t){e.exports="
"},function(e,t){e.exports="
tb.rulenode.timeout-required
tb.rulenode.min-timeout-message
"},function(e,t){e.exports='
{{ \'tb.rulenode.use-system-smtp-settings\' | translate }}
{{smtpProtocol.toUpperCase()}}
tb.rulenode.smtp-host-required
tb.rulenode.smtp-port-required
tb.rulenode.smtp-port-range
tb.rulenode.smtp-port-range
tb.rulenode.timeout-required
tb.rulenode.min-timeout-msec-message
{{ \'tb.rulenode.enable-tls\' | translate }}
'},function(e,t){e.exports="
tb.rulenode.topic-arn-pattern-required
tb.rulenode.topic-arn-pattern-hint
tb.rulenode.aws-access-key-id-required
tb.rulenode.aws-secret-access-key-required
tb.rulenode.aws-region-required
"},function(e,t){e.exports='
{{ type.name | translate }}
tb.rulenode.queue-url-pattern-required
tb.rulenode.queue-url-pattern-hint
tb.rulenode.min-delay-seconds-message
tb.rulenode.max-delay-seconds-message
tb.rulenode.message-attributes-hint
tb.rulenode.aws-access-key-id-required
tb.rulenode.aws-secret-access-key-required
tb.rulenode.aws-region-required
'},function(e,t){e.exports="
tb.rulenode.default-ttl-required
tb.rulenode.min-default-ttl-message
"},function(e,t){e.exports='
{{ (\'relation.search-direction.\' + direction) | translate}}
relation.relation-type
device.device-types
'},function(e,t){e.exports="
{{ 'tb.rulenode.latest-telemetry' | translate }}
"; -},function(e,t){e.exports='
'},function(e,t){e.exports='
'},function(e,t){e.exports='
'},function(e,t){e.exports="
{{ 'tb.rulenode.latest-telemetry' | translate }}
"},21,function(e,t){e.exports="
{{ ('relation.search-direction.' + direction) | translate}}
"},function(e,t){e.exports='
{{item}}
tb.rulenode.no-message-types-found
tb.rulenode.no-message-type-matching tb.rulenode.create-new-message-type
{{$chip.name}}
'},function(e,t){e.exports="
{{ 'tb.rulenode.test-filter-function' | translate }}
"},function(e,t){e.exports="
{{ 'tb.rulenode.test-switch-function' | translate }}
"},function(e,t){e.exports='
{{ keyText }} {{ valText }}  
{{keyRequiredText}}
{{valRequiredText}}
{{ \'tb.key-val.remove-entry\' | translate }} close
{{ \'tb.key-val.add-entry\' | translate }} add {{ \'action.add\' | translate }}
'},function(e,t){e.exports="
{{ ('relation.search-direction.' + direction) | translate}}
relation.relation-filters
"},function(e,t){e.exports='
{{ source.name | translate}}
'},function(e,t){e.exports="
{{ 'tb.rulenode.test-transformer-function' | translate }}
"},function(e,t){e.exports="
tb.rulenode.from-template-required
tb.rulenode.from-template-hint
tb.rulenode.to-template-required
tb.rulenode.mail-address-list-template-hint
tb.rulenode.mail-address-list-template-hint
tb.rulenode.mail-address-list-template-hint
tb.rulenode.subject-template-required
tb.rulenode.subject-template-hint
tb.rulenode.body-template-required
tb.rulenode.body-template-hint
"},function(e,t,n){"use strict";function a(e){return e&&e.__esModule?e:{default:e}}function r(e,t){var n=function(n,a,r,i){var l=o.default;a.html(l),n.types=t,n.$watch("configuration",function(e,t){angular.equals(e,t)||i.$setViewValue(n.configuration)}),i.$render=function(){n.configuration=i.$viewValue},e(a.contents())(n)};return{restrict:"E",require:"^ngModel",scope:{},link:n}}r.$inject=["$compile","types"],Object.defineProperty(t,"__esModule",{value:!0}),t.default=r;var i=n(5),o=a(i)},function(e,t,n){"use strict";function a(e){return e&&e.__esModule?e:{default:e}}function r(e,t,n,a){var r=function(r,i,l,s){var u=o.default;i.html(u),r.types=n,r.$watch("configuration",function(e,t){angular.equals(e,t)||s.$setViewValue(r.configuration)}),s.$render=function(){r.configuration=s.$viewValue},r.testDetailsBuildJs=function(e){var n=angular.copy(r.configuration.alarmDetailsBuildJs);a.testNodeScript(e,n,"json",t.instant("tb.rulenode.details")+"","Details",["msg","metadata","msgType"],r.ruleNodeId).then(function(e){r.configuration.alarmDetailsBuildJs=e,s.$setDirty()})},e(i.contents())(r)};return{restrict:"E",require:"^ngModel",scope:{ruleNodeId:"="},link:r}}r.$inject=["$compile","$translate","types","ruleNodeScriptTest"],Object.defineProperty(t,"__esModule",{value:!0}),t.default=r;var i=n(6),o=a(i)},function(e,t,n){"use strict";function a(e){return e&&e.__esModule?e:{default:e}}function r(e,t,n,a){var r=function(r,i,l,s){var u=o.default;i.html(u),r.types=n,r.$watch("configuration",function(e,t){angular.equals(e,t)||s.$setViewValue(r.configuration)}),s.$render=function(){r.configuration=s.$viewValue},r.testDetailsBuildJs=function(e){var n=angular.copy(r.configuration.alarmDetailsBuildJs);a.testNodeScript(e,n,"json",t.instant("tb.rulenode.details")+"","Details",["msg","metadata","msgType"],r.ruleNodeId).then(function(e){r.configuration.alarmDetailsBuildJs=e,s.$setDirty()})},e(i.contents())(r)};return{restrict:"E",require:"^ngModel",scope:{ruleNodeId:"="},link:r}}r.$inject=["$compile","$translate","types","ruleNodeScriptTest"],Object.defineProperty(t,"__esModule",{value:!0}),t.default=r;var i=n(7),o=a(i)},function(e,t,n){"use strict";function a(e){return e&&e.__esModule?e:{default:e}}function r(e,t,n,a){var r=function(r,i,l,s){var u=o.default;i.html(u),r.types=n,r.originator=null,r.$watch("configuration",function(e,t){angular.equals(e,t)||s.$setViewValue(r.configuration)}),s.$render=function(){r.configuration=s.$viewValue,r.configuration.originatorId&&r.configuration.originatorType?r.originator={id:r.configuration.originatorId,entityType:r.configuration.originatorType}:r.originator=null,r.$watch("originator",function(e,t){angular.equals(e,t)||(r.originator?(s.$viewValue.originatorId=r.originator.id,s.$viewValue.originatorType=r.originator.entityType):(s.$viewValue.originatorId=null,s.$viewValue.originatorType=null))},!0)},r.testScript=function(e){var n=angular.copy(r.configuration.jsScript);a.testNodeScript(e,n,"generate",t.instant("tb.rulenode.generator")+"","Generate",["prevMsg","prevMetadata","prevMsgType"],r.ruleNodeId).then(function(e){r.configuration.jsScript=e,s.$setDirty()})},e(i.contents())(r)};return{restrict:"E",require:"^ngModel",scope:{ruleNodeId:"="},link:r}}r.$inject=["$compile","$translate","types","ruleNodeScriptTest"],Object.defineProperty(t,"__esModule",{value:!0}),t.default=r,n(1);var i=n(8),o=a(i)},function(e,t,n){"use strict";function a(e){return e&&e.__esModule?e:{default:e}}Object.defineProperty(t,"__esModule",{value:!0});var r=n(51),i=a(r),o=n(36),l=a(o),s=n(39),u=a(s),d=n(38),c=a(d),m=n(37),g=a(m),p=n(42),f=a(p),b=n(46),v=a(b),y=n(47),q=a(y),h=n(45),T=a(h),$=n(41),k=a($),w=n(49),C=a(w),_=n(50),x=a(_),E=n(44),M=a(E),S=n(43),N=a(S),V=n(48),P=a(V);t.default=angular.module("thingsboard.ruleChain.config.action",[]).directive("tbActionNodeTimeseriesConfig",i.default).directive("tbActionNodeAttributesConfig",l.default).directive("tbActionNodeGeneratorConfig",u.default).directive("tbActionNodeCreateAlarmConfig",c.default).directive("tbActionNodeClearAlarmConfig",g.default).directive("tbActionNodeLogConfig",f.default).directive("tbActionNodeRpcReplyConfig",v.default).directive("tbActionNodeRpcRequestConfig",q.default).directive("tbActionNodeRestApiCallConfig",T.default).directive("tbActionNodeKafkaConfig",k.default).directive("tbActionNodeSnsConfig",C.default).directive("tbActionNodeSqsConfig",x.default).directive("tbActionNodeRabbitMqConfig",M.default).directive("tbActionNodeMqttConfig",N.default).directive("tbActionNodeSendEmailConfig",P.default).name},function(e,t,n){"use strict";function a(e){return e&&e.__esModule?e:{default:e}}function r(e){var t=function(t,n,a,r){var i=o.default;n.html(i),t.ackValues=["all","-1","0","1"],t.$watch("configuration",function(e,n){angular.equals(e,n)||r.$setViewValue(t.configuration)}),r.$render=function(){t.configuration=r.$viewValue},e(n.contents())(t)};return{restrict:"E",require:"^ngModel",scope:{},link:t}}r.$inject=["$compile"],Object.defineProperty(t,"__esModule",{value:!0}),t.default=r;var i=n(9),o=a(i)},function(e,t,n){"use strict";function a(e){return e&&e.__esModule?e:{default:e}}function r(e,t,n){var a=function(a,r,i,l){var s=o.default;r.html(s),a.$watch("configuration",function(e,t){angular.equals(e,t)||l.$setViewValue(a.configuration)}),l.$render=function(){a.configuration=l.$viewValue},a.testScript=function(e){var r=angular.copy(a.configuration.jsScript);n.testNodeScript(e,r,"string",t.instant("tb.rulenode.to-string")+"","ToString",["msg","metadata","msgType"],a.ruleNodeId).then(function(e){a.configuration.jsScript=e,l.$setDirty()})},e(r.contents())(a)};return{restrict:"E",require:"^ngModel",scope:{ruleNodeId:"="},link:a}}r.$inject=["$compile","$translate","ruleNodeScriptTest"],Object.defineProperty(t,"__esModule",{value:!0}),t.default=r;var i=n(10),o=a(i)},function(e,t,n){"use strict";function a(e){return e&&e.__esModule?e:{default:e}}function r(e,t,n){var a=function(a,r,i,l){var s=o.default;r.html(s),a.$mdExpansionPanel=t,a.ruleNodeTypes=n,a.credentialsTypeChanged=function(){var e=a.configuration.credentials.type;a.configuration.credentials={},a.configuration.credentials.type=e,a.updateValidity()},a.certFileAdded=function(e,t){var n=new FileReader;n.onload=function(n){a.$apply(function(){if(n.target.result){l.$setDirty();var r=n.target.result;r&&r.length>0&&("caCert"==t&&(a.configuration.credentials.caCertFileName=e.name,a.configuration.credentials.caCert=r),"privateKey"==t&&(a.configuration.credentials.privateKeyFileName=e.name,a.configuration.credentials.privateKey=r),"Cert"==t&&(a.configuration.credentials.certFileName=e.name,a.configuration.credentials.cert=r)),a.updateValidity()}})},n.readAsText(e.file)},a.clearCertFile=function(e){l.$setDirty(),"caCert"==e&&(a.configuration.credentials.caCertFileName=null,a.configuration.credentials.caCert=null),"privateKey"==e&&(a.configuration.credentials.privateKeyFileName=null,a.configuration.credentials.privateKey=null),"Cert"==e&&(a.configuration.credentials.certFileName=null,a.configuration.credentials.cert=null),a.updateValidity()},a.updateValidity=function(){var e=!0,t=a.configuration.credentials;t.type==n.mqttCredentialTypes["cert.PEM"].value&&(t.caCert&&t.cert&&t.privateKey||(e=!1)),l.$setValidity("Certs",e)},a.$watch("configuration",function(e,t){angular.equals(e,t)||l.$setViewValue(a.configuration)}),l.$render=function(){a.configuration=l.$viewValue},e(r.contents())(a)};return{restrict:"E",require:"^ngModel",scope:{readonly:"=ngReadonly"},link:a}}r.$inject=["$compile","$mdExpansionPanel","ruleNodeTypes"],Object.defineProperty(t,"__esModule",{value:!0}),t.default=r,n(2);var i=n(11),o=a(i)},function(e,t,n){"use strict";function a(e){return e&&e.__esModule?e:{default:e}}function r(e){var t=function(t,n,a,r){var i=o.default;n.html(i),t.messageProperties=[null,"BASIC","TEXT_PLAIN","MINIMAL_BASIC","MINIMAL_PERSISTENT_BASIC","PERSISTENT_BASIC","PERSISTENT_TEXT_PLAIN"],t.$watch("configuration",function(e,n){angular.equals(e,n)||r.$setViewValue(t.configuration)}),r.$render=function(){t.configuration=r.$viewValue},e(n.contents())(t)};return{restrict:"E",require:"^ngModel",scope:{readonly:"=ngReadonly"},link:t}}r.$inject=["$compile"],Object.defineProperty(t,"__esModule",{value:!0}),t.default=r;var i=n(12),o=a(i)},function(e,t,n){"use strict";function a(e){return e&&e.__esModule?e:{default:e}}function r(e,t){var n=function(n,a,r,i){var l=o.default;a.html(l),n.ruleNodeTypes=t,n.$watch("configuration",function(e,t){angular.equals(e,t)||i.$setViewValue(n.configuration)}),i.$render=function(){n.configuration=i.$viewValue},e(a.contents())(n)};return{restrict:"E",require:"^ngModel",scope:{},link:n}}r.$inject=["$compile","ruleNodeTypes"],Object.defineProperty(t,"__esModule",{value:!0}),t.default=r;var i=n(13),o=a(i)},function(e,t,n){"use strict";function a(e){return e&&e.__esModule?e:{default:e}}function r(e){var t=function(t,n,a,r){var i=o.default;n.html(i),t.$watch("configuration",function(e,n){angular.equals(e,n)||r.$setViewValue(t.configuration)}),r.$render=function(){t.configuration=r.$viewValue},e(n.contents())(t)};return{restrict:"E",require:"^ngModel",scope:{},link:t}}r.$inject=["$compile"],Object.defineProperty(t,"__esModule",{value:!0}),t.default=r;var i=n(14),o=a(i)},function(e,t,n){"use strict";function a(e){return e&&e.__esModule?e:{default:e}}function r(e){var t=function(t,n,a,r){var i=o.default;n.html(i),t.$watch("configuration",function(e,n){angular.equals(e,n)||r.$setViewValue(t.configuration)}),r.$render=function(){t.configuration=r.$viewValue},e(n.contents())(t)};return{restrict:"E",require:"^ngModel",scope:{},link:t}}r.$inject=["$compile"],Object.defineProperty(t,"__esModule",{value:!0}),t.default=r;var i=n(15),o=a(i)},function(e,t,n){"use strict";function a(e){return e&&e.__esModule?e:{default:e}}function r(e){var t=function(t,n,a,r){var i=o.default;n.html(i),t.smtpProtocols=["smtp","smtps"],t.$watch("configuration",function(e,n){angular.equals(e,n)||r.$setViewValue(t.configuration)}),r.$render=function(){t.configuration=r.$viewValue},e(n.contents())(t)};return{restrict:"E",require:"^ngModel",scope:{readonly:"=ngReadonly"},link:t}}r.$inject=["$compile"],Object.defineProperty(t,"__esModule",{value:!0}),t.default=r;var i=n(16),o=a(i)},function(e,t,n){"use strict";function a(e){return e&&e.__esModule?e:{default:e}}function r(e){var t=function(t,n,a,r){var i=o.default;n.html(i),t.$watch("configuration",function(e,n){angular.equals(e,n)||r.$setViewValue(t.configuration)}),r.$render=function(){t.configuration=r.$viewValue},e(n.contents())(t)};return{restrict:"E",require:"^ngModel",scope:{},link:t}}r.$inject=["$compile"],Object.defineProperty(t,"__esModule",{value:!0}),t.default=r;var i=n(17),o=a(i)},function(e,t,n){"use strict";function a(e){return e&&e.__esModule?e:{default:e}}function r(e,t){var n=function(n,a,r,i){var l=o.default;a.html(l),n.ruleNodeTypes=t,n.$watch("configuration",function(e,t){angular.equals(e,t)||i.$setViewValue(n.configuration)}),i.$render=function(){n.configuration=i.$viewValue},e(a.contents())(n)};return{restrict:"E",require:"^ngModel",scope:{readonly:"=ngReadonly"},link:n}}r.$inject=["$compile","ruleNodeTypes"],Object.defineProperty(t,"__esModule",{value:!0}),t.default=r;var i=n(18),o=a(i)},function(e,t,n){"use strict";function a(e){return e&&e.__esModule?e:{default:e}}function r(e){var t=function(t,n,a,r){var i=o.default;n.html(i),t.$watch("configuration",function(e,n){angular.equals(e,n)||r.$setViewValue(t.configuration)}),r.$render=function(){t.configuration=r.$viewValue},e(n.contents())(t)};return{restrict:"E",require:"^ngModel",scope:{},link:t}}r.$inject=["$compile"],Object.defineProperty(t,"__esModule",{value:!0}),t.default=r;var i=n(19),o=a(i)},function(e,t,n){"use strict";function a(e){return e&&e.__esModule?e:{default:e}}function r(e,t){var n=function(n,a,r,i){var l=o.default;a.html(l),n.types=t,n.$watch("query",function(e,t){angular.equals(e,t)||i.$setViewValue(n.query)}),i.$render=function(){n.query=i.$viewValue},e(a.contents())(n)};return{restrict:"E",require:"^ngModel",scope:{},link:n}}r.$inject=["$compile","types"],Object.defineProperty(t,"__esModule",{value:!0}),t.default=r;var i=n(20),o=a(i)},function(e,t){"use strict";function n(e){var t=function(t,n,a,r){n.html("
"),t.$watch("configuration",function(e,n){angular.equals(e,n)||r.$setViewValue(t.configuration)}),r.$render=function(){t.configuration=r.$viewValue},e(n.contents())(t)};return{restrict:"E",require:"^ngModel",scope:{},link:t}}n.$inject=["$compile"],Object.defineProperty(t,"__esModule",{value:!0}),t.default=n},function(e,t,n){"use strict";function a(e){return e&&e.__esModule?e:{default:e}}function r(e){var t=function(t,n,a,r){var i=o.default;n.html(i),t.$watch("configuration",function(e,n){angular.equals(e,n)||r.$setViewValue(t.configuration)}),r.$render=function(){t.configuration=r.$viewValue},e(n.contents())(t)};return{restrict:"E",require:"^ngModel",scope:{},link:t}}r.$inject=["$compile"],Object.defineProperty(t,"__esModule",{value:!0}),t.default=r;var i=n(21),o=a(i)},function(e,t,n){"use strict";function a(e){return e&&e.__esModule?e:{default:e}}function r(e,t){var n=function(n,a,r,i){var l=o.default;a.html(l);var s=186;n.separatorKeys=[t.KEY_CODE.ENTER,t.KEY_CODE.COMMA,s],n.$watch("configuration",function(e,t){angular.equals(e,t)||i.$setViewValue(n.configuration)}),i.$render=function(){n.configuration=i.$viewValue},e(a.contents())(n)};return{restrict:"E",require:"^ngModel",scope:{},link:n}}r.$inject=["$compile","$mdConstant"],Object.defineProperty(t,"__esModule",{value:!0}),t.default=r;var i=n(22),o=a(i)},function(e,t,n){"use strict";function a(e){return e&&e.__esModule?e:{default:e}}Object.defineProperty(t,"__esModule",{value:!0});var r=n(57),i=a(r),o=n(58),l=a(o),s=n(55),u=a(s),d=n(59),c=a(d),m=n(54),g=a(m),p=n(60),f=a(p);t.default=angular.module("thingsboard.ruleChain.config.enrichment",[]).directive("tbEnrichmentNodeOriginatorAttributesConfig",i.default).directive("tbEnrichmentNodeOriginatorFieldsConfig",l.default).directive("tbEnrichmentNodeDeviceAttributesConfig",u.default).directive("tbEnrichmentNodeRelatedAttributesConfig",c.default).directive("tbEnrichmentNodeCustomerAttributesConfig",g.default).directive("tbEnrichmentNodeTenantAttributesConfig",f.default).name},function(e,t,n){"use strict";function a(e){return e&&e.__esModule?e:{default:e}}function r(e,t){var n=function(n,a,r,i){var l=o.default;a.html(l);var s=186;n.separatorKeys=[t.KEY_CODE.ENTER,t.KEY_CODE.COMMA,s],n.$watch("configuration",function(e,t){angular.equals(e,t)||i.$setViewValue(n.configuration)}),i.$render=function(){n.configuration=i.$viewValue},e(a.contents())(n)};return{restrict:"E",require:"^ngModel",scope:{},link:n}}r.$inject=["$compile","$mdConstant"],Object.defineProperty(t,"__esModule",{value:!0}),t.default=r;var i=n(23),o=a(i)},function(e,t,n){"use strict";function a(e){return e&&e.__esModule?e:{default:e}}function r(e){var t=function(t,n,a,r){var i=o.default;n.html(i),t.$watch("configuration",function(e,n){angular.equals(e,n)||r.$setViewValue(t.configuration)}),r.$render=function(){t.configuration=r.$viewValue},e(n.contents())(t)};return{restrict:"E",require:"^ngModel",scope:{},link:t}}r.$inject=["$compile"],Object.defineProperty(t,"__esModule",{value:!0}),t.default=r;var i=n(24),o=a(i)},function(e,t,n){"use strict";function a(e){return e&&e.__esModule?e:{default:e}}function r(e){var t=function(t,n,a,r){var i=o.default;n.html(i),t.$watch("configuration",function(e,n){angular.equals(e,n)||r.$setViewValue(t.configuration)}),r.$render=function(){t.configuration=r.$viewValue},e(n.contents())(t)};return{restrict:"E",require:"^ngModel",scope:{},link:t}}r.$inject=["$compile"],Object.defineProperty(t,"__esModule",{value:!0}),t.default=r;var i=n(25),o=a(i)},function(e,t,n){"use strict";function a(e){return e&&e.__esModule?e:{default:e}}function r(e){var t=function(t,n,a,r){var i=o.default;n.html(i),t.$watch("configuration",function(e,n){angular.equals(e,n)||r.$setViewValue(t.configuration)}),r.$render=function(){t.configuration=r.$viewValue},e(n.contents())(t)};return{restrict:"E",require:"^ngModel",scope:{},link:t}}r.$inject=["$compile"],Object.defineProperty(t,"__esModule",{value:!0}),t.default=r;var i=n(26),o=a(i)},function(e,t,n){"use strict";function a(e){return e&&e.__esModule?e:{default:e}}function r(e,t){var n=function(n,a,r,i){var l=o.default;a.html(l),n.types=t,n.$watch("configuration",function(e,t){angular.equals(e,t)||i.$setViewValue(n.configuration)}),i.$render=function(){n.configuration=i.$viewValue},e(a.contents())(n)};return{restrict:"E",require:"^ngModel",scope:{},link:n}}r.$inject=["$compile","types"],Object.defineProperty(t,"__esModule",{value:!0}),t.default=r;var i=n(27),o=a(i)},function(e,t,n){"use strict";function a(e){return e&&e.__esModule?e:{default:e}}Object.defineProperty(t,"__esModule",{value:!0});var r=n(64),i=a(r),o=n(63),l=a(o),s=n(65),u=a(s),d=n(61),c=a(d);t.default=angular.module("thingsboard.ruleChain.config.filter",[]).directive("tbFilterNodeScriptConfig",i.default).directive("tbFilterNodeMessageTypeConfig",l.default).directive("tbFilterNodeSwitchConfig",u.default).directive("tbFilterNodeCheckRelationConfig",c.default).name},function(e,t,n){"use strict";function a(e){return e&&e.__esModule?e:{default:e}}function r(e,t,n){var a=function(a,r,i,l){function s(){if(l.$viewValue){for(var e=[],t=0;t-1&&t.kvList.splice(e,1)}function l(){t.kvList||(t.kvList=[]),t.kvList.push({key:"",value:""})}function s(){var e={};t.kvList.forEach(function(t){t.key&&(e[t.key]=t.value)}),r.$setViewValue(e),u()}function u(){var e=!0;t.required&&!t.kvList.length&&(e=!1),r.$setValidity("kvMap",e)}var d=o.default;n.html(d),t.ngModelCtrl=r,t.removeKeyVal=i,t.addKeyVal=l,t.kvList=[],t.$watch("query",function(e,n){angular.equals(e,n)||r.$setViewValue(t.query)}),r.$render=function(){if(r.$viewValue){var e=r.$viewValue;t.kvList.length=0;for(var n in e)t.kvList.push({key:n,value:e[n]})}t.$watch("kvList",function(e,t){angular.equals(e,t)||s()},!0),u()},e(n.contents())(t)};return{restrict:"E",require:"^ngModel",scope:{required:"=ngRequired",disabled:"=ngDisabled",requiredText:"=",keyText:"=",keyRequiredText:"=",valText:"=",valRequiredText:"="},link:t}}r.$inject=["$compile"],Object.defineProperty(t,"__esModule",{value:!0}),t.default=r;var i=n(31),o=a(i);n(4)},function(e,t,n){"use strict";function a(e){return e&&e.__esModule?e:{default:e}}function r(e,t){var n=function(n,a,r,i){var l=o.default;a.html(l),n.types=t,n.$watch("query",function(e,t){angular.equals(e,t)||i.$setViewValue(n.query)}),i.$render=function(){n.query=i.$viewValue},e(a.contents())(n)};return{restrict:"E",require:"^ngModel",scope:{},link:n}}r.$inject=["$compile","types"],Object.defineProperty(t,"__esModule",{value:!0}),t.default=r;var i=n(32),o=a(i)},function(e,t,n){"use strict";function a(e){return e&&e.__esModule?e:{default:e}}function r(e,t){var n=function(n,a,r,i){var l=o.default;a.html(l),n.ruleNodeTypes=t,n.$watch("configuration",function(e,t){angular.equals(e,t)||i.$setViewValue(n.configuration)}),i.$render=function(){n.configuration=i.$viewValue},e(a.contents())(n)};return{restrict:"E",require:"^ngModel",scope:{},link:n}}r.$inject=["$compile","ruleNodeTypes"],Object.defineProperty(t,"__esModule",{value:!0}),t.default=r;var i=n(33),o=a(i)},function(e,t,n){"use strict";function a(e){return e&&e.__esModule?e:{default:e}}Object.defineProperty(t,"__esModule",{value:!0});var r=n(68),i=a(r),o=n(70),l=a(o),s=n(71),u=a(s);t.default=angular.module("thingsboard.ruleChain.config.transform",[]).directive("tbTransformationNodeChangeOriginatorConfig",i.default).directive("tbTransformationNodeScriptConfig",l.default).directive("tbTransformationNodeToEmailConfig",u.default).name},function(e,t,n){"use strict";function a(e){return e&&e.__esModule?e:{default:e}}function r(e,t,n){var a=function(a,r,i,l){var s=o.default;r.html(s),a.$watch("configuration",function(e,t){angular.equals(e,t)||l.$setViewValue(a.configuration)}),l.$render=function(){a.configuration=l.$viewValue},a.testScript=function(e){var r=angular.copy(a.configuration.jsScript);n.testNodeScript(e,r,"update",t.instant("tb.rulenode.transformer")+"","Transform",["msg","metadata","msgType"],a.ruleNodeId).then(function(e){a.configuration.jsScript=e,l.$setDirty()})},e(r.contents())(a)};return{restrict:"E",require:"^ngModel",scope:{ruleNodeId:"="},link:a}}r.$inject=["$compile","$translate","ruleNodeScriptTest"],Object.defineProperty(t,"__esModule",{value:!0}),t.default=r;var i=n(34),o=a(i)},function(e,t,n){"use strict";function a(e){return e&&e.__esModule?e:{default:e}}function r(e){var t=function(t,n,a,r){var i=o.default;n.html(i),t.$watch("configuration",function(e,n){angular.equals(e,n)||r.$setViewValue(t.configuration)}),r.$render=function(){t.configuration=r.$viewValue},e(n.contents())(t)};return{restrict:"E",require:"^ngModel",scope:{},link:t}}r.$inject=["$compile"],Object.defineProperty(t,"__esModule",{value:!0}),t.default=r;var i=n(35),o=a(i)},function(e,t,n){"use strict";function a(e){return e&&e.__esModule?e:{default:e}}Object.defineProperty(t,"__esModule",{value:!0});var r=n(75),i=a(r),o=n(62),l=a(o),s=n(56),u=a(s),d=n(69),c=a(d),m=n(40),g=a(m),p=n(53),f=a(p),b=n(67),v=a(b),y=n(52),q=a(y),h=n(66),T=a(h),$=n(74),k=a($);t.default=angular.module("thingsboard.ruleChain.config",[i.default,l.default,u.default,c.default,g.default]).directive("tbNodeEmptyConfig",f.default).directive("tbRelationsQueryConfig",v.default).directive("tbDeviceRelationsQueryConfig",q.default).directive("tbKvMapConfig",T.default).config(k.default).name},function(e,t){"use strict";function n(e){var t={tb:{rulenode:{filter:"Filter",switch:"Switch","message-type":"Message type","message-type-required":"Message type is required.","message-types-filter":"Message types filter","no-message-types-found":"No message types found","no-message-type-matching":"'{{messageType}}' not found.","create-new-message-type":"Create a new one!","message-types-required":"Message types are required.","client-attributes":"Client attributes","shared-attributes":"Shared attributes","server-attributes":"Server attributes","latest-timeseries":"Latest timeseries","relations-query":"Relations query","device-relations-query":"Device relations query","max-relation-level":"Max relation level","unlimited-level":"Unlimited level","latest-telemetry":"Latest telemetry","attr-mapping":"Attributes mapping","source-attribute":"Source attribute","source-attribute-required":"Source attribute is required.","source-telemetry":"Source telemetry","source-telemetry-required":"Source telemetry is required.","target-attribute":"Target attribute","target-attribute-required":"Target attribute is required.","attr-mapping-required":"At least one attribute mapping should be specified.","fields-mapping":"Fields mapping","fields-mapping-required":"At least one field mapping should be specified.","source-field":"Source field","source-field-required":"Source field is required.","originator-source":"Originator source","originator-customer":"Customer","originator-tenant":"Tenant","originator-related":"Related","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.","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","alarm-type-required":"Alarm type is required.","alarm-severity":"Alarm severity","alarm-severity-required":"Alarm severity is required",propagate:"Propagate",condition:"Condition",details:"Details","to-string":"To string","test-to-string-function":"Test to string function","from-template":"From Template","from-template-required":"From Template is required","from-template-hint":"From address template, use ${metaKeyName} to substitute variables from metadata","to-template":"To Template","to-template-required":"To Template is required","mail-address-list-template-hint":"Comma separated address list, use ${metaKeyName} to substitute variables from metadata","cc-template":"Cc Template","bcc-template":"Bcc Template","subject-template":"Subject Template","subject-template-required":"Subject Template is required","subject-template-hint":"Mail subject template, use ${metaKeyName} to substitute variables from metadata","body-template":"Body Template","body-template-required":"Body Template is required","body-template-hint":"Mail body template, use ${metaKeyName} to substitute variables from metadata","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","endpoint-url-pattern-hint":"HTTP URL address pattern, use ${metaKeyName} to substitute variables from metadata","request-method":"Request method",headers:"Headers","headers-hint":"Use ${metaKeyName} in header/value fields to substitute variables from metadata",header:"Header","header-required":"Header is required",value:"Value","value-required":"Value is required","topic-pattern":"Topic pattern","topic-pattern-required":"Topic pattern is required","mqtt-topic-pattern-hint":"MQTT topic pattern, use ${metaKeyName} to substitute variables from metadata","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","topic-arn-pattern-hint":"Topic ARN pattern, use ${metaKeyName} to substitute variables from metadata","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","queue-url-pattern-hint":"Queue URL pattern, use ${metaKeyName} to substitute variables from metadata","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","message-attributes":"Message attributes","message-attributes-hint":"Use ${metaKeyName} in name/value fields to substitute variables from metadata","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","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","username-required":"Username is required.","password-required":"Password is required.","ca-cert":"CA certificate file *","private-key":"Private key file *",cert:"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","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"},"key-val":{key:"Key",value:"Value","remove-entry":"Remove entry","add-entry":"Add entry"}}};angular.merge(e.en_US,t)}Object.defineProperty(t,"__esModule",{value:!0}),t.default=n},function(e,t,n){"use strict";function a(e){return e&&e.__esModule?e:{default:e}}function r(e,t){(0,o.default)(t);for(var n in t){var a=t[n];e.translations(n,a)}}r.$inject=["$translateProvider","locales"],Object.defineProperty(t,"__esModule",{value:!0}),t.default=r;var i=n(73),o=a(i)},function(e,t){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=angular.module("thingsboard.ruleChain.config.types",[]).constant("ruleNodeTypes",{messageType:{POST_ATTRIBUTES_REQUEST:{name:"Post attributes",value:"POST_ATTRIBUTES_REQUEST"},POST_TELEMETRY_REQUEST:{name:"Post telemetry",value:"POST_TELEMETRY_REQUEST"},TO_SERVER_RPC_REQUEST:{name:"RPC Request from Device",value:"TO_SERVER_RPC_REQUEST"},RPC_CALL_FROM_SERVER_TO_DEVICE:{name:"RPC Request to Device",value:"RPC_CALL_FROM_SERVER_TO_DEVICE"},ACTIVITY_EVENT:{name:"Activity Event",value:"ACTIVITY_EVENT"},INACTIVITY_EVENT:{name:"Inactivity Event",value:"INACTIVITY_EVENT"},CONNECT_EVENT:{name:"Connect Event",value:"CONNECT_EVENT"},DISCONNECT_EVENT:{name:"Disconnect Event",value:"DISCONNECT_EVENT"},ENTITY_CREATED:{name:"Entity Created",value:"ENTITY_CREATED"},ENTITY_UPDATED:{name:"Entity Updated",value:"ENTITY_UPDATED"},ENTITY_DELETED:{name:"Entity Deleted",value:"ENTITY_DELETED"},ENTITY_ASSIGNED:{name:"Entity Assigned",value:"ENTITY_ASSIGNED"},ENTITY_UNASSIGNED:{name:"Entity Unassigned",value:"ENTITY_UNASSIGNED"},ATTRIBUTES_UPDATED:{name:"Attributes Updated",value:"ATTRIBUTES_UPDATED"},ATTRIBUTES_DELETED:{name:"Attributes Deleted",value:"ATTRIBUTES_DELETED"}},originatorSource:{CUSTOMER:{name:"tb.rulenode.originator-customer",value:"CUSTOMER"},TENANT:{name:"tb.rulenode.originator-tenant",value:"TENANT"},RELATED:{name:"tb.rulenode.originator-related",value:"RELATED"}},httpRequestType:["GET","POST","PUT","DELETE"],sqsQueueType:{STANDARD:{name:"tb.rulenode.sqs-queue-standard",value:"STANDARD"},FIFO:{name:"tb.rulenode.sqs-queue-fifo",value:"FIFO"}},mqttCredentialTypes:{anonymous:{value:"anonymous",name:"tb.rulenode.credentials-anonymous"},basic:{value:"basic",name:"tb.rulenode.credentials-basic"},"cert.PEM":{value:"cert.PEM",name:"tb.rulenode.credentials-pem"}}}).name}])); +!function(e){function t(r){if(n[r])return n[r].exports;var a=n[r]={exports:{},id:r,loaded:!1};return e[r].call(a.exports,a,a.exports,t),a.loaded=!0,a.exports}var n={};return t.m=e,t.c=n,t.p="/static/",t(0)}(function(e){for(var t in e)if(Object.prototype.hasOwnProperty.call(e,t))switch(typeof e[t]){case"function":break;case"object":e[t]=function(t){var n=t.slice(1),r=e[t[0]];return function(e,t,a){r.apply(this,[e,t,a].concat(n))}}(e[t]);break;default:e[t]=e[e[t]]}return e}([function(e,t,n){e.exports=n(76)},function(e,t){},1,1,1,function(e,t){e.exports='
{{scope.name | translate}}
'},function(e,t){e.exports="
{{ 'tb.rulenode.test-details-function' | translate }}
tb.rulenode.alarm-type-required
"},function(e,t){e.exports="
{{ 'tb.rulenode.test-details-function' | translate }}
tb.rulenode.alarm-type-required
{{ severity.name | translate}}
tb.rulenode.alarm-severity-required
{{ 'tb.rulenode.propagate' | translate }}
"},function(e,t){e.exports="
tb.rulenode.message-count-required
tb.rulenode.min-message-count-message
tb.rulenode.period-seconds-required
tb.rulenode.min-period-seconds-message
{{ 'tb.rulenode.test-generator-function' | translate }}
"},function(e,t){e.exports='
tb.rulenode.topic-pattern-required
tb.rulenode.bootstrap-servers-required
tb.rulenode.min-retries-message
tb.rulenode.min-batch-size-bytes-message
tb.rulenode.min-linger-ms-message
tb.rulenode.min-buffer-memory-bytes-message
{{ ackValue }}
tb.rulenode.key-serializer-required
tb.rulenode.value-serializer-required
'},function(e,t){e.exports="
{{ 'tb.rulenode.test-to-string-function' | translate }}
"},function(e,t){e.exports='
tb.rulenode.topic-pattern-required
tb.rulenode.mqtt-topic-pattern-hint
tb.rulenode.host-required
tb.rulenode.port-required
tb.rulenode.port-range
tb.rulenode.port-range
tb.rulenode.connect-timeout-required
tb.rulenode.connect-timeout-range
tb.rulenode.connect-timeout-range
{{ \'tb.rulenode.clean-session\' | translate }} {{ \'tb.rulenode.enable-ssl\' | translate }}
{{ \'tb.rulenode.credentials\' | translate }}
{{ ruleNodeTypes.mqttCredentialTypes[configuration.credentials.type].name | translate }}
{{ \'tb.rulenode.credentials\' | translate }}
{{ ruleNodeTypes.mqttCredentialTypes[configuration.credentials.type].name | translate }}
{{credentialsValue.name | translate}}
tb.rulenode.credentials-type-required
tb.rulenode.username-required
tb.rulenode.password-required
'},function(e,t){e.exports="
tb.rulenode.period-seconds-required
tb.rulenode.min-period-0-seconds-message
tb.rulenode.max-pending-messages-required
tb.rulenode.max-pending-messages-range
tb.rulenode.max-pending-messages-range
"},function(e,t){e.exports='
{{ property }}
tb.rulenode.host-required
tb.rulenode.port-required
tb.rulenode.port-range
tb.rulenode.port-range
{{ \'tb.rulenode.automatic-recovery\' | translate }}
tb.rulenode.min-connection-timeout-ms-message
tb.rulenode.min-handshake-timeout-ms-message
'},function(e,t){e.exports='
tb.rulenode.endpoint-url-pattern-required
tb.rulenode.endpoint-url-pattern-hint
{{ type }}
tb.rulenode.headers-hint
'},function(e,t){e.exports="
"},function(e,t){e.exports="
tb.rulenode.timeout-required
tb.rulenode.min-timeout-message
"},function(e,t){e.exports='
{{ \'tb.rulenode.use-system-smtp-settings\' | translate }}
{{smtpProtocol.toUpperCase()}}
tb.rulenode.smtp-host-required
tb.rulenode.smtp-port-required
tb.rulenode.smtp-port-range
tb.rulenode.smtp-port-range
tb.rulenode.timeout-required
tb.rulenode.min-timeout-msec-message
{{ \'tb.rulenode.enable-tls\' | translate }}
'},function(e,t){e.exports="
tb.rulenode.topic-arn-pattern-required
tb.rulenode.topic-arn-pattern-hint
tb.rulenode.aws-access-key-id-required
tb.rulenode.aws-secret-access-key-required
tb.rulenode.aws-region-required
"},function(e,t){e.exports='
{{ type.name | translate }}
tb.rulenode.queue-url-pattern-required
tb.rulenode.queue-url-pattern-hint
tb.rulenode.min-delay-seconds-message
tb.rulenode.max-delay-seconds-message
tb.rulenode.message-attributes-hint
tb.rulenode.aws-access-key-id-required
tb.rulenode.aws-secret-access-key-required
tb.rulenode.aws-region-required
'},function(e,t){e.exports="
tb.rulenode.default-ttl-required
tb.rulenode.min-default-ttl-message
"},function(e,t){e.exports='
{{ (\'relation.search-direction.\' + direction) | translate}}
relation.relation-type
device.device-types
'; +},function(e,t){e.exports="
{{ 'tb.rulenode.latest-telemetry' | translate }}
"},function(e,t){e.exports='
'},function(e,t){e.exports='
'},function(e,t){e.exports='
'},function(e,t){e.exports="
{{ 'tb.rulenode.latest-telemetry' | translate }}
"},22,function(e,t){e.exports="
{{ ('relation.search-direction.' + direction) | translate}}
"},function(e,t){e.exports='
{{item}}
tb.rulenode.no-message-types-found
tb.rulenode.no-message-type-matching tb.rulenode.create-new-message-type
{{$chip.name}}
'},function(e,t){e.exports='
'},function(e,t){e.exports="
{{ 'tb.rulenode.test-filter-function' | translate }}
"},function(e,t){e.exports="
{{ 'tb.rulenode.test-switch-function' | translate }}
"},function(e,t){e.exports='
{{ keyText }} {{ valText }}  
{{keyRequiredText}}
{{valRequiredText}}
{{ \'tb.key-val.remove-entry\' | translate }} close
{{ \'tb.key-val.add-entry\' | translate }} add {{ \'action.add\' | translate }}
'},function(e,t){e.exports="
{{ ('relation.search-direction.' + direction) | translate}}
relation.relation-filters
"},function(e,t){e.exports='
{{ source.name | translate}}
'},function(e,t){e.exports="
{{ 'tb.rulenode.test-transformer-function' | translate }}
"},function(e,t){e.exports="
tb.rulenode.from-template-required
tb.rulenode.from-template-hint
tb.rulenode.to-template-required
tb.rulenode.mail-address-list-template-hint
tb.rulenode.mail-address-list-template-hint
tb.rulenode.mail-address-list-template-hint
tb.rulenode.subject-template-required
tb.rulenode.subject-template-hint
tb.rulenode.body-template-required
tb.rulenode.body-template-hint
"},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function a(e,t){var n=function(n,r,a,i){var l=o.default;r.html(l),n.types=t,n.$watch("configuration",function(e,t){angular.equals(e,t)||i.$setViewValue(n.configuration)}),i.$render=function(){n.configuration=i.$viewValue},e(r.contents())(n)};return{restrict:"E",require:"^ngModel",scope:{},link:n}}a.$inject=["$compile","types"],Object.defineProperty(t,"__esModule",{value:!0}),t.default=a;var i=n(5),o=r(i)},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function a(e,t,n,r){var a=function(a,i,l,s){var u=o.default;i.html(u),a.types=n,a.$watch("configuration",function(e,t){angular.equals(e,t)||s.$setViewValue(a.configuration)}),s.$render=function(){a.configuration=s.$viewValue},a.testDetailsBuildJs=function(e){var n=angular.copy(a.configuration.alarmDetailsBuildJs);r.testNodeScript(e,n,"json",t.instant("tb.rulenode.details")+"","Details",["msg","metadata","msgType"],a.ruleNodeId).then(function(e){a.configuration.alarmDetailsBuildJs=e,s.$setDirty()})},e(i.contents())(a)};return{restrict:"E",require:"^ngModel",scope:{ruleNodeId:"="},link:a}}a.$inject=["$compile","$translate","types","ruleNodeScriptTest"],Object.defineProperty(t,"__esModule",{value:!0}),t.default=a;var i=n(6),o=r(i)},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function a(e,t,n,r){var a=function(a,i,l,s){var u=o.default;i.html(u),a.types=n,a.$watch("configuration",function(e,t){angular.equals(e,t)||s.$setViewValue(a.configuration)}),s.$render=function(){a.configuration=s.$viewValue},a.testDetailsBuildJs=function(e){var n=angular.copy(a.configuration.alarmDetailsBuildJs);r.testNodeScript(e,n,"json",t.instant("tb.rulenode.details")+"","Details",["msg","metadata","msgType"],a.ruleNodeId).then(function(e){a.configuration.alarmDetailsBuildJs=e,s.$setDirty()})},e(i.contents())(a)};return{restrict:"E",require:"^ngModel",scope:{ruleNodeId:"="},link:a}}a.$inject=["$compile","$translate","types","ruleNodeScriptTest"],Object.defineProperty(t,"__esModule",{value:!0}),t.default=a;var i=n(7),o=r(i)},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function a(e,t,n,r){var a=function(a,i,l,s){var u=o.default;i.html(u),a.types=n,a.originator=null,a.$watch("configuration",function(e,t){angular.equals(e,t)||s.$setViewValue(a.configuration)}),s.$render=function(){a.configuration=s.$viewValue,a.configuration.originatorId&&a.configuration.originatorType?a.originator={id:a.configuration.originatorId,entityType:a.configuration.originatorType}:a.originator=null,a.$watch("originator",function(e,t){angular.equals(e,t)||(a.originator?(s.$viewValue.originatorId=a.originator.id,s.$viewValue.originatorType=a.originator.entityType):(s.$viewValue.originatorId=null,s.$viewValue.originatorType=null))},!0)},a.testScript=function(e){var n=angular.copy(a.configuration.jsScript);r.testNodeScript(e,n,"generate",t.instant("tb.rulenode.generator")+"","Generate",["prevMsg","prevMetadata","prevMsgType"],a.ruleNodeId).then(function(e){a.configuration.jsScript=e,s.$setDirty()})},e(i.contents())(a)};return{restrict:"E",require:"^ngModel",scope:{ruleNodeId:"="},link:a}}a.$inject=["$compile","$translate","types","ruleNodeScriptTest"],Object.defineProperty(t,"__esModule",{value:!0}),t.default=a,n(1);var i=n(8),o=r(i)},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}Object.defineProperty(t,"__esModule",{value:!0});var a=n(54),i=r(a),o=n(38),l=r(o),s=n(41),u=r(s),d=n(40),c=r(d),m=n(39),g=r(m),p=n(44),f=r(p),b=n(49),v=r(b),y=n(50),q=r(y),h=n(48),$=r(h),k=n(43),T=r(k),w=n(52),x=r(w),C=n(53),M=r(C),_=n(47),S=r(_),N=n(45),V=r(N),j=n(51),P=r(j),F=n(46),E=r(F);t.default=angular.module("thingsboard.ruleChain.config.action",[]).directive("tbActionNodeTimeseriesConfig",i.default).directive("tbActionNodeAttributesConfig",l.default).directive("tbActionNodeGeneratorConfig",u.default).directive("tbActionNodeCreateAlarmConfig",c.default).directive("tbActionNodeClearAlarmConfig",g.default).directive("tbActionNodeLogConfig",f.default).directive("tbActionNodeRpcReplyConfig",v.default).directive("tbActionNodeRpcRequestConfig",q.default).directive("tbActionNodeRestApiCallConfig",$.default).directive("tbActionNodeKafkaConfig",T.default).directive("tbActionNodeSnsConfig",x.default).directive("tbActionNodeSqsConfig",M.default).directive("tbActionNodeRabbitMqConfig",S.default).directive("tbActionNodeMqttConfig",V.default).directive("tbActionNodeSendEmailConfig",P.default).directive("tbActionNodeMsgDelayConfig",E.default).name},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function a(e){var t=function(t,n,r,a){var i=o.default;n.html(i),t.ackValues=["all","-1","0","1"],t.$watch("configuration",function(e,n){angular.equals(e,n)||a.$setViewValue(t.configuration)}),a.$render=function(){t.configuration=a.$viewValue},e(n.contents())(t)};return{restrict:"E",require:"^ngModel",scope:{},link:t}}a.$inject=["$compile"],Object.defineProperty(t,"__esModule",{value:!0}),t.default=a;var i=n(9),o=r(i)},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function a(e,t,n){var r=function(r,a,i,l){var s=o.default;a.html(s),r.$watch("configuration",function(e,t){angular.equals(e,t)||l.$setViewValue(r.configuration)}),l.$render=function(){r.configuration=l.$viewValue},r.testScript=function(e){var a=angular.copy(r.configuration.jsScript);n.testNodeScript(e,a,"string",t.instant("tb.rulenode.to-string")+"","ToString",["msg","metadata","msgType"],r.ruleNodeId).then(function(e){r.configuration.jsScript=e,l.$setDirty()})},e(a.contents())(r)};return{restrict:"E",require:"^ngModel",scope:{ruleNodeId:"="},link:r}}a.$inject=["$compile","$translate","ruleNodeScriptTest"],Object.defineProperty(t,"__esModule",{value:!0}),t.default=a;var i=n(10),o=r(i)},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function a(e,t,n){var r=function(r,a,i,l){var s=o.default;a.html(s),r.$mdExpansionPanel=t,r.ruleNodeTypes=n,r.credentialsTypeChanged=function(){var e=r.configuration.credentials.type;r.configuration.credentials={},r.configuration.credentials.type=e,r.updateValidity()},r.certFileAdded=function(e,t){var n=new FileReader;n.onload=function(n){r.$apply(function(){if(n.target.result){l.$setDirty();var a=n.target.result;a&&a.length>0&&("caCert"==t&&(r.configuration.credentials.caCertFileName=e.name,r.configuration.credentials.caCert=a),"privateKey"==t&&(r.configuration.credentials.privateKeyFileName=e.name,r.configuration.credentials.privateKey=a),"Cert"==t&&(r.configuration.credentials.certFileName=e.name,r.configuration.credentials.cert=a)),r.updateValidity()}})},n.readAsText(e.file)},r.clearCertFile=function(e){l.$setDirty(),"caCert"==e&&(r.configuration.credentials.caCertFileName=null,r.configuration.credentials.caCert=null),"privateKey"==e&&(r.configuration.credentials.privateKeyFileName=null,r.configuration.credentials.privateKey=null),"Cert"==e&&(r.configuration.credentials.certFileName=null,r.configuration.credentials.cert=null),r.updateValidity()},r.updateValidity=function(){var e=!0,t=r.configuration.credentials;t.type==n.mqttCredentialTypes["cert.PEM"].value&&(t.caCert&&t.cert&&t.privateKey||(e=!1)),l.$setValidity("Certs",e)},r.$watch("configuration",function(e,t){angular.equals(e,t)||l.$setViewValue(r.configuration)}),l.$render=function(){r.configuration=l.$viewValue},e(a.contents())(r)};return{restrict:"E",require:"^ngModel",scope:{readonly:"=ngReadonly"},link:r}}a.$inject=["$compile","$mdExpansionPanel","ruleNodeTypes"],Object.defineProperty(t,"__esModule",{value:!0}),t.default=a,n(2);var i=n(11),o=r(i)},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function a(e){var t=function(t,n,r,a){var i=o.default;n.html(i),t.$watch("configuration",function(e,n){angular.equals(e,n)||a.$setViewValue(t.configuration)}),a.$render=function(){t.configuration=a.$viewValue},e(n.contents())(t)};return{restrict:"E",require:"^ngModel",scope:{},link:t}}a.$inject=["$compile"],Object.defineProperty(t,"__esModule",{value:!0}),t.default=a;var i=n(12),o=r(i)},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function a(e){var t=function(t,n,r,a){var i=o.default;n.html(i),t.messageProperties=[null,"BASIC","TEXT_PLAIN","MINIMAL_BASIC","MINIMAL_PERSISTENT_BASIC","PERSISTENT_BASIC","PERSISTENT_TEXT_PLAIN"],t.$watch("configuration",function(e,n){angular.equals(e,n)||a.$setViewValue(t.configuration)}),a.$render=function(){t.configuration=a.$viewValue},e(n.contents())(t)};return{restrict:"E",require:"^ngModel",scope:{readonly:"=ngReadonly"},link:t}}a.$inject=["$compile"],Object.defineProperty(t,"__esModule",{value:!0}),t.default=a;var i=n(13),o=r(i)},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function a(e,t){var n=function(n,r,a,i){var l=o.default;r.html(l),n.ruleNodeTypes=t,n.$watch("configuration",function(e,t){angular.equals(e,t)||i.$setViewValue(n.configuration)}),i.$render=function(){n.configuration=i.$viewValue},e(r.contents())(n)};return{restrict:"E",require:"^ngModel",scope:{},link:n}}a.$inject=["$compile","ruleNodeTypes"],Object.defineProperty(t,"__esModule",{value:!0}),t.default=a;var i=n(14),o=r(i)},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function a(e){var t=function(t,n,r,a){var i=o.default;n.html(i),t.$watch("configuration",function(e,n){angular.equals(e,n)||a.$setViewValue(t.configuration)}),a.$render=function(){t.configuration=a.$viewValue},e(n.contents())(t)};return{restrict:"E",require:"^ngModel",scope:{},link:t}}a.$inject=["$compile"],Object.defineProperty(t,"__esModule",{value:!0}),t.default=a;var i=n(15),o=r(i)},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function a(e){var t=function(t,n,r,a){var i=o.default;n.html(i),t.$watch("configuration",function(e,n){angular.equals(e,n)||a.$setViewValue(t.configuration)}),a.$render=function(){t.configuration=a.$viewValue},e(n.contents())(t)};return{restrict:"E",require:"^ngModel",scope:{},link:t}}a.$inject=["$compile"],Object.defineProperty(t,"__esModule",{value:!0}),t.default=a;var i=n(16),o=r(i)},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function a(e){var t=function(t,n,r,a){var i=o.default;n.html(i),t.smtpProtocols=["smtp","smtps"],t.$watch("configuration",function(e,n){angular.equals(e,n)||a.$setViewValue(t.configuration)}),a.$render=function(){t.configuration=a.$viewValue},e(n.contents())(t)};return{restrict:"E",require:"^ngModel",scope:{readonly:"=ngReadonly"},link:t}}a.$inject=["$compile"],Object.defineProperty(t,"__esModule",{value:!0}),t.default=a;var i=n(17),o=r(i)},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function a(e){var t=function(t,n,r,a){var i=o.default;n.html(i),t.$watch("configuration",function(e,n){angular.equals(e,n)||a.$setViewValue(t.configuration)}),a.$render=function(){t.configuration=a.$viewValue},e(n.contents())(t)};return{restrict:"E",require:"^ngModel",scope:{},link:t}}a.$inject=["$compile"],Object.defineProperty(t,"__esModule",{value:!0}),t.default=a;var i=n(18),o=r(i)},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function a(e,t){var n=function(n,r,a,i){var l=o.default;r.html(l),n.ruleNodeTypes=t,n.$watch("configuration",function(e,t){angular.equals(e,t)||i.$setViewValue(n.configuration)}),i.$render=function(){n.configuration=i.$viewValue},e(r.contents())(n)};return{restrict:"E",require:"^ngModel",scope:{readonly:"=ngReadonly"},link:n}}a.$inject=["$compile","ruleNodeTypes"],Object.defineProperty(t,"__esModule",{value:!0}),t.default=a;var i=n(19),o=r(i)},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function a(e){var t=function(t,n,r,a){var i=o.default;n.html(i),t.$watch("configuration",function(e,n){angular.equals(e,n)||a.$setViewValue(t.configuration)}),a.$render=function(){t.configuration=a.$viewValue},e(n.contents())(t)};return{restrict:"E",require:"^ngModel",scope:{},link:t}}a.$inject=["$compile"],Object.defineProperty(t,"__esModule",{value:!0}),t.default=a;var i=n(20),o=r(i)},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function a(e,t){var n=function(n,r,a,i){var l=o.default;r.html(l),n.types=t,n.$watch("query",function(e,t){angular.equals(e,t)||i.$setViewValue(n.query)}),i.$render=function(){n.query=i.$viewValue},e(r.contents())(n)};return{restrict:"E",require:"^ngModel",scope:{},link:n}}a.$inject=["$compile","types"],Object.defineProperty(t,"__esModule",{value:!0}),t.default=a;var i=n(21),o=r(i)},function(e,t){"use strict";function n(e){var t=function(t,n,r,a){n.html("
"),t.$watch("configuration",function(e,n){angular.equals(e,n)||a.$setViewValue(t.configuration)}),a.$render=function(){t.configuration=a.$viewValue},e(n.contents())(t)};return{restrict:"E",require:"^ngModel",scope:{},link:t}}n.$inject=["$compile"],Object.defineProperty(t,"__esModule",{value:!0}),t.default=n},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function a(e){var t=function(t,n,r,a){var i=o.default;n.html(i),t.$watch("configuration",function(e,n){angular.equals(e,n)||a.$setViewValue(t.configuration)}),a.$render=function(){t.configuration=a.$viewValue},e(n.contents())(t)};return{restrict:"E",require:"^ngModel",scope:{},link:t}}a.$inject=["$compile"],Object.defineProperty(t,"__esModule",{value:!0}),t.default=a;var i=n(22),o=r(i)},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function a(e,t){var n=function(n,r,a,i){var l=o.default;r.html(l);var s=186;n.separatorKeys=[t.KEY_CODE.ENTER,t.KEY_CODE.COMMA,s],n.$watch("configuration",function(e,t){angular.equals(e,t)||i.$setViewValue(n.configuration)}),i.$render=function(){n.configuration=i.$viewValue},e(r.contents())(n)};return{restrict:"E",require:"^ngModel",scope:{},link:n}}a.$inject=["$compile","$mdConstant"],Object.defineProperty(t,"__esModule",{value:!0}),t.default=a;var i=n(23),o=r(i)},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}Object.defineProperty(t,"__esModule",{value:!0});var a=n(60),i=r(a),o=n(61),l=r(o),s=n(58),u=r(s),d=n(62),c=r(d),m=n(57),g=r(m),p=n(63),f=r(p);t.default=angular.module("thingsboard.ruleChain.config.enrichment",[]).directive("tbEnrichmentNodeOriginatorAttributesConfig",i.default).directive("tbEnrichmentNodeOriginatorFieldsConfig",l.default).directive("tbEnrichmentNodeDeviceAttributesConfig",u.default).directive("tbEnrichmentNodeRelatedAttributesConfig",c.default).directive("tbEnrichmentNodeCustomerAttributesConfig",g.default).directive("tbEnrichmentNodeTenantAttributesConfig",f.default).name},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function a(e,t){var n=function(n,r,a,i){var l=o.default;r.html(l);var s=186;n.separatorKeys=[t.KEY_CODE.ENTER,t.KEY_CODE.COMMA,s],n.$watch("configuration",function(e,t){angular.equals(e,t)||i.$setViewValue(n.configuration)}),i.$render=function(){n.configuration=i.$viewValue},e(r.contents())(n)};return{restrict:"E",require:"^ngModel",scope:{},link:n}}a.$inject=["$compile","$mdConstant"],Object.defineProperty(t,"__esModule",{value:!0}),t.default=a;var i=n(24),o=r(i)},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function a(e){var t=function(t,n,r,a){var i=o.default;n.html(i),t.$watch("configuration",function(e,n){angular.equals(e,n)||a.$setViewValue(t.configuration)}),a.$render=function(){t.configuration=a.$viewValue},e(n.contents())(t)};return{restrict:"E",require:"^ngModel",scope:{},link:t}}a.$inject=["$compile"],Object.defineProperty(t,"__esModule",{value:!0}),t.default=a;var i=n(25),o=r(i)},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function a(e){var t=function(t,n,r,a){var i=o.default;n.html(i),t.$watch("configuration",function(e,n){angular.equals(e,n)||a.$setViewValue(t.configuration)}),a.$render=function(){t.configuration=a.$viewValue},e(n.contents())(t)};return{restrict:"E",require:"^ngModel",scope:{},link:t}}a.$inject=["$compile"],Object.defineProperty(t,"__esModule",{value:!0}),t.default=a;var i=n(26),o=r(i)},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function a(e){var t=function(t,n,r,a){var i=o.default;n.html(i),t.$watch("configuration",function(e,n){angular.equals(e,n)||a.$setViewValue(t.configuration)}),a.$render=function(){t.configuration=a.$viewValue},e(n.contents())(t)};return{restrict:"E",require:"^ngModel",scope:{},link:t}}a.$inject=["$compile"],Object.defineProperty(t,"__esModule",{ +value:!0}),t.default=a;var i=n(27),o=r(i)},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function a(e,t){var n=function(n,r,a,i){var l=o.default;r.html(l),n.types=t,n.$watch("configuration",function(e,t){angular.equals(e,t)||i.$setViewValue(n.configuration)}),i.$render=function(){n.configuration=i.$viewValue},e(r.contents())(n)};return{restrict:"E",require:"^ngModel",scope:{},link:n}}a.$inject=["$compile","types"],Object.defineProperty(t,"__esModule",{value:!0}),t.default=a;var i=n(28),o=r(i)},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}Object.defineProperty(t,"__esModule",{value:!0});var a=n(68),i=r(a),o=n(66),l=r(o),s=n(69),u=r(s),d=n(64),c=r(d),m=n(67),g=r(m);t.default=angular.module("thingsboard.ruleChain.config.filter",[]).directive("tbFilterNodeScriptConfig",i.default).directive("tbFilterNodeMessageTypeConfig",l.default).directive("tbFilterNodeSwitchConfig",u.default).directive("tbFilterNodeCheckRelationConfig",c.default).directive("tbFilterNodeOriginatorTypeConfig",g.default).name},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function a(e,t,n){var r=function(r,a,i,l){function s(){if(l.$viewValue){for(var e=[],t=0;t-1&&t.kvList.splice(e,1)}function l(){t.kvList||(t.kvList=[]),t.kvList.push({key:"",value:""})}function s(){var e={};t.kvList.forEach(function(t){t.key&&(e[t.key]=t.value)}),a.$setViewValue(e),u()}function u(){var e=!0;t.required&&!t.kvList.length&&(e=!1),a.$setValidity("kvMap",e)}var d=o.default;n.html(d),t.ngModelCtrl=a,t.removeKeyVal=i,t.addKeyVal=l,t.kvList=[],t.$watch("query",function(e,n){angular.equals(e,n)||a.$setViewValue(t.query)}),a.$render=function(){if(a.$viewValue){var e=a.$viewValue;t.kvList.length=0;for(var n in e)t.kvList.push({key:n,value:e[n]})}t.$watch("kvList",function(e,t){angular.equals(e,t)||s()},!0),u()},e(n.contents())(t)};return{restrict:"E",require:"^ngModel",scope:{required:"=ngRequired",disabled:"=ngDisabled",requiredText:"=",keyText:"=",keyRequiredText:"=",valText:"=",valRequiredText:"="},link:t}}a.$inject=["$compile"],Object.defineProperty(t,"__esModule",{value:!0}),t.default=a;var i=n(33),o=r(i);n(4)},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function a(e,t){var n=function(n,r,a,i){var l=o.default;r.html(l),n.types=t,n.$watch("query",function(e,t){angular.equals(e,t)||i.$setViewValue(n.query)}),i.$render=function(){n.query=i.$viewValue},e(r.contents())(n)};return{restrict:"E",require:"^ngModel",scope:{},link:n}}a.$inject=["$compile","types"],Object.defineProperty(t,"__esModule",{value:!0}),t.default=a;var i=n(34),o=r(i)},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function a(e,t){var n=function(n,r,a,i){var l=o.default;r.html(l),n.ruleNodeTypes=t,n.$watch("configuration",function(e,t){angular.equals(e,t)||i.$setViewValue(n.configuration)}),i.$render=function(){n.configuration=i.$viewValue},e(r.contents())(n)};return{restrict:"E",require:"^ngModel",scope:{},link:n}}a.$inject=["$compile","ruleNodeTypes"],Object.defineProperty(t,"__esModule",{value:!0}),t.default=a;var i=n(35),o=r(i)},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}Object.defineProperty(t,"__esModule",{value:!0});var a=n(72),i=r(a),o=n(74),l=r(o),s=n(75),u=r(s);t.default=angular.module("thingsboard.ruleChain.config.transform",[]).directive("tbTransformationNodeChangeOriginatorConfig",i.default).directive("tbTransformationNodeScriptConfig",l.default).directive("tbTransformationNodeToEmailConfig",u.default).name},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function a(e,t,n){var r=function(r,a,i,l){var s=o.default;a.html(s),r.$watch("configuration",function(e,t){angular.equals(e,t)||l.$setViewValue(r.configuration)}),l.$render=function(){r.configuration=l.$viewValue},r.testScript=function(e){var a=angular.copy(r.configuration.jsScript);n.testNodeScript(e,a,"update",t.instant("tb.rulenode.transformer")+"","Transform",["msg","metadata","msgType"],r.ruleNodeId).then(function(e){r.configuration.jsScript=e,l.$setDirty()})},e(a.contents())(r)};return{restrict:"E",require:"^ngModel",scope:{ruleNodeId:"="},link:r}}a.$inject=["$compile","$translate","ruleNodeScriptTest"],Object.defineProperty(t,"__esModule",{value:!0}),t.default=a;var i=n(36),o=r(i)},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function a(e){var t=function(t,n,r,a){var i=o.default;n.html(i),t.$watch("configuration",function(e,n){angular.equals(e,n)||a.$setViewValue(t.configuration)}),a.$render=function(){t.configuration=a.$viewValue},e(n.contents())(t)};return{restrict:"E",require:"^ngModel",scope:{},link:t}}a.$inject=["$compile"],Object.defineProperty(t,"__esModule",{value:!0}),t.default=a;var i=n(37),o=r(i)},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}Object.defineProperty(t,"__esModule",{value:!0});var a=n(79),i=r(a),o=n(65),l=r(o),s=n(59),u=r(s),d=n(73),c=r(d),m=n(42),g=r(m),p=n(56),f=r(p),b=n(71),v=r(b),y=n(55),q=r(y),h=n(70),$=r(h),k=n(78),T=r(k);t.default=angular.module("thingsboard.ruleChain.config",[i.default,l.default,u.default,c.default,g.default]).directive("tbNodeEmptyConfig",f.default).directive("tbRelationsQueryConfig",v.default).directive("tbDeviceRelationsQueryConfig",q.default).directive("tbKvMapConfig",$.default).config(T.default).name},function(e,t){"use strict";function n(e){var t={tb:{rulenode:{filter:"Filter",switch:"Switch","message-type":"Message type","message-type-required":"Message type is required.","message-types-filter":"Message types filter","no-message-types-found":"No message types found","no-message-type-matching":"'{{messageType}}' not found.","create-new-message-type":"Create a new one!","message-types-required":"Message types are required.","client-attributes":"Client attributes","shared-attributes":"Shared attributes","server-attributes":"Server attributes","latest-timeseries":"Latest timeseries","relations-query":"Relations query","device-relations-query":"Device relations query","max-relation-level":"Max relation level","unlimited-level":"Unlimited level","latest-telemetry":"Latest telemetry","attr-mapping":"Attributes mapping","source-attribute":"Source attribute","source-attribute-required":"Source attribute is required.","source-telemetry":"Source telemetry","source-telemetry-required":"Source telemetry is required.","target-attribute":"Target attribute","target-attribute-required":"Target attribute is required.","attr-mapping-required":"At least one attribute mapping should be specified.","fields-mapping":"Fields mapping","fields-mapping-required":"At least one field mapping should be specified.","source-field":"Source field","source-field-required":"Source field is required.","originator-source":"Originator source","originator-customer":"Customer","originator-tenant":"Tenant","originator-related":"Related","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.","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","alarm-type-required":"Alarm type is required.","alarm-severity":"Alarm severity","alarm-severity-required":"Alarm severity is required",propagate:"Propagate",condition:"Condition",details:"Details","to-string":"To string","test-to-string-function":"Test to string function","from-template":"From Template","from-template-required":"From Template is required","from-template-hint":"From address template, use ${metaKeyName} to substitute variables from metadata","to-template":"To Template","to-template-required":"To Template is required","mail-address-list-template-hint":"Comma separated address list, use ${metaKeyName} to substitute variables from metadata","cc-template":"Cc Template","bcc-template":"Bcc Template","subject-template":"Subject Template","subject-template-required":"Subject Template is required","subject-template-hint":"Mail subject template, use ${metaKeyName} to substitute variables from metadata","body-template":"Body Template","body-template-required":"Body Template is required","body-template-hint":"Mail body template, use ${metaKeyName} to substitute variables from metadata","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","endpoint-url-pattern-hint":"HTTP URL address pattern, use ${metaKeyName} to substitute variables from metadata","request-method":"Request method",headers:"Headers","headers-hint":"Use ${metaKeyName} in header/value fields to substitute variables from metadata",header:"Header","header-required":"Header is required",value:"Value","value-required":"Value is required","topic-pattern":"Topic pattern","topic-pattern-required":"Topic pattern is required","mqtt-topic-pattern-hint":"MQTT topic pattern, use ${metaKeyName} to substitute variables from metadata","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","topic-arn-pattern-hint":"Topic ARN pattern, use ${metaKeyName} to substitute variables from metadata","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","queue-url-pattern-hint":"Queue URL pattern, use ${metaKeyName} to substitute variables from metadata","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","message-attributes":"Message attributes","message-attributes-hint":"Use ${metaKeyName} in name/value fields to substitute variables from metadata","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","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","username-required":"Username is required.","password-required":"Password is required.","ca-cert":"CA certificate file *","private-key":"Private key file *",cert:"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","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","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"},"key-val":{key:"Key",value:"Value","remove-entry":"Remove entry","add-entry":"Add entry"}}};e.translations("en_US",t)}Object.defineProperty(t,"__esModule",{value:!0}),t.default=n},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function a(e){(0,o.default)(e)}a.$inject=["$translateProvider"],Object.defineProperty(t,"__esModule",{value:!0}),t.default=a;var i=n(77),o=r(i)},function(e,t){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=angular.module("thingsboard.ruleChain.config.types",[]).constant("ruleNodeTypes",{originatorSource:{CUSTOMER:{name:"tb.rulenode.originator-customer",value:"CUSTOMER"},TENANT:{name:"tb.rulenode.originator-tenant",value:"TENANT"},RELATED:{name:"tb.rulenode.originator-related",value:"RELATED"}},httpRequestType:["GET","POST","PUT","DELETE"],sqsQueueType:{STANDARD:{name:"tb.rulenode.sqs-queue-standard",value:"STANDARD"},FIFO:{name:"tb.rulenode.sqs-queue-fifo",value:"FIFO"}},mqttCredentialTypes:{anonymous:{value:"anonymous",name:"tb.rulenode.credentials-anonymous"},basic:{value:"basic",name:"tb.rulenode.credentials-basic"},"cert.PEM":{value:"cert.PEM",name:"tb.rulenode.credentials-pem"}}}).name}])); //# sourceMappingURL=rulenode-core-config.js.map \ No newline at end of file diff --git a/tools/pom.xml b/tools/pom.xml index e5d443ad00..054eab03e2 100644 --- a/tools/pom.xml +++ b/tools/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 2.0.3 + 2.1.0-SNAPSHOT thingsboard org.thingsboard diff --git a/transport/coap/pom.xml b/transport/coap/pom.xml index 9b37184e4c..61e455a313 100644 --- a/transport/coap/pom.xml +++ b/transport/coap/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 2.0.3 + 2.1.0-SNAPSHOT transport org.thingsboard.transport diff --git a/transport/http/pom.xml b/transport/http/pom.xml index d9c46d26ae..3978620843 100644 --- a/transport/http/pom.xml +++ b/transport/http/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 2.0.3 + 2.1.0-SNAPSHOT transport org.thingsboard.transport diff --git a/transport/mqtt/pom.xml b/transport/mqtt/pom.xml index e0af4c0308..0bdb9a88c8 100644 --- a/transport/mqtt/pom.xml +++ b/transport/mqtt/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 2.0.3 + 2.1.0-SNAPSHOT transport org.thingsboard.transport diff --git a/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/GatewaySessionCtx.java b/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/GatewaySessionCtx.java index cfba944952..69ed17f3b0 100644 --- a/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/GatewaySessionCtx.java +++ b/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/GatewaySessionCtx.java @@ -17,6 +17,7 @@ package org.thingsboard.server.transport.mqtt.session; import com.google.gson.JsonArray; import com.google.gson.JsonElement; +import com.google.gson.JsonNull; import com.google.gson.JsonObject; import com.google.gson.JsonSyntaxException; import io.netty.channel.ChannelHandlerContext; @@ -240,7 +241,7 @@ public class GatewaySessionCtx { private String getDeviceType(JsonElement json) throws AdaptorException { JsonElement type = json.getAsJsonObject().get("type"); - return type == null ? DEFAULT_DEVICE_TYPE : type.getAsString(); + return type == null || type instanceof JsonNull ? DEFAULT_DEVICE_TYPE : type.getAsString(); } private JsonElement getJson(MqttPublishMessage mqttMsg) throws AdaptorException { diff --git a/transport/pom.xml b/transport/pom.xml index bb1420f096..03f3d11081 100644 --- a/transport/pom.xml +++ b/transport/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 2.0.3 + 2.1.0-SNAPSHOT thingsboard org.thingsboard diff --git a/ui/package.json b/ui/package.json index 328f47bcbb..06b7feea78 100644 --- a/ui/package.json +++ b/ui/package.json @@ -1,7 +1,7 @@ { "name": "thingsboard", "private": true, - "version": "2.0.3", + "version": "2.1.0", "description": "Thingsboard UI", "licenses": [ { @@ -15,7 +15,6 @@ }, "dependencies": { "@flowjs/ng-flow": "^2.7.1", - "ace-builds": "1.3.1", "angular": "1.5.8", "angular-animate": "1.5.8", "angular-aria": "1.5.8", @@ -37,17 +36,17 @@ "angular-socialshare": "^2.3.8", "angular-storage": "0.0.15", "angular-touch": "1.5.8", - "angular-translate": "2.13.1", - "angular-translate-handler-log": "2.13.1", - "angular-translate-interpolation-messageformat": "2.13.1", - "angular-translate-loader-static-files": "2.13.1", - "angular-translate-storage-cookie": "2.13.1", - "angular-translate-storage-local": "2.13.1", + "angular-translate": "2.18.1", + "angular-translate-handler-log": "2.18.1", + "angular-translate-interpolation-messageformat": "2.18.1", + "angular-translate-loader-static-files": "2.18.1", + "angular-translate-storage-cookie": "2.18.1", + "angular-translate-storage-local": "2.18.1", "angular-ui-ace": "^0.2.3", "angular-ui-router": "^0.3.1", "angular-websocket": "^2.0.1", "base64-js": "^1.2.1", - "brace": "^0.8.0", + "brace": "^0.10.0", "canvas-gauges": "^2.0.9", "clipboard": "^1.5.15", "compass-sass-mixins": "^0.12.7", @@ -96,6 +95,7 @@ "babel-loader": "^6.2.5", "babel-preset-es2015": "^6.14.0", "babel-preset-react": "^6.16.0", + "compression-webpack-plugin": "^1.1.11", "connect-history-api-fallback": "^1.3.0", "copy-webpack-plugin": "^3.0.1", "cross-env": "^3.2.4", @@ -127,7 +127,9 @@ "webpack-dev-middleware": "^1.6.1", "webpack-dev-server": "^1.15.1", "webpack-hot-middleware": "^2.12.2", - "webpack-material-design-icons": "^0.1.0" + "webpack-material-design-icons": "^0.1.0", + "directory-tree": "^2.1.0", + "jsonminify": "^0.4.1" }, "engine": "node >= 5.9.0", "nyc": { diff --git a/ui/pom.xml b/ui/pom.xml index b1c09196cc..8003eee1a2 100644 --- a/ui/pom.xml +++ b/ui/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 2.0.3 + 2.1.0-SNAPSHOT thingsboard org.thingsboard diff --git a/ui/src/app/api/alias-controller.js b/ui/src/app/api/alias-controller.js index 10b110743f..66781a8dbb 100644 --- a/ui/src/app/api/alias-controller.js +++ b/ui/src/app/api/alias-controller.js @@ -146,6 +146,7 @@ export default class AliasController { newDatasource.entityId = resolvedEntity.id; newDatasource.entityType = resolvedEntity.entityType; newDatasource.entityName = resolvedEntity.name; + newDatasource.entityDescription = resolvedEntity.entityDescription newDatasource.name = resolvedEntity.name; newDatasource.generated = i > 0 ? true : false; datasources.push(newDatasource); @@ -167,6 +168,7 @@ export default class AliasController { datasource.entityType = entity.entityType; datasource.entityName = entity.name; datasource.name = entity.name; + datasource.entityDescription = entity.entityDescription; deferred.resolve([datasource]); } else { if (aliasInfo.stateEntity) { diff --git a/ui/src/app/api/dashboard.service.js b/ui/src/app/api/dashboard.service.js index 507fe9767a..adab48fb46 100644 --- a/ui/src/app/api/dashboard.service.js +++ b/ui/src/app/api/dashboard.service.js @@ -252,7 +252,7 @@ function DashboardService($rootScope, $http, $q, $location, $filter) { if (port != 80 && port != 443) { url += ":" + port; } - url += "/dashboards/" + dashboard.id.id + "?publicId=" + dashboard.publicCustomerId; + url += "/dashboard/" + dashboard.id.id + "?publicId=" + dashboard.publicCustomerId; return url; } diff --git a/ui/src/app/api/entity.service.js b/ui/src/app/api/entity.service.js index 762bf1aba3..2e29238dfe 100644 --- a/ui/src/app/api/entity.service.js +++ b/ui/src/app/api/entity.service.js @@ -329,7 +329,7 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device } function entityToEntityInfo(entity) { - return { name: entity.name, entityType: entity.id.entityType, id: entity.id.id }; + return { name: entity.name, entityType: entity.id.entityType, id: entity.id.id, entityDescription: entity.additionalInfo?entity.additionalInfo.description:"" }; } function entityRelationInfoToEntityInfo(entityRelationInfo, direction) { diff --git a/ui/src/app/api/rule-chain.service.js b/ui/src/app/api/rule-chain.service.js index e7436dedc6..186e31cce4 100644 --- a/ui/src/app/api/rule-chain.service.js +++ b/ui/src/app/api/rule-chain.service.js @@ -32,6 +32,7 @@ function RuleChainService($http, $q, $filter, $ocLazyLoad, $translate, types, co getRuleNodeComponents: getRuleNodeComponents, getRuleNodeComponentByClazz: getRuleNodeComponentByClazz, getRuleNodeSupportedLinks: getRuleNodeSupportedLinks, + ruleNodeAllowCustomLinks: ruleNodeAllowCustomLinks, resolveTargetRuleChains: resolveTargetRuleChains, testScript: testScript, getLatestRuleNodeDebugInput: getLatestRuleNodeDebugInput @@ -127,21 +128,21 @@ function RuleChainService($http, $q, $filter, $ocLazyLoad, $translate, types, co function getRuleNodeSupportedLinks(component) { var relationTypes = component.configurationDescriptor.nodeDefinition.relationTypes; - var customRelations = component.configurationDescriptor.nodeDefinition.customRelations; - var linkLabels = []; + var linkLabels = {}; for (var i=0;i= min && interval.value <= max) { @@ -175,6 +99,89 @@ function TimeService($translate, types) { return intervals; } + function initPredefIntervals() { + if (!predefIntervals) { + predefIntervals = [ + { + name: $translate.instant('timeinterval.seconds-interval', {seconds: 1}, 'messageformat'), + value: 1 * SECOND + }, + { + name: $translate.instant('timeinterval.seconds-interval', {seconds: 5}, 'messageformat'), + value: 5 * SECOND + }, + { + name: $translate.instant('timeinterval.seconds-interval', {seconds: 10}, 'messageformat'), + value: 10 * SECOND + }, + { + name: $translate.instant('timeinterval.seconds-interval', {seconds: 15}, 'messageformat'), + value: 15 * SECOND + }, + { + name: $translate.instant('timeinterval.seconds-interval', {seconds: 30}, 'messageformat'), + value: 30 * SECOND + }, + { + name: $translate.instant('timeinterval.minutes-interval', {minutes: 1}, 'messageformat'), + value: 1 * MINUTE + }, + { + name: $translate.instant('timeinterval.minutes-interval', {minutes: 2}, 'messageformat'), + value: 2 * MINUTE + }, + { + name: $translate.instant('timeinterval.minutes-interval', {minutes: 5}, 'messageformat'), + value: 5 * MINUTE + }, + { + name: $translate.instant('timeinterval.minutes-interval', {minutes: 10}, 'messageformat'), + value: 10 * MINUTE + }, + { + name: $translate.instant('timeinterval.minutes-interval', {minutes: 15}, 'messageformat'), + value: 15 * MINUTE + }, + { + name: $translate.instant('timeinterval.minutes-interval', {minutes: 30}, 'messageformat'), + value: 30 * MINUTE + }, + { + name: $translate.instant('timeinterval.hours-interval', {hours: 1}, 'messageformat'), + value: 1 * HOUR + }, + { + name: $translate.instant('timeinterval.hours-interval', {hours: 2}, 'messageformat'), + value: 2 * HOUR + }, + { + name: $translate.instant('timeinterval.hours-interval', {hours: 5}, 'messageformat'), + value: 5 * HOUR + }, + { + name: $translate.instant('timeinterval.hours-interval', {hours: 10}, 'messageformat'), + value: 10 * HOUR + }, + { + name: $translate.instant('timeinterval.hours-interval', {hours: 12}, 'messageformat'), + value: 12 * HOUR + }, + { + name: $translate.instant('timeinterval.days-interval', {days: 1}, 'messageformat'), + value: 1 * DAY + }, + { + name: $translate.instant('timeinterval.days-interval', {days: 7}, 'messageformat'), + value: 7 * DAY + }, + { + name: $translate.instant('timeinterval.days-interval', {days: 30}, 'messageformat'), + value: 30 * DAY + } + ]; + } + } + function matchesExistingInterval(min, max, intervalMs) { var intervals = getIntervals(min, max); for (var i in intervals) { diff --git a/ui/src/app/api/user.service.js b/ui/src/app/api/user.service.js index cb85709384..48c811bb8d 100644 --- a/ui/src/app/api/user.service.js +++ b/ui/src/app/api/user.service.js @@ -488,7 +488,8 @@ function UserService($http, $q, $rootScope, adminService, dashboardService, logi } else { return true; } - } else if (to.name === 'home.dashboards.dashboard' && allowedDashboardIds.indexOf(params.dashboardId) > -1) { + } else if ((to.name === 'home.dashboards.dashboard' || to.name === 'dashboard') + && allowedDashboardIds.indexOf(params.dashboardId) > -1) { return false; } else { return true; @@ -504,10 +505,10 @@ function UserService($http, $q, $rootScope, adminService, dashboardService, logi var place = 'home.links'; if (currentUser.authority === 'TENANT_ADMIN' || currentUser.authority === 'CUSTOMER_USER') { if (userHasDefaultDashboard()) { - place = 'home.dashboards.dashboard'; + place = $rootScope.forceFullscreen ? 'dashboard' : 'home.dashboards.dashboard'; params = {dashboardId: currentUserDetails.additionalInfo.defaultDashboardId}; } else if (isPublic()) { - place = 'home.dashboards.dashboard'; + place = 'dashboard'; params = {dashboardId: lastPublicDashboardId}; } } else if (currentUser.authority === 'SYS_ADMIN') { diff --git a/ui/src/app/app.config.js b/ui/src/app/app.config.js index a84bdde337..edc2c2aba1 100644 --- a/ui/src/app/app.config.js +++ b/ui/src/app/app.config.js @@ -15,10 +15,6 @@ */ import injectTapEventPlugin from 'react-tap-event-plugin'; import UrlHandler from './url.handler'; -import addLocaleKorean from './locale/locale.constant-ko'; -import addLocaleChinese from './locale/locale.constant-zh'; -import addLocaleRussian from './locale/locale.constant-ru'; -import addLocaleSpanish from './locale/locale.constant-es'; /* eslint-disable import/no-unresolved, import/default */ @@ -38,46 +34,28 @@ export default function AppConfig($provide, $mdThemingProvider, $httpProvider, $translateProvider, - storeProvider, - locales) { + storeProvider) { injectTapEventPlugin(); $locationProvider.html5Mode(true); $urlRouterProvider.otherwise(UrlHandler); storeProvider.setCaching(false); - - $translateProvider.useSanitizeValueStrategy(null); - $translateProvider.useMissingTranslationHandler('tbMissingTranslationHandler'); - $translateProvider.addInterpolation('$translateMessageFormatInterpolation'); - $translateProvider.fallbackLanguage('en_US'); - - addLocaleKorean(locales); - addLocaleChinese(locales); - addLocaleRussian(locales); - addLocaleSpanish(locales); - - for (var langKey in locales) { - var translationTable = locales[langKey]; - $translateProvider.translations(langKey, translationTable); - } - - var lang = $translateProvider.resolveClientLocale(); - if (lang) { - lang = lang.toLowerCase(); - if (lang.startsWith('ko')) { - $translateProvider.preferredLanguage('ko_KR'); - } else if (lang.startsWith('zh')) { - $translateProvider.preferredLanguage('zh_CN'); - } else if (lang.startsWith('es')) { - $translateProvider.preferredLanguage('es_ES'); - } else if (lang.startsWith('ru')) { - $translateProvider.preferredLanguage('ru_RU'); - } else { - $translateProvider.preferredLanguage('en_US'); - } - } else { - $translateProvider.preferredLanguage('en_US'); - } + + $translateProvider.useSanitizeValueStrategy(null) + .useMissingTranslationHandler('tbMissingTranslationHandler') + .addInterpolation('$translateMessageFormatInterpolation') + .useStaticFilesLoader({ + files: [ + { + prefix: PUBLIC_PATH + 'locale/locale.constant-', //eslint-disable-line + suffix: '.json' + } + ] + }) + .registerAvailableLanguageKeys(SUPPORTED_LANGS, getLanguageAliases(SUPPORTED_LANGS)) //eslint-disable-line + .fallbackLanguage('en_US') // must be before determinePreferredLanguage + .uniformLanguageTag('java') // must be before determinePreferredLanguage + .determinePreferredLanguage(); $httpProvider.interceptors.push('globalInterceptor'); @@ -168,4 +146,24 @@ export default function AppConfig($provide, //$mdThemingProvider.alwaysWatchTheme(true); } + function getLanguageAliases(supportedLangs) { + var aliases = {}; + + supportedLangs.sort().forEach(function(item, index, array) { + if (item.length === 2) { + aliases[item] = item; + aliases[item + '_*'] = item; + } else { + var key = item.slice(0, 2); + if (index === 0 || key !== array[index - 1].slice(0, 2)) { + aliases[key] = item; + aliases[key + '_*'] = item; + } else { + aliases[item] = item; + } + } + }); + + return aliases; + } } \ No newline at end of file diff --git a/ui/src/app/app.js b/ui/src/app/app.js index f021efb007..c8cdeb02b0 100644 --- a/ui/src/app/app.js +++ b/ui/src/app/app.js @@ -51,7 +51,7 @@ import react from 'ngreact'; import '@flowjs/ng-flow/dist/ng-flow-standalone.min'; import 'ngFlowchart/dist/ngFlowchart'; -import thingsboardLocales from './locale/locale.constant'; +import thingsboardTranslateHandler from './locale/translate-handler'; import thingsboardLogin from './login'; import thingsboardDialogs from './components/datakey-config-dialog.controller'; import thingsboardMenu from './services/menu.service'; @@ -117,7 +117,7 @@ angular.module('thingsboard', [ react.name, 'flow', 'flowchart', - thingsboardLocales, + thingsboardTranslateHandler, thingsboardLogin, thingsboardDialogs, thingsboardMenu, diff --git a/ui/src/app/app.run.js b/ui/src/app/app.run.js index f3886b8dec..4667b09e06 100644 --- a/ui/src/app/app.run.js +++ b/ui/src/app/app.run.js @@ -113,7 +113,10 @@ export default function AppRun($rootScope, $window, $injector, $location, $log, showForbiddenDialog(); } else if (to.redirectTo) { evt.preventDefault(); - $state.go(to.redirectTo, params) + $state.go(to.redirectTo, params); + } else if (to.name === 'home.dashboards.dashboard' && $rootScope.forceFullscreen) { + evt.preventDefault(); + $state.go('dashboard', params); } } } else { @@ -138,7 +141,7 @@ export default function AppRun($rootScope, $window, $injector, $location, $log, $rootScope.pageTitle = 'ThingsBoard'; $rootScope.stateChangeSuccessHandle = $rootScope.$on('$stateChangeSuccess', function (evt, to, params) { - if (userService.isPublic() && to.name === 'home.dashboards.dashboard') { + if (userService.isPublic() && to.name === 'dashboard') { $location.search('publicId', userService.getPublicId()); userService.updateLastPublicDashboardId(params.dashboardId); } diff --git a/ui/src/app/common/types.constant.js b/ui/src/app/common/types.constant.js index cf1023eb4e..1e34577119 100644 --- a/ui/src/app/common/types.constant.js +++ b/ui/src/app/common/types.constant.js @@ -195,6 +195,21 @@ export default angular.module('thingsboard.types', []) }, "ATTRIBUTES_READ": { name: "audit-log.type-attributes-read" + }, + "RELATION_ADD_OR_UPDATE": { + name: "audit-log.type-relation-add-or-update" + }, + "RELATION_DELETED": { + name: "audit-log.type-relation-delete" + }, + "RELATIONS_DELETED": { + name: "audit-log.type-relations-delete" + }, + "ALARM_ACK": { + name: "audit-log.type-alarm-ack" + }, + "ALARM_CLEAR": { + name: "audit-log.type-alarm-clear" } }, auditLogActionStatus: { @@ -366,6 +381,12 @@ export default angular.module('thingsboard.types', []) list: 'entity.list-of-rulechains', nameStartsWith: 'entity.rulechain-name-starts-with' }, + "RULE_NODE": { + type: 'entity.type-rulenode', + typePlural: 'entity.type-rulenodes', + list: 'entity.list-of-rulenodes', + nameStartsWith: 'entity.rulenode-name-starts-with' + }, "CURRENT_CUSTOMER": { type: 'entity.type-current-customer', list: 'entity.type-current-customer' @@ -510,6 +531,22 @@ export default angular.module('thingsboard.types', []) } } }, + unknownNodeComponent: { + type: 'UNKNOWN', + name: 'unknown', + clazz: 'tb.internal.Unknown', + configurationDescriptor: { + nodeDefinition: { + description: "", + details: "", + inEnabled: true, + outEnabled: true, + relationTypes: [], + customRelations: false, + defaultConfiguration: {} + } + } + }, inputNodeComponent: { type: 'INPUT', name: 'Input', @@ -565,6 +602,75 @@ export default angular.module('thingsboard.types', []) nodeClass: "tb-input-type", icon: "input", special: true + }, + UNKNOWN: { + value: "UNKNOWN", + name: "rulenode.type-unknown", + details: "rulenode.type-unknown-details", + nodeClass: "tb-unknown-type", + icon: "help_outline" + } + }, + messageType: { + 'POST_ATTRIBUTES_REQUEST': { + name: 'Post attributes', + value: 'POST_ATTRIBUTES_REQUEST' + }, + 'POST_TELEMETRY_REQUEST': { + name: 'Post telemetry', + value: 'POST_TELEMETRY_REQUEST' + }, + 'TO_SERVER_RPC_REQUEST': { + name: 'RPC Request from Device', + value: 'TO_SERVER_RPC_REQUEST' + }, + 'RPC_CALL_FROM_SERVER_TO_DEVICE': { + name: 'RPC Request to Device', + value: 'RPC_CALL_FROM_SERVER_TO_DEVICE' + }, + 'ACTIVITY_EVENT': { + name: 'Activity Event', + value: 'ACTIVITY_EVENT' + }, + 'INACTIVITY_EVENT': { + name: 'Inactivity Event', + value: 'INACTIVITY_EVENT' + }, + 'CONNECT_EVENT': { + name: 'Connect Event', + value: 'CONNECT_EVENT' + }, + 'DISCONNECT_EVENT': { + name: 'Disconnect Event', + value: 'DISCONNECT_EVENT' + }, + 'ENTITY_CREATED': { + name: 'Entity Created', + value: 'ENTITY_CREATED' + }, + 'ENTITY_UPDATED': { + name: 'Entity Updated', + value: 'ENTITY_UPDATED' + }, + 'ENTITY_DELETED': { + name: 'Entity Deleted', + value: 'ENTITY_DELETED' + }, + 'ENTITY_ASSIGNED': { + name: 'Entity Assigned', + value: 'ENTITY_ASSIGNED' + }, + 'ENTITY_UNASSIGNED': { + name: 'Entity Unassigned', + value: 'ENTITY_UNASSIGNED' + }, + 'ATTRIBUTES_UPDATED': { + name: 'Attributes Updated', + value: 'ATTRIBUTES_UPDATED' + }, + 'ATTRIBUTES_DELETED': { + name: 'Attributes Deleted', + value: 'ATTRIBUTES_DELETED' } }, valueType: { diff --git a/ui/src/app/components/dashboard.scss b/ui/src/app/components/dashboard.scss index 9f76347064..ca99fcc08f 100644 --- a/ui/src/app/components/dashboard.scss +++ b/ui/src/app/components/dashboard.scss @@ -40,12 +40,12 @@ div.tb-widget { position: absolute; top: 8px; right: 8px; - z-index: 1; - margin: 0px; + z-index: 19; + margin: 0; .md-button.md-icon-button { - margin: 0px !important; - padding: 0px !important; + margin: 0 !important; + padding: 0 !important; line-height: 20px; width: 32px; height: 32px; diff --git a/ui/src/app/components/datasource-entity.tpl.html b/ui/src/app/components/datasource-entity.tpl.html index 484164f838..db6fd3be96 100644 --- a/ui/src/app/components/datasource-entity.tpl.html +++ b/ui/src/app/components/datasource-entity.tpl.html @@ -60,7 +60,7 @@
-
+
{{$chip.label}}
@@ -112,7 +112,7 @@
-
+
{{$chip.label}}
@@ -164,7 +164,7 @@
-
+
{{$chip.label}}
diff --git a/ui/src/app/components/datasource-func.tpl.html b/ui/src/app/components/datasource-func.tpl.html index 134dcd7552..6bf49ba8f7 100644 --- a/ui/src/app/components/datasource-func.tpl.html +++ b/ui/src/app/components/datasource-func.tpl.html @@ -61,7 +61,7 @@
-
+
{{$chip.label}}
@@ -112,7 +112,7 @@
-
+
{{$chip.label}}
diff --git a/ui/src/app/components/details-sidenav.scss b/ui/src/app/components/details-sidenav.scss index 360b1330e4..c7e991912b 100644 --- a/ui/src/app/components/details-sidenav.scss +++ b/ui/src/app/components/details-sidenav.scss @@ -59,14 +59,4 @@ md-sidenav.tb-sidenav-details { background-color: $primary-hue-3; } } - - md-tab-content.md-active > div { - height: 100%; - & > *:first-child { - height: 100%; - } - md-content { - height: 100%; - } - } } diff --git a/ui/src/app/components/json-content.directive.js b/ui/src/app/components/json-content.directive.js index e945079273..102748679c 100644 --- a/ui/src/app/components/json-content.directive.js +++ b/ui/src/app/components/json-content.directive.js @@ -18,8 +18,8 @@ import './json-content.scss'; import 'brace/ext/language_tools'; import 'brace/mode/json'; import 'brace/mode/text'; -import 'ace-builds/src-min-noconflict/snippets/json'; -import 'ace-builds/src-min-noconflict/snippets/text'; +import 'brace/snippets/json'; +import 'brace/snippets/text'; import fixAceEditor from './ace-editor-fix'; diff --git a/ui/src/app/components/json-object-edit.directive.js b/ui/src/app/components/json-object-edit.directive.js index 215b7b9fe8..9364689f1e 100644 --- a/ui/src/app/components/json-object-edit.directive.js +++ b/ui/src/app/components/json-object-edit.directive.js @@ -17,7 +17,7 @@ import './json-object-edit.scss'; import 'brace/ext/language_tools'; import 'brace/mode/json'; -import 'ace-builds/src-min-noconflict/snippets/json'; +import 'brace/snippets/json'; import fixAceEditor from './ace-editor-fix'; diff --git a/ui/src/app/components/widget/action/manage-widget-actions.directive.js b/ui/src/app/components/widget/action/manage-widget-actions.directive.js index 81c40cd3fd..88a37a876e 100644 --- a/ui/src/app/components/widget/action/manage-widget-actions.directive.js +++ b/ui/src/app/components/widget/action/manage-widget-actions.directive.js @@ -111,8 +111,15 @@ function ManageWidgetActionsController($rootScope, $scope, $document, $mdDialog, } }); - function enterFilterMode () { + function enterFilterMode (event) { + let $button = angular.element(event.currentTarget); + let $toolbarsContainer = $button.closest('.toolbarsContainer'); + vm.query.search = ''; + + $timeout(()=>{ + $toolbarsContainer.find('.searchInput').focus(); + }) } function exitFilterMode () { diff --git a/ui/src/app/components/widget/action/manage-widget-actions.tpl.html b/ui/src/app/components/widget/action/manage-widget-actions.tpl.html index fc9262e87a..07f76f2e33 100644 --- a/ui/src/app/components/widget/action/manage-widget-actions.tpl.html +++ b/ui/src/app/components/widget/action/manage-widget-actions.tpl.html @@ -15,7 +15,7 @@ limitations under the License. --> -
+
widget-config.actions @@ -26,7 +26,7 @@ {{ 'widget-config.add-action' | translate }} - + search {{ 'action.search' | translate }} @@ -44,7 +44,7 @@ - + close diff --git a/ui/src/app/components/widget/widget-config.tpl.html b/ui/src/app/components/widget/widget-config.tpl.html index ce796d4210..e8762bdeeb 100644 --- a/ui/src/app/components/widget/widget-config.tpl.html +++ b/ui/src/app/components/widget/widget-config.tpl.html @@ -187,17 +187,17 @@
- {{ 'widget-config.display-title' | translate }}
- {{ 'widget-config.drop-shadow' | translate }}
- {{ 'widget-config.enable-fullscreen' | translate }}
diff --git a/ui/src/app/components/widget/widget.controller.js b/ui/src/app/components/widget/widget.controller.js index 9feb40d7b5..36e5bee1cc 100644 --- a/ui/src/app/components/widget/widget.controller.js +++ b/ui/src/app/components/widget/widget.controller.js @@ -479,7 +479,11 @@ export default function WidgetController($scope, $state, $timeout, $window, $ele dashboardId: targetDashboardId, state: utils.objToBase64([ stateObject ]) } - $state.go('home.dashboards.dashboard', stateParams); + if ($state.current.name === 'dashboard') { + $state.go('dashboard', stateParams); + } else { + $state.go('home.dashboards.dashboard', stateParams); + } break; case types.widgetActionTypes.custom.value: var customFunction = descriptor.customFunction; diff --git a/ui/src/app/dashboard/dashboard.controller.js b/ui/src/app/dashboard/dashboard.controller.js index f672f3f03b..6df48df032 100644 --- a/ui/src/app/dashboard/dashboard.controller.js +++ b/ui/src/app/dashboard/dashboard.controller.js @@ -196,6 +196,7 @@ export default function DashboardController(types, utils, dashboardUtils, widget vm.displayDashboardTimewindow = displayDashboardTimewindow; vm.displayDashboardsSelect = displayDashboardsSelect; vm.displayEntitiesSelect = displayEntitiesSelect; + vm.hideFullscreenButton = hideFullscreenButton; vm.widgetsBundle; @@ -258,7 +259,11 @@ export default function DashboardController(types, utils, dashboardUtils, widget dashboardId: vm.currentDashboardId }); } else { - $state.go('home.dashboards.dashboard', {dashboardId: vm.currentDashboardId}); + if ($state.current.name === 'dashboard') { + $state.go('dashboard', {dashboardId: vm.currentDashboardId}); + } else { + $state.go('home.dashboards.dashboard', {dashboardId: vm.currentDashboardId}); + } } } }); @@ -805,6 +810,10 @@ export default function DashboardController(types, utils, dashboardUtils, widget } } + function hideFullscreenButton() { + return vm.widgetEditMode || vm.iframeMode || $rootScope.forceFullscreen || $state.current.name === 'dashboard'; + } + function onRevertWidgetEdit(widgetForm) { if (widgetForm.$dirty) { widgetForm.$setPristine(); diff --git a/ui/src/app/dashboard/dashboard.routes.js b/ui/src/app/dashboard/dashboard.routes.js index ccb43c708f..4572ac38f7 100644 --- a/ui/src/app/dashboard/dashboard.routes.js +++ b/ui/src/app/dashboard/dashboard.routes.js @@ -86,6 +86,24 @@ export default function DashboardRoutes($stateProvider) { label: '{"icon": "dashboard", "label": "{{ vm.dashboard.title }}", "translate": "false"}' } }) + .state('dashboard', { + url: '/dashboard/:dashboardId?state', + reloadOnSearch: false, + module: 'private', + auth: ['TENANT_ADMIN', 'CUSTOMER_USER'], + views: { + "@": { + templateUrl: dashboardTemplate, + controller: 'DashboardController', + controllerAs: 'vm' + } + }, + data: { + widgetEditMode: false, + searchEnabled: false, + pageTitle: 'dashboard.dashboard' + } + }) .state('home.customers.dashboards.dashboard', { url: '/:dashboardId?state', reloadOnSearch: false, diff --git a/ui/src/app/dashboard/dashboard.tpl.html b/ui/src/app/dashboard/dashboard.tpl.html index 9626509a51..829f174fe7 100644 --- a/ui/src/app/dashboard/dashboard.tpl.html +++ b/ui/src/app/dashboard/dashboard.tpl.html @@ -16,7 +16,7 @@ --> + hide-expand-button="vm.hideFullscreenButton()" expand-tooltip-direction="bottom" ng-if="vm.dashboard">
- - {{ 'action.save' | translate }} + + {{ 'action.select' | translate }} {{ 'action.cancel' | translate }} diff --git a/ui/src/app/device/device-card.tpl.html b/ui/src/app/device/device-card.tpl.html index 522f1ab376..fbda549df5 100644 --- a/ui/src/app/device/device-card.tpl.html +++ b/ui/src/app/device/device-card.tpl.html @@ -16,7 +16,8 @@ -->
-
{{vm.item.type}}
-
{{'device.assignedToCustomer' | translate}} '{{vm.item.assignedCustomer.title}}'
-
{{'device.public' | translate}}
+
{{vm.item.type}}
+
{{vm.item.additionalInfo.description}}
+
{{'device.assignedToCustomer' | translate}} '{{vm.item.assignedCustomer.title}}'
+
{{'device.public' | translate}}
diff --git a/ui/src/app/entity/alias/entity-aliases.tpl.html b/ui/src/app/entity/alias/entity-aliases.tpl.html index a760eab968..8eb7ff5a31 100644 --- a/ui/src/app/entity/alias/entity-aliases.tpl.html +++ b/ui/src/app/entity/alias/entity-aliases.tpl.html @@ -43,7 +43,7 @@
{{$index + 1}}. - +
@@ -81,7 +81,7 @@ close - +
diff --git a/ui/src/app/entity/attribute/attribute-table.directive.js b/ui/src/app/entity/attribute/attribute-table.directive.js index b551ae600c..00618541ce 100644 --- a/ui/src/app/entity/attribute/attribute-table.directive.js +++ b/ui/src/app/entity/attribute/attribute-table.directive.js @@ -30,7 +30,7 @@ import AliasController from '../../api/alias-controller'; /*@ngInject*/ export default function AttributeTableDirective($compile, $templateCache, $rootScope, $q, $mdEditDialog, $mdDialog, - $mdUtil, $document, $translate, $filter, utils, types, dashboardUtils, + $mdUtil, $document, $translate, $filter, $timeout, utils, types, dashboardUtils, entityService, attributeService, widgetService) { var linker = function (scope, element, attrs) { @@ -110,8 +110,15 @@ export default function AttributeTableDirective($compile, $templateCache, $rootS scope.attributeScope = getAttributeScopeByValue(attrs.defaultAttributeScope); } - scope.enterFilterMode = function() { + scope.enterFilterMode = function(event) { + let $button = angular.element(event.currentTarget); + let $toolbarsContainer = $button.closest('.toolbarsContainer'); + scope.query.search = ''; + + $timeout(()=>{ + $toolbarsContainer.find('.searchInput').focus(); + }) } scope.exitFilterMode = function() { diff --git a/ui/src/app/entity/attribute/attribute-table.tpl.html b/ui/src/app/entity/attribute/attribute-table.tpl.html index d55a6da99b..ecbcf00fd6 100644 --- a/ui/src/app/entity/attribute/attribute-table.tpl.html +++ b/ui/src/app/entity/attribute/attribute-table.tpl.html @@ -26,7 +26,7 @@ -
+
@@ -39,7 +39,7 @@ {{ 'action.add' | translate }} - + search {{ 'action.search' | translate }} @@ -65,7 +65,7 @@ - + close diff --git a/ui/src/app/entity/entity-select.directive.js b/ui/src/app/entity/entity-select.directive.js index 8e4031c9cf..e7ac5fd893 100644 --- a/ui/src/app/entity/entity-select.directive.js +++ b/ui/src/app/entity/entity-select.directive.js @@ -22,14 +22,28 @@ import entitySelectTemplate from './entity-select.tpl.html'; /* eslint-enable import/no-unresolved, import/default */ /*@ngInject*/ -export default function EntitySelect($compile, $templateCache) { +export default function EntitySelect($compile, $templateCache, entityService) { var linker = function (scope, element, attrs, ngModelCtrl) { var template = $templateCache.get(entitySelectTemplate); element.html(template); scope.tbRequired = angular.isDefined(scope.tbRequired) ? scope.tbRequired : false; - scope.model = {}; + + var entityTypes = entityService.prepareAllowedEntityTypesList(scope.allowedEntityTypes, scope.useAliasEntityTypes); + + var entityTypeKeys = Object.keys(entityTypes); + + if (entityTypeKeys.length === 1) { + scope.displayEntityTypeSelect = false; + scope.defaultEntityType = entityTypes[entityTypeKeys[0]]; + } else { + scope.displayEntityTypeSelect = true; + } + + scope.model = { + entityType: scope.defaultEntityType + }; scope.updateView = function () { if (!scope.disabled) { @@ -54,7 +68,7 @@ export default function EntitySelect($compile, $templateCache) { scope.model.entityType = value.entityType; scope.model.entityId = value.id; } else { - scope.model.entityType = null; + scope.model.entityType = scope.defaultEntityType; scope.model.entityId = null; } initWatchers(); @@ -106,6 +120,7 @@ export default function EntitySelect($compile, $templateCache) { theForm: '=?', tbRequired: '=?', disabled:'=ngDisabled', + allowedEntityTypes: "=?", useAliasEntityTypes: "=?" } }; diff --git a/ui/src/app/entity/entity-select.tpl.html b/ui/src/app/entity/entity-select.tpl.html index 9e5e227922..d6b6eeaba4 100644 --- a/ui/src/app/entity/entity-select.tpl.html +++ b/ui/src/app/entity/entity-select.tpl.html @@ -17,10 +17,12 @@ -->
{ + var entityType = entityTypeFromValue(entityTypeValue); + if (entityType) { + entityTypes[entityType] = entityTypeValue; + } + }); + } else { + entityTypes = entityService.prepareAllowedEntityTypesList(scope.allowedEntityTypes); + } + + function entityTypeFromValue(entityTypeValue) { + for (var entityType in types.entityType) { + if (types.entityType[entityType] === entityTypeValue) { + return entityType; + } + } + return null; + } + scope.entityTypesList = []; for (var type in entityTypes) { var entityTypeInfo = {}; @@ -62,28 +85,43 @@ export default function EntityTypeListDirective($compile, $templateCache, $q, $m } ngModelCtrl.$render = function () { - scope.entityTypeList = []; + if (scope.entityTypeListWatch) { + scope.entityTypeListWatch(); + scope.entityTypeListWatch = null; + } + var entityTypeList = []; var value = ngModelCtrl.$viewValue; if (value && value.length) { value.forEach(function(type) { var entityTypeInfo = {}; entityTypeInfo.value = type; entityTypeInfo.name = $translate.instant(types.entityTypeTranslations[entityTypeInfo.value].type) + ''; - scope.entityTypeList.push(entityTypeInfo); + entityTypeList.push(entityTypeInfo); }); } + scope.entityTypeList = entityTypeList; + scope.entityTypeListWatch = scope.$watch('entityTypeList', function (newVal, prevVal) { + if (!angular.equals(newVal, prevVal)) { + updateEntityTypeList(); + } + }, true); } - scope.$watch('entityTypeList', function () { - var values = []; + function updateEntityTypeList() { + var values = ngModelCtrl.$viewValue; + if (!values) { + values = []; + ngModelCtrl.$setViewValue(values); + } else { + values.length = 0; + } if (scope.entityTypeList && scope.entityTypeList.length) { - scope.entityTypeList.forEach(function(entityType) { + scope.entityTypeList.forEach(function (entityType) { values.push(entityType.value); }); } - ngModelCtrl.$setViewValue(values); scope.updateValidity(); - }, true); + } $compile(element.contents())(scope); @@ -103,7 +141,8 @@ export default function EntityTypeListDirective($compile, $templateCache, $q, $m scope: { disabled:'=ngDisabled', tbRequired: '=?', - allowedEntityTypes: '=?' + allowedEntityTypes: '=?', + ignoreAuthorityFilter: '=?' } }; diff --git a/ui/src/app/entity/relation/relation-filters.directive.js b/ui/src/app/entity/relation/relation-filters.directive.js index 9ab66cac72..e945fb6f41 100644 --- a/ui/src/app/entity/relation/relation-filters.directive.js +++ b/ui/src/app/entity/relation/relation-filters.directive.js @@ -44,6 +44,10 @@ export default function RelationFilters($compile, $templateCache) { scope.removeFilter = removeFilter; ngModelCtrl.$render = function () { + if (scope.relationFiltersWatch) { + scope.relationFiltersWatch(); + scope.relationFiltersWatch = null; + } if (ngModelCtrl.$viewValue) { var value = ngModelCtrl.$viewValue; scope.relationFilters.length = 0; @@ -51,7 +55,7 @@ export default function RelationFilters($compile, $templateCache) { scope.relationFilters.push(filter); }); } - scope.$watch('relationFilters', function (newVal, prevVal) { + scope.relationFiltersWatch = scope.$watch('relationFilters', function (newVal, prevVal) { if (!angular.equals(newVal, prevVal)) { updateValue(); } @@ -74,11 +78,16 @@ export default function RelationFilters($compile, $templateCache) { } function updateValue() { - var value = []; + var value = ngModelCtrl.$viewValue; + if (!value) { + value = []; + ngModelCtrl.$setViewValue(value); + } else { + value.length = 0; + } scope.relationFilters.forEach(function (filter) { value.push(filter); }); - ngModelCtrl.$setViewValue(value); } $compile(element.contents())(scope); } diff --git a/ui/src/app/entity/relation/relation-table.directive.js b/ui/src/app/entity/relation/relation-table.directive.js index 32478117ee..872042c2fa 100644 --- a/ui/src/app/entity/relation/relation-table.directive.js +++ b/ui/src/app/entity/relation/relation-table.directive.js @@ -41,7 +41,7 @@ export default function RelationTable() { } /*@ngInject*/ -function RelationTableController($scope, $q, $mdDialog, $document, $translate, $filter, utils, types, entityRelationService) { +function RelationTableController($scope, $q, $mdDialog, $document, $translate, $filter, $timeout, utils, types, entityRelationService) { let vm = this; @@ -90,8 +90,15 @@ function RelationTableController($scope, $q, $mdDialog, $document, $translate, $ } }); - function enterFilterMode () { + function enterFilterMode (event) { + let $button = angular.element(event.currentTarget); + let $toolbarsContainer = $button.closest('.toolbarsContainer'); + vm.query.search = ''; + + $timeout(()=>{ + $toolbarsContainer.find('.searchInput').focus(); + }) } function exitFilterMode () { diff --git a/ui/src/app/entity/relation/relation-table.tpl.html b/ui/src/app/entity/relation/relation-table.tpl.html index 16d422c751..a2b0920b4e 100644 --- a/ui/src/app/entity/relation/relation-table.tpl.html +++ b/ui/src/app/entity/relation/relation-table.tpl.html @@ -26,7 +26,7 @@ -
+
@@ -39,7 +39,7 @@ {{ 'action.add' | translate }} - + search {{ 'action.search' | translate }} @@ -64,7 +64,7 @@ - + close diff --git a/ui/src/app/extension/extension-table.directive.js b/ui/src/app/extension/extension-table.directive.js index ecd38658f9..18d281c0b0 100644 --- a/ui/src/app/extension/extension-table.directive.js +++ b/ui/src/app/extension/extension-table.directive.js @@ -45,7 +45,7 @@ export default function ExtensionTableDirective() { } /*@ngInject*/ -function ExtensionTableController($scope, $filter, $document, $translate, types, $mdDialog, attributeService, telemetryWebsocketService, importExport) { +function ExtensionTableController($scope, $filter, $document, $translate, $timeout, $mdDialog, types, attributeService, telemetryWebsocketService, importExport) { let vm = this; @@ -141,11 +141,17 @@ function ExtensionTableController($scope, $filter, $document, $translate, types, } }); - function enterFilterMode() { + function enterFilterMode(event) { + let $button = angular.element(event.currentTarget); + let $toolbarsContainer = $button.closest('.toolbarsContainer'); + vm.query.search = ''; if(vm.inWidget) { vm.ctx.hideTitlePanel = true; } + $timeout(()=>{ + $toolbarsContainer.find('.searchInput').focus(); + }) } function exitFilterMode() { diff --git a/ui/src/app/extension/extension-table.tpl.html b/ui/src/app/extension/extension-table.tpl.html index 0ad2f4df34..6a482b9ffc 100644 --- a/ui/src/app/extension/extension-table.tpl.html +++ b/ui/src/app/extension/extension-table.tpl.html @@ -16,7 +16,7 @@ --> -
+
@@ -41,7 +41,7 @@ {{ 'action.add' | translate }} - + search {{ 'action.search' | translate }} @@ -66,7 +66,7 @@ - + close diff --git a/ui/src/app/help/help-links.constant.js b/ui/src/app/help/help-links.constant.js index 1b708a9178..458c118883 100644 --- a/ui/src/app/help/help-links.constant.js +++ b/ui/src/app/help/help-links.constant.js @@ -20,6 +20,7 @@ var ruleNodeClazzHelpLinkMap = { 'org.thingsboard.rule.engine.filter.TbJsSwitchNode': 'ruleNodeJsSwitch', 'org.thingsboard.rule.engine.filter.TbMsgTypeFilterNode': 'ruleNodeMessageTypeFilter', 'org.thingsboard.rule.engine.filter.TbMsgTypeSwitchNode': 'ruleNodeMessageTypeSwitch', + 'org.thingsboard.rule.engine.filter.TbOriginatorTypeFilterNode': 'ruleNodeOriginatorTypeFilter', 'org.thingsboard.rule.engine.filter.TbOriginatorTypeSwitchNode': 'ruleNodeOriginatorTypeSwitch', 'org.thingsboard.rule.engine.metadata.TbGetAttributesNode': 'ruleNodeOriginatorAttributes', 'org.thingsboard.rule.engine.metadata.TbGetOriginatorFieldsNode': 'ruleNodeOriginatorFields', @@ -31,7 +32,8 @@ var ruleNodeClazzHelpLinkMap = { 'org.thingsboard.rule.engine.transform.TbTransformMsgNode': 'ruleNodeTransformMsg', 'org.thingsboard.rule.engine.mail.TbMsgToEmailNode': 'ruleNodeMsgToEmail', 'org.thingsboard.rule.engine.action.TbClearAlarmNode': 'ruleNodeClearAlarm', - 'org.thingsboard.rule.engine.action.TbCreateAlarmNode': 'ruleNodeCrateAlarm', + 'org.thingsboard.rule.engine.action.TbCreateAlarmNode': 'ruleNodeCreateAlarm', + 'org.thingsboard.rule.engine.delay.TbMsgDelayNode': 'ruleNodeMsgDelay', 'org.thingsboard.rule.engine.debug.TbMsgGeneratorNode': 'ruleNodeMsgGenerator', 'org.thingsboard.rule.engine.action.TbLogNode': 'ruleNodeLog', 'org.thingsboard.rule.engine.rpc.TbSendRPCReplyNode': 'ruleNodeRpcCallReply', @@ -61,6 +63,7 @@ export default angular.module('thingsboard.help', []) ruleNodeJsSwitch: helpBaseUrl + "/docs/user-guide/rule-engine-2-0/filter-nodes/#switch-node", ruleNodeMessageTypeFilter: helpBaseUrl + "/docs/user-guide/rule-engine-2-0/filter-nodes/#message-type-filter-node", ruleNodeMessageTypeSwitch: helpBaseUrl + "/docs/user-guide/rule-engine-2-0/filter-nodes/#message-type-switch-node", + ruleNodeOriginatorTypeFilter: helpBaseUrl + "/docs/user-guide/rule-engine-2-0/filter-nodes/#originator-type-filter-node", ruleNodeOriginatorTypeSwitch: helpBaseUrl + "/docs/user-guide/rule-engine-2-0/filter-nodes/#originator-type-switch-node", ruleNodeOriginatorAttributes: helpBaseUrl + "/docs/user-guide/rule-engine-2-0/enrichment-nodes/#originator-attributes", ruleNodeOriginatorFields: helpBaseUrl + "/docs/user-guide/rule-engine-2-0/enrichment-nodes/#originator-fields", @@ -72,7 +75,8 @@ export default angular.module('thingsboard.help', []) ruleNodeTransformMsg: helpBaseUrl + "/docs/user-guide/rule-engine-2-0/transformation-nodes/#script-transformation-node", ruleNodeMsgToEmail: helpBaseUrl + "/docs/user-guide/rule-engine-2-0/transformation-nodes/#to-email-node", ruleNodeClearAlarm: helpBaseUrl + "/docs/user-guide/rule-engine-2-0/action-nodes/#clear-alarm-node", - ruleNodeCrateAlarm: helpBaseUrl + "/docs/user-guide/rule-engine-2-0/action-nodes/#create-alarm-node", + ruleNodeCreateAlarm: helpBaseUrl + "/docs/user-guide/rule-engine-2-0/action-nodes/#create-alarm-node", + ruleNodeMsgDelay: helpBaseUrl + "/docs/user-guide/rule-engine-2-0/action-nodes/#delay-node", ruleNodeMsgGenerator: helpBaseUrl + "/docs/user-guide/rule-engine-2-0/action-nodes/#generator-node", ruleNodeLog: helpBaseUrl + "/docs/user-guide/rule-engine-2-0/action-nodes/#log-node", ruleNodeRpcCallReply: helpBaseUrl + "/docs/user-guide/rule-engine-2-0/action-nodes/#rpc-call-reply-node", diff --git a/ui/src/app/locale/locale.constant-en_US.json b/ui/src/app/locale/locale.constant-en_US.json new file mode 100644 index 0000000000..22aad1a90d --- /dev/null +++ b/ui/src/app/locale/locale.constant-en_US.json @@ -0,0 +1,1462 @@ +{ + "access": { + "unauthorized": "Unauthorized", + "unauthorized-access": "Unauthorized Access", + "unauthorized-access-text": "You should sign in to have access to this resource!", + "access-forbidden": "Access Forbidden", + "access-forbidden-text": "You haven't access rights to this location!
Try to sign in with different user if you still wish to gain access to this location.", + "refresh-token-expired": "Session has expired", + "refresh-token-failed": "Unable to refresh session" + }, + "action": { + "activate": "Activate", + "suspend": "Suspend", + "save": "Save", + "saveAs": "Save as", + "cancel": "Cancel", + "ok": "OK", + "delete": "Delete", + "add": "Add", + "yes": "Yes", + "no": "No", + "update": "Update", + "remove": "Remove", + "search": "Search", + "clear-search": "Clear search", + "assign": "Assign", + "unassign": "Unassign", + "share": "Share", + "make-private": "Make private", + "apply": "Apply", + "apply-changes": "Apply changes", + "edit-mode": "Edit mode", + "enter-edit-mode": "Enter edit mode", + "decline-changes": "Decline changes", + "close": "Close", + "back": "Back", + "run": "Run", + "sign-in": "Sign in!", + "edit": "Edit", + "view": "View", + "create": "Create", + "drag": "Drag", + "refresh": "Refresh", + "undo": "Undo", + "copy": "Copy", + "paste": "Paste", + "copy-reference": "Copy reference", + "paste-reference": "Paste reference", + "import": "Import", + "export": "Export", + "share-via": "Share via {{provider}}" + }, + "aggregation": { + "aggregation": "Aggregation", + "function": "Data aggregation function", + "limit": "Max values", + "group-interval": "Grouping interval", + "min": "Min", + "max": "Max", + "avg": "Average", + "sum": "Sum", + "count": "Count", + "none": "None" + }, + "admin": { + "general": "General", + "general-settings": "General Settings", + "outgoing-mail": "Outgoing Mail", + "outgoing-mail-settings": "Outgoing Mail Settings", + "system-settings": "System Settings", + "test-mail-sent": "Test mail was successfully sent!", + "base-url": "Base URL", + "base-url-required": "Base URL is required.", + "mail-from": "Mail From", + "mail-from-required": "Mail From is required.", + "smtp-protocol": "SMTP 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-invalid": "That doesn't look like a valid smtp port.", + "timeout-msec": "Timeout (msec)", + "timeout-required": "Timeout is required.", + "timeout-invalid": "That doesn't look like a valid timeout.", + "enable-tls": "Enable TLS", + "send-test-mail": "Send test mail" + }, + "alarm": { + "alarm": "Alarm", + "alarms": "Alarms", + "select-alarm": "Select alarm", + "no-alarms-matching": "No alarms matching '{{entity}}' were found.", + "alarm-required": "Alarm is required", + "alarm-status": "Alarm status", + "search-status": { + "ANY": "Any", + "ACTIVE": "Active", + "CLEARED": "Cleared", + "ACK": "Acknowledged", + "UNACK": "Unacknowledged" + }, + "display-status": { + "ACTIVE_UNACK": "Active Unacknowledged", + "ACTIVE_ACK": "Active Acknowledged", + "CLEARED_UNACK": "Cleared Unacknowledged", + "CLEARED_ACK": "Cleared Acknowledged" + }, + "no-alarms-prompt": "No alarms found", + "created-time": "Created time", + "type": "Type", + "severity": "Severity", + "originator": "Originator", + "originator-type": "Originator type", + "details": "Details", + "status": "Status", + "alarm-details": "Alarm details", + "start-time": "Start time", + "end-time": "End time", + "ack-time": "Acknowledged time", + "clear-time": "Cleared time", + "severity-critical": "Critical", + "severity-major": "Major", + "severity-minor": "Minor", + "severity-warning": "Warning", + "severity-indeterminate": "Indeterminate", + "acknowledge": "Acknowledge", + "clear": "Clear", + "search": "Search alarms", + "selected-alarms": "{ count, plural, 1 {1 alarm} other {# alarms} } selected", + "no-data": "No data to display", + "polling-interval": "Alarms polling interval (sec)", + "polling-interval-required": "Alarms polling interval is required.", + "min-polling-interval-message": "At least 1 sec polling interval is allowed.", + "aknowledge-alarms-title": "Acknowledge { count, plural, 1 {1 alarm} other {# alarms} }", + "aknowledge-alarms-text": "Are you sure you want to acknowledge { count, plural, 1 {1 alarm} other {# alarms} }?", + "clear-alarms-title": "Clear { count, plural, 1 {1 alarm} other {# alarms} }", + "clear-alarms-text": "Are you sure you want to clear { count, plural, 1 {1 alarm} other {# alarms} }?" + }, + "alias": { + "add": "Add alias", + "edit": "Edit alias", + "name": "Alias name", + "name-required": "Alias name is required", + "duplicate-alias": "Alias with same name is already exists.", + "filter-type-single-entity": "Single entity", + "filter-type-entity-list": "Entity list", + "filter-type-entity-name": "Entity name", + "filter-type-state-entity": "Entity from dashboard state", + "filter-type-state-entity-description": "Entity taken from dashboard state parameters", + "filter-type-asset-type": "Asset type", + "filter-type-asset-type-description": "Assets of type '{{assetType}}'", + "filter-type-asset-type-and-name-description": "Assets of type '{{assetType}}' and with name starting with '{{prefix}}'", + "filter-type-device-type": "Device type", + "filter-type-device-type-description": "Devices of type '{{deviceType}}'", + "filter-type-device-type-and-name-description": "Devices of type '{{deviceType}}' and with name starting with '{{prefix}}'", + "filter-type-relations-query": "Relations query", + "filter-type-relations-query-description": "{{entities}} that have {{relationType}} relation {{direction}} {{rootEntity}}", + "filter-type-asset-search-query": "Asset search query", + "filter-type-asset-search-query-description": "Assets with types {{assetTypes}} that have {{relationType}} relation {{direction}} {{rootEntity}}", + "filter-type-device-search-query": "Device search query", + "filter-type-device-search-query-description": "Devices with types {{deviceTypes}} that have {{relationType}} relation {{direction}} {{rootEntity}}", + "entity-filter": "Entity filter", + "resolve-multiple": "Resolve as multiple entities", + "filter-type": "Filter type", + "filter-type-required": "Filter type is required.", + "entity-filter-no-entity-matched": "No entities matching specified filter were found.", + "no-entity-filter-specified": "No entity filter specified", + "root-state-entity": "Use dashboard state entity as root", + "root-entity": "Root entity", + "state-entity-parameter-name": "State entity parameter name", + "default-state-entity": "Default state entity", + "default-entity-parameter-name": "By default", + "max-relation-level": "Max relation level", + "unlimited-level": "Unlimited level", + "state-entity": "Dashboard state entity", + "all-entities": "All entities", + "any-relation": "any" + }, + "asset": { + "asset": "Asset", + "assets": "Assets", + "management": "Asset management", + "view-assets": "View Assets", + "add": "Add Asset", + "assign-to-customer": "Assign to customer", + "assign-asset-to-customer": "Assign Asset(s) To Customer", + "assign-asset-to-customer-text": "Please select the assets to assign to the customer", + "no-assets-text": "No assets found", + "assign-to-customer-text": "Please select the customer to assign the asset(s)", + "public": "Public", + "assignedToCustomer": "Assigned to customer", + "make-public": "Make asset public", + "make-private": "Make asset private", + "unassign-from-customer": "Unassign from customer", + "delete": "Delete asset", + "asset-public": "Asset is public", + "asset-type": "Asset type", + "asset-type-required": "Asset type is required.", + "select-asset-type": "Select asset type", + "enter-asset-type": "Enter asset type", + "any-asset": "Any asset", + "no-asset-types-matching": "No asset types matching '{{entitySubtype}}' were found.", + "asset-type-list-empty": "No asset types selected.", + "asset-types": "Asset types", + "name": "Name", + "name-required": "Name is required.", + "description": "Description", + "type": "Type", + "type-required": "Type is required.", + "details": "Details", + "events": "Events", + "add-asset-text": "Add new asset", + "asset-details": "Asset details", + "assign-assets": "Assign assets", + "assign-assets-text": "Assign { count, plural, 1 {1 asset} other {# assets} } to customer", + "delete-assets": "Delete assets", + "unassign-assets": "Unassign assets", + "unassign-assets-action-title": "Unassign { count, plural, 1 {1 asset} other {# assets} } from customer", + "assign-new-asset": "Assign new asset", + "delete-asset-title": "Are you sure you want to delete the asset '{{assetName}}'?", + "delete-asset-text": "Be careful, after the confirmation the asset and all related data will become unrecoverable.", + "delete-assets-title": "Are you sure you want to delete { count, plural, 1 {1 asset} other {# assets} }?", + "delete-assets-action-title": "Delete { count, plural, 1 {1 asset} other {# assets} }", + "delete-assets-text": "Be careful, after the confirmation all selected assets will be removed and all related data will become unrecoverable.", + "make-public-asset-title": "Are you sure you want to make the asset '{{assetName}}' public?", + "make-public-asset-text": "After the confirmation the asset and all its data will be made public and accessible by others.", + "make-private-asset-title": "Are you sure you want to make the asset '{{assetName}}' private?", + "make-private-asset-text": "After the confirmation the asset and all its data will be made private and won't be accessible by others.", + "unassign-asset-title": "Are you sure you want to unassign the asset '{{assetName}}'?", + "unassign-asset-text": "After the confirmation the asset will be unassigned and won't be accessible by the customer.", + "unassign-asset": "Unassign asset", + "unassign-assets-title": "Are you sure you want to unassign { count, plural, 1 {1 asset} other {# assets} }?", + "unassign-assets-text": "After the confirmation all selected assets will be unassigned and won't be accessible by the customer.", + "copyId": "Copy asset Id", + "idCopiedMessage": "Asset Id has been copied to clipboard", + "select-asset": "Select asset", + "no-assets-matching": "No assets matching '{{entity}}' were found.", + "asset-required": "Asset is required", + "name-starts-with": "Asset name starts with" + }, + "attribute": { + "attributes": "Attributes", + "latest-telemetry": "Latest telemetry", + "attributes-scope": "Entity attributes scope", + "scope-latest-telemetry": "Latest telemetry", + "scope-client": "Client attributes", + "scope-server": "Server attributes", + "scope-shared": "Shared attributes", + "add": "Add attribute", + "key": "Key", + "last-update-time": "Last update time", + "key-required": "Attribute key is required.", + "value": "Value", + "value-required": "Attribute value is required.", + "delete-attributes-title": "Are you sure you want to delete { count, plural, 1 {1 attribute} other {# attributes} }?", + "delete-attributes-text": "Be careful, after the confirmation all selected attributes will be removed.", + "delete-attributes": "Delete attributes", + "enter-attribute-value": "Enter attribute value", + "show-on-widget": "Show on widget", + "widget-mode": "Widget mode", + "next-widget": "Next widget", + "prev-widget": "Previous widget", + "add-to-dashboard": "Add to dashboard", + "add-widget-to-dashboard": "Add widget to dashboard", + "selected-attributes": "{ count, plural, 1 {1 attribute} other {# attributes} } selected", + "selected-telemetry": "{ count, plural, 1 {1 telemetry unit} other {# telemetry units} } selected" + }, + "audit-log": { + "audit": "Audit", + "audit-logs": "Audit Logs", + "timestamp": "Timestamp", + "entity-type": "Entity Type", + "entity-name": "Entity Name", + "user": "User", + "type": "Type", + "status": "Status", + "details": "Details", + "type-added": "Added", + "type-deleted": "Deleted", + "type-updated": "Updated", + "type-attributes-updated": "Attributes updated", + "type-attributes-deleted": "Attributes deleted", + "type-rpc-call": "RPC call", + "type-credentials-updated": "Credentials updated", + "type-assigned-to-customer": "Assigned to Customer", + "type-unassigned-from-customer": "Unassigned from Customer", + "type-activated": "Activated", + "type-suspended": "Suspended", + "type-credentials-read": "Credentials read", + "type-attributes-read": "Attributes read", + "type-relation-add-or-update": "Relation updated", + "type-relation-delete": "Relation deleted", + "type-relations-delete": "All relation deleted", + "type-alarm-ack": "Acknowledged", + "type-alarm-clear": "Cleared", + "status-success": "Success", + "status-failure": "Failure", + "audit-log-details": "Audit log details", + "no-audit-logs-prompt": "No logs found", + "action-data": "Action data", + "failure-details": "Failure details", + "search": "Search audit logs", + "clear-search": "Clear search" + }, + "confirm-on-exit": { + "message": "You have unsaved changes. Are you sure you want to leave this page?", + "html-message": "You have unsaved changes.
Are you sure you want to leave this page?", + "title": "Unsaved changes" + }, + "contact": { + "country": "Country", + "city": "City", + "state": "State / Province", + "postal-code": "Zip / Postal Code", + "postal-code-invalid": "Invalid Zip / Postal Code format.", + "address": "Address", + "address2": "Address 2", + "phone": "Phone", + "email": "Email", + "no-address": "No address" + }, + "common": { + "username": "Username", + "password": "Password", + "enter-username": "Enter username", + "enter-password": "Enter password", + "enter-search": "Enter search" + }, + "content-type": { + "json": "Json", + "text": "Text", + "binary": "Binary (Base64)" + }, + "customer": { + "customer": "Customer", + "customers": "Customers", + "management": "Customer management", + "dashboard": "Customer Dashboard", + "dashboards": "Customer Dashboards", + "devices": "Customer Devices", + "assets": "Customer Assets", + "public-dashboards": "Public Dashboards", + "public-devices": "Public Devices", + "public-assets": "Public Assets", + "add": "Add Customer", + "delete": "Delete customer", + "manage-customer-users": "Manage customer users", + "manage-customer-devices": "Manage customer devices", + "manage-customer-dashboards": "Manage customer dashboards", + "manage-public-devices": "Manage public devices", + "manage-public-dashboards": "Manage public dashboards", + "manage-customer-assets": "Manage customer assets", + "manage-public-assets": "Manage public assets", + "add-customer-text": "Add new customer", + "no-customers-text": "No customers found", + "customer-details": "Customer details", + "delete-customer-title": "Are you sure you want to delete the customer '{{customerTitle}}'?", + "delete-customer-text": "Be careful, after the confirmation the customer and all related data will become unrecoverable.", + "delete-customers-title": "Are you sure you want to delete { count, plural, 1 {1 customer} other {# customers} }?", + "delete-customers-action-title": "Delete { count, plural, 1 {1 customer} other {# customers} }", + "delete-customers-text": "Be careful, after the confirmation all selected customers will be removed and all related data will become unrecoverable.", + "manage-users": "Manage users", + "manage-assets": "Manage assets", + "manage-devices": "Manage devices", + "manage-dashboards": "Manage dashboards", + "title": "Title", + "title-required": "Title is required.", + "description": "Description", + "details": "Details", + "events": "Events", + "copyId": "Copy customer Id", + "idCopiedMessage": "Customer Id has been copied to clipboard", + "select-customer": "Select customer", + "no-customers-matching": "No customers matching '{{entity}}' were found.", + "customer-required": "Customer is required", + "select-default-customer": "Select default customer", + "default-customer": "Default customer", + "default-customer-required": "Default customer is required in order to debug dashboard on Tenant level" + }, + "datetime": { + "date-from": "Date from", + "time-from": "Time from", + "date-to": "Date to", + "time-to": "Time to" + }, + "dashboard": { + "dashboard": "Dashboard", + "dashboards": "Dashboards", + "management": "Dashboard management", + "view-dashboards": "View Dashboards", + "add": "Add Dashboard", + "assign-dashboard-to-customer": "Assign Dashboard(s) To Customer", + "assign-dashboard-to-customer-text": "Please select the dashboards to assign to the customer", + "assign-to-customer-text": "Please select the customer to assign the dashboard(s)", + "assign-to-customer": "Assign to customer", + "unassign-from-customer": "Unassign from customer", + "make-public": "Make dashboard public", + "make-private": "Make dashboard private", + "manage-assigned-customers": "Manage assigned customers", + "assigned-customers": "Assigned customers", + "assign-to-customers": "Assign Dashboard(s) To Customers", + "assign-to-customers-text": "Please select the customers to assign the dashboard(s)", + "unassign-from-customers": "Unassign Dashboard(s) From Customers", + "unassign-from-customers-text": "Please select the customers to unassign from the dashboard(s)", + "no-dashboards-text": "No dashboards found", + "no-widgets": "No widgets configured", + "add-widget": "Add new widget", + "title": "Title", + "select-widget-title": "Select widget", + "select-widget-subtitle": "List of available widget types", + "delete": "Delete dashboard", + "title-required": "Title is required.", + "description": "Description", + "details": "Details", + "dashboard-details": "Dashboard details", + "add-dashboard-text": "Add new dashboard", + "assign-dashboards": "Assign dashboards", + "assign-new-dashboard": "Assign new dashboard", + "assign-dashboards-text": "Assign { count, plural, 1 {1 dashboard} other {# dashboards} } to customers", + "unassign-dashboards-action-text": "Unassign { count, plural, 1 {1 dashboard} other {# dashboards} } from customers", + "delete-dashboards": "Delete dashboards", + "unassign-dashboards": "Unassign dashboards", + "unassign-dashboards-action-title": "Unassign { count, plural, 1 {1 dashboard} other {# dashboards} } from customer", + "delete-dashboard-title": "Are you sure you want to delete the dashboard '{{dashboardTitle}}'?", + "delete-dashboard-text": "Be careful, after the confirmation the dashboard and all related data will become unrecoverable.", + "delete-dashboards-title": "Are you sure you want to delete { count, plural, 1 {1 dashboard} other {# dashboards} }?", + "delete-dashboards-action-title": "Delete { count, plural, 1 {1 dashboard} other {# dashboards} }", + "delete-dashboards-text": "Be careful, after the confirmation all selected dashboards will be removed and all related data will become unrecoverable.", + "unassign-dashboard-title": "Are you sure you want to unassign the dashboard '{{dashboardTitle}}'?", + "unassign-dashboard-text": "After the confirmation the dashboard will be unassigned and won't be accessible by the customer.", + "unassign-dashboard": "Unassign dashboard", + "unassign-dashboards-title": "Are you sure you want to unassign { count, plural, 1 {1 dashboard} other {# dashboards} }?", + "unassign-dashboards-text": "After the confirmation all selected dashboards will be unassigned and won't be accessible by the customer.", + "public-dashboard-title": "Dashboard is now public", + "public-dashboard-text": "Your dashboard {{dashboardTitle}} is now public and accessible via next public link:", + "public-dashboard-notice": "Note: Do not forget to make related devices public in order to access their data.", + "make-private-dashboard-title": "Are you sure you want to make the dashboard '{{dashboardTitle}}' private?", + "make-private-dashboard-text": "After the confirmation the dashboard will be made private and won't be accessible by others.", + "make-private-dashboard": "Make dashboard private", + "socialshare-text": "'{{dashboardTitle}}' powered by ThingsBoard", + "socialshare-title": "'{{dashboardTitle}}' powered by ThingsBoard", + "select-dashboard": "Select dashboard", + "no-dashboards-matching": "No dashboards matching '{{entity}}' were found.", + "dashboard-required": "Dashboard is required.", + "select-existing": "Select existing dashboard", + "create-new": "Create new dashboard", + "new-dashboard-title": "New dashboard title", + "open-dashboard": "Open dashboard", + "set-background": "Set background", + "background-color": "Background color", + "background-image": "Background image", + "background-size-mode": "Background size mode", + "no-image": "No image selected", + "drop-image": "Drop an image or click to select a file to upload.", + "settings": "Settings", + "columns-count": "Columns count", + "columns-count-required": "Columns count is required.", + "min-columns-count-message": "Only 10 minimum column count is allowed.", + "max-columns-count-message": "Only 1000 maximum column count is allowed.", + "widgets-margins": "Margin between widgets", + "horizontal-margin": "Horizontal margin", + "horizontal-margin-required": "Horizontal margin value is required.", + "min-horizontal-margin-message": "Only 0 is allowed as minimum horizontal margin value.", + "max-horizontal-margin-message": "Only 50 is allowed as maximum horizontal margin value.", + "vertical-margin": "Vertical margin", + "vertical-margin-required": "Vertical margin value is required.", + "min-vertical-margin-message": "Only 0 is allowed as minimum vertical margin value.", + "max-vertical-margin-message": "Only 50 is allowed as maximum vertical margin value.", + "autofill-height": "Auto fill layout height", + "mobile-layout": "Mobile layout settings", + "mobile-row-height": "Mobile row height, px", + "mobile-row-height-required": "Mobile row height value is required.", + "min-mobile-row-height-message": "Only 5 pixels is allowed as minimum mobile row height value.", + "max-mobile-row-height-message": "Only 200 pixels is allowed as maximum mobile row height value.", + "display-title": "Display dashboard title", + "toolbar-always-open": "Keep toolbar opened", + "title-color": "Title color", + "display-dashboards-selection": "Display dashboards selection", + "display-entities-selection": "Display entities selection", + "display-dashboard-timewindow": "Display timewindow", + "display-dashboard-export": "Display export", + "import": "Import dashboard", + "export": "Export dashboard", + "export-failed-error": "Unable to export dashboard: {{error}}", + "create-new-dashboard": "Create new dashboard", + "dashboard-file": "Dashboard file", + "invalid-dashboard-file-error": "Unable to import dashboard: Invalid dashboard data structure.", + "dashboard-import-missing-aliases-title": "Configure aliases used by imported dashboard", + "create-new-widget": "Create new widget", + "import-widget": "Import widget", + "widget-file": "Widget file", + "invalid-widget-file-error": "Unable to import widget: Invalid widget data structure.", + "widget-import-missing-aliases-title": "Configure aliases used by imported widget", + "open-toolbar": "Open dashboard toolbar", + "close-toolbar": "Close toolbar", + "configuration-error": "Configuration error", + "alias-resolution-error-title": "Dashboard aliases configuration error", + "invalid-aliases-config": "Unable to find any devices matching to some of the aliases filter.
Please contact your administrator in order to resolve this issue.", + "select-devices": "Select devices", + "assignedToCustomer": "Assigned to customer", + "assignedToCustomers": "Assigned to customers", + "public": "Public", + "public-link": "Public link", + "copy-public-link": "Copy public link", + "public-link-copied-message": "Dashboard public link has been copied to clipboard", + "manage-states": "Manage dashboard states", + "states": "Dashboard states", + "search-states": "Search dashboard states", + "selected-states": "{ count, plural, 1 {1 dashboard state} other {# dashboard states} } selected", + "edit-state": "Edit dashboard state", + "delete-state": "Delete dashboard state", + "add-state": "Add dashboard state", + "state": "Dashboard state", + "state-name": "Name", + "state-name-required": "Dashboard state name is required.", + "state-id": "State Id", + "state-id-required": "Dashboard state id is required.", + "state-id-exists": "Dashboard state with the same id is already exists.", + "is-root-state": "Root state", + "delete-state-title": "Delete dashboard state", + "delete-state-text": "Are you sure you want delete dashboard state with name '{{stateName}}'?", + "show-details": "Show details", + "hide-details": "Hide details", + "select-state": "Select target state", + "state-controller": "State controller" + }, + "datakey": { + "settings": "Settings", + "advanced": "Advanced", + "label": "Label", + "color": "Color", + "units": "Special symbol to show next to value", + "decimals": "Number of digits after floating point", + "data-generation-func": "Data generation function", + "use-data-post-processing-func": "Use data post-processing function", + "configuration": "Data key configuration", + "timeseries": "Timeseries", + "attributes": "Attributes", + "alarm": "Alarm fields", + "timeseries-required": "Entity timeseries are required.", + "timeseries-or-attributes-required": "Entity timeseries/attributes are required.", + "maximum-timeseries-or-attributes": "Maximum { count, plural, 1 {1 timeseries/attribute is allowed.} other {# timeseries/attributes are allowed} }", + "alarm-fields-required": "Alarm fields are required.", + "function-types": "Function types", + "function-types-required": "Function types are required.", + "maximum-function-types": "Maximum { count, plural, 1 {1 function type is allowed.} other {# function types are allowed} }" + }, + "datasource": { + "type": "Datasource type", + "name": "Name", + "add-datasource-prompt": "Please add datasource" + }, + "details": { + "edit-mode": "Edit mode", + "toggle-edit-mode": "Toggle edit mode" + }, + "device": { + "device": "Device", + "device-required": "Device is required.", + "devices": "Devices", + "management": "Device management", + "view-devices": "View Devices", + "device-alias": "Device alias", + "aliases": "Device aliases", + "no-alias-matching": "'{{alias}}' not found.", + "no-aliases-found": "No aliases found.", + "no-key-matching": "'{{key}}' not found.", + "no-keys-found": "No keys found.", + "create-new-alias": "Create a new one!", + "create-new-key": "Create a new one!", + "duplicate-alias-error": "Duplicate alias found '{{alias}}'.
Device aliases must be unique whithin the dashboard.", + "configure-alias": "Configure '{{alias}}' alias", + "no-devices-matching": "No devices matching '{{entity}}' were found.", + "alias": "Alias", + "alias-required": "Device alias is required.", + "remove-alias": "Remove device alias", + "add-alias": "Add device alias", + "name-starts-with": "Device name starts with", + "device-list": "Device list", + "use-device-name-filter": "Use filter", + "device-list-empty": "No devices selected.", + "device-name-filter-required": "Device name filter is required.", + "device-name-filter-no-device-matched": "No devices starting with '{{device}}' were found.", + "add": "Add Device", + "assign-to-customer": "Assign to customer", + "assign-device-to-customer": "Assign Device(s) To Customer", + "assign-device-to-customer-text": "Please select the devices to assign to the customer", + "make-public": "Make device public", + "make-private": "Make device private", + "no-devices-text": "No devices found", + "assign-to-customer-text": "Please select the customer to assign the device(s)", + "device-details": "Device details", + "add-device-text": "Add new device", + "credentials": "Credentials", + "manage-credentials": "Manage credentials", + "delete": "Delete device", + "assign-devices": "Assign devices", + "assign-devices-text": "Assign { count, plural, 1 {1 device} other {# devices} } to customer", + "delete-devices": "Delete devices", + "unassign-from-customer": "Unassign from customer", + "unassign-devices": "Unassign devices", + "unassign-devices-action-title": "Unassign { count, plural, 1 {1 device} other {# devices} } from customer", + "assign-new-device": "Assign new device", + "make-public-device-title": "Are you sure you want to make the device '{{deviceName}}' public?", + "make-public-device-text": "After the confirmation the device and all its data will be made public and accessible by others.", + "make-private-device-title": "Are you sure you want to make the device '{{deviceName}}' private?", + "make-private-device-text": "After the confirmation the device and all its data will be made private and won't be accessible by others.", + "view-credentials": "View credentials", + "delete-device-title": "Are you sure you want to delete the device '{{deviceName}}'?", + "delete-device-text": "Be careful, after the confirmation the device and all related data will become unrecoverable.", + "delete-devices-title": "Are you sure you want to delete { count, plural, 1 {1 device} other {# devices} }?", + "delete-devices-action-title": "Delete { count, plural, 1 {1 device} other {# devices} }", + "delete-devices-text": "Be careful, after the confirmation all selected devices will be removed and all related data will become unrecoverable.", + "unassign-device-title": "Are you sure you want to unassign the device '{{deviceName}}'?", + "unassign-device-text": "After the confirmation the device will be unassigned and won't be accessible by the customer.", + "unassign-device": "Unassign device", + "unassign-devices-title": "Are you sure you want to unassign { count, plural, 1 {1 device} other {# devices} }?", + "unassign-devices-text": "After the confirmation all selected devices will be unassigned and won't be accessible by the customer.", + "device-credentials": "Device Credentials", + "credentials-type": "Credentials type", + "access-token": "Access token", + "access-token-required": "Access token is required.", + "access-token-invalid": "Access token length must be from 1 to 20 characters.", + "rsa-key": "RSA public key", + "rsa-key-required": "RSA public key is required.", + "secret": "Secret", + "secret-required": "Secret is required.", + "device-type": "Device type", + "device-type-required": "Device type is required.", + "select-device-type": "Select device type", + "enter-device-type": "Enter device type", + "any-device": "Any device", + "no-device-types-matching": "No device types matching '{{entitySubtype}}' were found.", + "device-type-list-empty": "No device types selected.", + "device-types": "Device types", + "name": "Name", + "name-required": "Name is required.", + "description": "Description", + "events": "Events", + "details": "Details", + "copyId": "Copy device Id", + "copyAccessToken": "Copy access token", + "idCopiedMessage": "Device Id has been copied to clipboard", + "accessTokenCopiedMessage": "Device access token has been copied to clipboard", + "assignedToCustomer": "Assigned to customer", + "unable-delete-device-alias-title": "Unable to delete device alias", + "unable-delete-device-alias-text": "Device alias '{{deviceAlias}}' can't be deleted as it used by the following widget(s):
{{widgetsList}}", + "is-gateway": "Is gateway", + "public": "Public", + "device-public": "Device is public", + "select-device": "Select device" + }, + "dialog": { + "close": "Close dialog" + }, + "error": { + "unable-to-connect": "Unable to connect to the server! Please check your internet connection.", + "unhandled-error-code": "Unhandled error code: {{errorCode}}", + "unknown-error": "Unknown error" + }, + "entity": { + "entity": "Entity", + "entities": "Entities", + "aliases": "Entity aliases", + "entity-alias": "Entity alias", + "unable-delete-entity-alias-title": "Unable to delete entity alias", + "unable-delete-entity-alias-text": "Entity alias '{{entityAlias}}' can't be deleted as it used by the following widget(s):
{{widgetsList}}", + "duplicate-alias-error": "Duplicate alias found '{{alias}}'.
Entity aliases must be unique whithin the dashboard.", + "missing-entity-filter-error": "Filter is missing for alias '{{alias}}'.", + "configure-alias": "Configure '{{alias}}' alias", + "alias": "Alias", + "alias-required": "Entity alias is required.", + "remove-alias": "Remove entity alias", + "add-alias": "Add entity alias", + "entity-list": "Entity list", + "entity-type": "Entity type", + "entity-types": "Entity types", + "entity-type-list": "Entity type list", + "any-entity": "Any entity", + "enter-entity-type": "Enter entity type", + "no-entities-matching": "No entities matching '{{entity}}' were found.", + "no-entity-types-matching": "No entity types matching '{{entityType}}' were found.", + "name-starts-with": "Name starts with", + "use-entity-name-filter": "Use filter", + "entity-list-empty": "No entities selected.", + "entity-type-list-empty": "No entity types selected.", + "entity-name-filter-required": "Entity name filter is required.", + "entity-name-filter-no-entity-matched": "No entities starting with '{{entity}}' were found.", + "all-subtypes": "All", + "select-entities": "Select entities", + "no-aliases-found": "No aliases found.", + "no-alias-matching": "'{{alias}}' not found.", + "create-new-alias": "Create a new one!", + "key": "Key", + "key-name": "Key name", + "no-keys-found": "No keys found.", + "no-key-matching": "'{{key}}' not found.", + "create-new-key": "Create a new one!", + "type": "Type", + "type-required": "Entity type is required.", + "type-device": "Device", + "type-devices": "Devices", + "list-of-devices": "{ count, plural, 1 {One device} other {List of # devices} }", + "device-name-starts-with": "Devices whose names start with '{{prefix}}'", + "type-asset": "Asset", + "type-assets": "Assets", + "list-of-assets": "{ count, plural, 1 {One asset} other {List of # assets} }", + "asset-name-starts-with": "Assets whose names start with '{{prefix}}'", + "type-rule": "Rule", + "type-rules": "Rules", + "list-of-rules": "{ count, plural, 1 {One rule} other {List of # rules} }", + "rule-name-starts-with": "Rules whose names start with '{{prefix}}'", + "type-plugin": "Plugin", + "type-plugins": "Plugins", + "list-of-plugins": "{ count, plural, 1 {One plugin} other {List of # plugins} }", + "plugin-name-starts-with": "Plugins whose names start with '{{prefix}}'", + "type-tenant": "Tenant", + "type-tenants": "Tenants", + "list-of-tenants": "{ count, plural, 1 {One tenant} other {List of # tenants} }", + "tenant-name-starts-with": "Tenants whose names start with '{{prefix}}'", + "type-customer": "Customer", + "type-customers": "Customers", + "list-of-customers": "{ count, plural, 1 {One customer} other {List of # customers} }", + "customer-name-starts-with": "Customers whose names start with '{{prefix}}'", + "type-user": "User", + "type-users": "Users", + "list-of-users": "{ count, plural, 1 {One user} other {List of # users} }", + "user-name-starts-with": "Users whose names start with '{{prefix}}'", + "type-dashboard": "Dashboard", + "type-dashboards": "Dashboards", + "list-of-dashboards": "{ count, plural, 1 {One dashboard} other {List of # dashboards} }", + "dashboard-name-starts-with": "Dashboards whose names start with '{{prefix}}'", + "type-alarm": "Alarm", + "type-alarms": "Alarms", + "list-of-alarms": "{ count, plural, 1 {One alarms} other {List of # alarms} }", + "alarm-name-starts-with": "Alarms whose names start with '{{prefix}}'", + "type-rulechain": "Rule chain", + "type-rulechains": "Rule chains", + "list-of-rulechains": "{ count, plural, 1 {One rule chain} other {List of # rule chains} }", + "rulechain-name-starts-with": "Rule chains whose names start with '{{prefix}}'", + "type-rulenode": "Rule node", + "type-rulenodes": "Rule nodes", + "list-of-rulenodes": "{ count, plural, 1 {One rule node} other {List of # rule nodes} }", + "rulenode-name-starts-with": "Rule nodes whose names start with '{{prefix}}'", + "type-current-customer": "Current Customer", + "search": "Search entities", + "selected-entities": "{ count, plural, 1 {1 entity} other {# entities} } selected", + "entity-name": "Entity name", + "details": "Entity details", + "no-entities-prompt": "No entities found", + "no-data": "No data to display" + }, + "event": { + "event-type": "Event type", + "type-error": "Error", + "type-lc-event": "Lifecycle event", + "type-stats": "Statistics", + "type-debug-rule-node": "Debug", + "type-debug-rule-chain": "Debug", + "no-events-prompt": "No events found", + "error": "Error", + "alarm": "Alarm", + "event-time": "Event time", + "server": "Server", + "body": "Body", + "method": "Method", + "type": "Type", + "entity": "Entity", + "message-id": "Message Id", + "message-type": "Message Type", + "data-type": "Data Type", + "relation-type": "Relation Type", + "metadata": "Metadata", + "data": "Data", + "event": "Event", + "status": "Status", + "success": "Success", + "failed": "Failed", + "messages-processed": "Messages processed", + "errors-occurred": "Errors occurred" + }, + "extension": { + "extensions": "Extensions", + "selected-extensions": "{ count, plural, 1 {1 extension} other {# extensions} } selected", + "type": "Type", + "key": "Key", + "value": "Value", + "id": "Id", + "extension-id": "Extension id", + "extension-type": "Extension type", + "transformer-json": "JSON *", + "unique-id-required": "Current extension id already exists.", + "delete": "Delete extension", + "add": "Add extension", + "edit": "Edit extension", + "delete-extension-title": "Are you sure you want to delete the extension '{{extensionId}}'?", + "delete-extension-text": "Be careful, after the confirmation the extension and all related data will become unrecoverable.", + "delete-extensions-title": "Are you sure you want to delete { count, plural, 1 {1 extension} other {# extensions} }?", + "delete-extensions-text": "Be careful, after the confirmation all selected extensions will be removed.", + "converters": "Converters", + "converter-id": "Converter id", + "configuration": "Configuration", + "converter-configurations": "Converter configurations", + "token": "Security token", + "add-converter": "Add converter", + "add-config": "Add converter configuration", + "device-name-expression": "Device name expression", + "device-type-expression": "Device type expression", + "custom": "Custom", + "to-double": "To Double", + "transformer": "Transformer", + "json-required": "Transformer json is required.", + "json-parse": "Unable to parse transformer json.", + "attributes": "Attributes", + "add-attribute": "Add attribute", + "add-map": "Add mapping element", + "timeseries": "Timeseries", + "add-timeseries": "Add timeseries", + "field-required": "Field is required", + "brokers": "Brokers", + "add-broker": "Add broker", + "host": "Host", + "port": "Port", + "port-range": "Port should be in a range from 1 to 65535.", + "ssl": "Ssl", + "credentials": "Credentials", + "username": "Username", + "password": "Password", + "retry-interval": "Retry interval in milliseconds", + "anonymous": "Anonymous", + "basic": "Basic", + "pem": "PEM", + "ca-cert": "CA certificate file *", + "private-key": "Private key file *", + "cert": "Certificate file *", + "no-file": "No file selected.", + "drop-file": "Drop a file or click to select a file to upload.", + "mapping": "Mapping", + "topic-filter": "Topic filter", + "converter-type": "Converter type", + "converter-json": "Json", + "json-name-expression": "Device name json expression", + "topic-name-expression": "Device name topic expression", + "json-type-expression": "Device type json expression", + "topic-type-expression": "Device type topic expression", + "attribute-key-expression": "Attribute key expression", + "attr-json-key-expression": "Attribute key json expression", + "attr-topic-key-expression": "Attribute key topic expression", + "request-id-expression": "Request id expression", + "request-id-json-expression": "Request id json expression", + "request-id-topic-expression": "Request id topic expression", + "response-topic-expression": "Response topic expression", + "value-expression": "Value expression", + "topic": "Topic", + "timeout": "Timeout in milliseconds", + "converter-json-required": "Converter json is required.", + "converter-json-parse": "Unable to parse converter json.", + "filter-expression": "Filter expression", + "connect-requests": "Connect requests", + "add-connect-request": "Add connect request", + "disconnect-requests": "Disconnect requests", + "add-disconnect-request": "Add disconnect request", + "attribute-requests": "Attribute requests", + "add-attribute-request": "Add attribute request", + "attribute-updates": "Attribute updates", + "add-attribute-update": "Add attribute update", + "server-side-rpc": "Server side RPC", + "add-server-side-rpc-request": "Add server-side RPC request", + "device-name-filter": "Device name filter", + "attribute-filter": "Attribute filter", + "method-filter": "Method filter", + "request-topic-expression": "Request topic expression", + "response-timeout": "Response timeout in milliseconds", + "topic-expression": "Topic expression", + "client-scope": "Client scope", + "add-device": "Add device", + "opc-server": "Servers", + "opc-add-server": "Add server", + "opc-add-server-prompt": "Please add server", + "opc-application-name": "Application name", + "opc-application-uri": "Application uri", + "opc-scan-period-in-seconds": "Scan period in seconds", + "opc-security": "Security", + "opc-identity": "Identity", + "opc-keystore": "Keystore", + "opc-type": "Type", + "opc-keystore-type": "Type", + "opc-keystore-location": "Location *", + "opc-keystore-password": "Password", + "opc-keystore-alias": "Alias", + "opc-keystore-key-password": "Key password", + "opc-device-node-pattern": "Device node pattern", + "opc-device-name-pattern": "Device name pattern", + "modbus-server": "Servers/slaves", + "modbus-add-server": "Add server/slave", + "modbus-add-server-prompt": "Please add server/slave", + "modbus-transport": "Transport", + "modbus-port-name": "Serial port name", + "modbus-encoding": "Encoding", + "modbus-parity": "Parity", + "modbus-baudrate": "Baud rate", + "modbus-databits": "Data bits", + "modbus-stopbits": "Stop bits", + "modbus-databits-range": "Data bits should be in a range from 7 to 8.", + "modbus-stopbits-range": "Stop bits should be in a range from 1 to 2.", + "modbus-unit-id": "Unit ID", + "modbus-unit-id-range": "Unit ID should be in a range from 1 to 247.", + "modbus-device-name": "Device name", + "modbus-poll-period": "Poll period (ms)", + "modbus-attributes-poll-period": "Attributes poll period (ms)", + "modbus-timeseries-poll-period": "Timeseries poll period (ms)", + "modbus-poll-period-range": "Poll period should be positive value.", + "modbus-tag": "Tag", + "modbus-function": "Function", + "modbus-register-address": "Register address", + "modbus-register-address-range": "Register address should be in a range from 0 to 65535.", + "modbus-register-bit-index": "Bit index", + "modbus-register-bit-index-range": "Bit index should be in a range from 0 to 15.", + "modbus-register-count": "Register count", + "modbus-register-count-range": "Register count should be a positive value.", + "modbus-byte-order": "Byte order", + + "sync": { + "status": "Status", + "sync": "Sync", + "not-sync": "Not sync", + "last-sync-time": "Last sync time", + "not-available": "Not available" + }, + + "export-extensions-configuration": "Export extensions configuration", + "import-extensions-configuration": "Import extensions configuration", + "import-extensions": "Import extensions", + "import-extension": "Import extension", + "export-extension": "Export extension", + "file": "Extensions file", + "invalid-file-error": "Invalid extension file" + }, + "fullscreen": { + "expand": "Expand to fullscreen", + "exit": "Exit fullscreen", + "toggle": "Toggle fullscreen mode", + "fullscreen": "Fullscreen" + }, + "function": { + "function": "Function" + }, + "grid": { + "delete-item-title": "Are you sure you want to delete this item?", + "delete-item-text": "Be careful, after the confirmation this item and all related data will become unrecoverable.", + "delete-items-title": "Are you sure you want to delete { count, plural, 1 {1 item} other {# items} }?", + "delete-items-action-title": "Delete { count, plural, 1 {1 item} other {# items} }", + "delete-items-text": "Be careful, after the confirmation all selected items will be removed and all related data will become unrecoverable.", + "add-item-text": "Add new item", + "no-items-text": "No items found", + "item-details": "Item details", + "delete-item": "Delete Item", + "delete-items": "Delete Items", + "scroll-to-top": "Scroll to top" + }, + "help": { + "goto-help-page": "Go to help page" + }, + "home": { + "home": "Home", + "profile": "Profile", + "logout": "Logout", + "menu": "Menu", + "avatar": "Avatar", + "open-user-menu": "Open user menu" + }, + "import": { + "no-file": "No file selected", + "drop-file": "Drop a JSON file or click to select a file to upload." + }, + "item": { + "selected": "Selected" + }, + "js-func": { + "no-return-error": "Function must return value!", + "return-type-mismatch": "Function must return value of '{{type}}' type!", + "tidy": "Tidy" + }, + "key-val": { + "key": "Key", + "value": "Value", + "remove-entry": "Remove entry", + "add-entry": "Add entry", + "no-data": "No entries" + }, + "layout": { + "layout": "Layout", + "manage": "Manage layouts", + "settings": "Layout settings", + "color": "Color", + "main": "Main", + "right": "Right", + "select": "Select target layout" + }, + "legend": { + "position": "Legend position", + "show-max": "Show max value", + "show-min": "Show min value", + "show-avg": "Show average value", + "show-total": "Show total value", + "settings": "Legend settings", + "min": "min", + "max": "max", + "avg": "avg", + "total": "total" + }, + "login": { + "login": "Login", + "request-password-reset": "Request Password Reset", + "reset-password": "Reset Password", + "create-password": "Create Password", + "passwords-mismatch-error": "Entered passwords must be same!", + "password-again": "Password again", + "sign-in": "Please sign in", + "username": "Username (email)", + "remember-me": "Remember me", + "forgot-password": "Forgot Password?", + "password-reset": "Password reset", + "new-password": "New password", + "new-password-again": "New password again", + "password-link-sent-message": "Password reset link was successfully sent!", + "email": "Email" + }, + "position": { + "top": "Top", + "bottom": "Bottom", + "left": "Left", + "right": "Right" + }, + "profile": { + "profile": "Profile", + "change-password": "Change Password", + "current-password": "Current password" + }, + "relation": { + "relations": "Relations", + "direction": "Direction", + "search-direction": { + "FROM": "From", + "TO": "To" + }, + "direction-type": { + "FROM": "from", + "TO": "to" + }, + "from-relations": "Outbound relations", + "to-relations": "Inbound relations", + "selected-relations": "{ count, plural, 1 {1 relation} other {# relations} } selected", + "type": "Type", + "to-entity-type": "To entity type", + "to-entity-name": "To entity name", + "from-entity-type": "From entity type", + "from-entity-name": "From entity name", + "to-entity": "To entity", + "from-entity": "From entity", + "delete": "Delete relation", + "relation-type": "Relation type", + "relation-type-required": "Relation type is required.", + "any-relation-type": "Any type", + "add": "Add relation", + "edit": "Edit relation", + "delete-to-relation-title": "Are you sure you want to delete relation to the entity '{{entityName}}'?", + "delete-to-relation-text": "Be careful, after the confirmation the entity '{{entityName}}' will be unrelated from the current entity.", + "delete-to-relations-title": "Are you sure you want to delete { count, plural, 1 {1 relation} other {# relations} }?", + "delete-to-relations-text": "Be careful, after the confirmation all selected relations will be removed and corresponding entities will be unrelated from the current entity.", + "delete-from-relation-title": "Are you sure you want to delete relation from the entity '{{entityName}}'?", + "delete-from-relation-text": "Be careful, after the confirmation current entity will be unrelated from the entity '{{entityName}}'.", + "delete-from-relations-title": "Are you sure you want to delete { count, plural, 1 {1 relation} other {# relations} }?", + "delete-from-relations-text": "Be careful, after the confirmation all selected relations will be removed and current entity will be unrelated from the corresponding entities.", + "remove-relation-filter": "Remove relation filter", + "add-relation-filter": "Add relation filter", + "any-relation": "Any relation", + "relation-filters": "Relation filters", + "additional-info": "Additional info (JSON)", + "invalid-additional-info": "Unable to parse additional info json." + }, + "rulechain": { + "rulechain": "Rule chain", + "rulechains": "Rule chains", + "root": "Root", + "delete": "Delete rule chain", + "name": "Name", + "name-required": "Name is required.", + "description": "Description", + "add": "Add Rule Chain", + "set-root": "Make rule chain root", + "set-root-rulechain-title": "Are you sure you want to make the rule chain '{{ruleChainName}}' root?", + "set-root-rulechain-text": "After the confirmation the rule chain will become root and will handle all incoming transport messages.", + "delete-rulechain-title": "Are you sure you want to delete the rule chain '{{ruleChainName}}'?", + "delete-rulechain-text": "Be careful, after the confirmation the rule chain and all related data will become unrecoverable.", + "delete-rulechains-title": "Are you sure you want to delete { count, plural, 1 {1 rule chain} other {# rule chains} }?", + "delete-rulechains-action-title": "Delete { count, plural, 1 {1 rule chain} other {# rule chains} }", + "delete-rulechains-text": "Be careful, after the confirmation all selected rule chains will be removed and all related data will become unrecoverable.", + "add-rulechain-text": "Add new rule chain", + "no-rulechains-text": "No rule chains found", + "rulechain-details": "Rule chain details", + "details": "Details", + "events": "Events", + "system": "System", + "import": "Import rule chain", + "export": "Export rule chain", + "export-failed-error": "Unable to export rule chain: {{error}}", + "create-new-rulechain": "Create new rule chain", + "rulechain-file": "Rule chain file", + "invalid-rulechain-file-error": "Unable to import rule chain: Invalid rule chain data structure.", + "copyId": "Copy rule chain Id", + "idCopiedMessage": "Rule chain Id has been copied to clipboard", + "select-rulechain": "Select rule chain", + "no-rulechains-matching": "No rule chains matching '{{entity}}' were found.", + "rulechain-required": "Rule chain is required", + "management": "Rules management", + "debug-mode": "Debug mode" + }, + "rulenode": { + "details": "Details", + "events": "Events", + "search": "Search nodes", + "open-node-library": "Open node library", + "add": "Add rule node", + "name": "Name", + "name-required": "Name is required.", + "type": "Type", + "description": "Description", + "delete": "Delete rule node", + "select-all-objects": "Select all nodes and connections", + "deselect-all-objects": "Deselect all nodes and connections", + "delete-selected-objects": "Delete selected nodes and connections", + "delete-selected": "Delete selected", + "select-all": "Select all", + "copy-selected": "Copy selected", + "deselect-all": "Deselect all", + "rulenode-details": "Rule node details", + "debug-mode": "Debug mode", + "configuration": "Configuration", + "link": "Link", + "link-details": "Rule node link details", + "add-link": "Add link", + "link-label": "Link label", + "link-label-required": "Link label is required.", + "custom-link-label": "Custom link label", + "custom-link-label-required": "Custom link label is required.", + "link-labels": "Link labels", + "link-labels-required": "Link labels is required.", + "no-link-labels-found": "No link labels found", + "no-link-label-matching": "'{{label}}' not found.", + "create-new-link-label": "Create a new one!", + "type-filter": "Filter", + "type-filter-details": "Filter incoming messages with configured conditions", + "type-enrichment": "Enrichment", + "type-enrichment-details": "Add additional information into Message Metadata", + "type-transformation": "Transformation", + "type-transformation-details": "Change Message payload and Metadata", + "type-action": "Action", + "type-action-details": "Perform special action", + "type-external": "External", + "type-external-details": "Interacts with external system", + "type-rule-chain": "Rule Chain", + "type-rule-chain-details": "Forwards incoming messages to specified Rule Chain", + "type-input": "Input", + "type-input-details": "Logical input of Rule Chain, forwards incoming messages to next related Rule Node", + "type-unknown": "Unknown", + "type-unknown-details": "Unresolved Rule Node", + "directive-is-not-loaded": "Defined configuration directive '{{directiveName}}' is not available.", + "ui-resources-load-error": "Failed to load configuration ui resources.", + "invalid-target-rulechain": "Unable to resolve target rule chain!", + "test-script-function": "Test script function", + "message": "Message", + "message-type": "Message type", + "select-message-type": "Select message type", + "message-type-required": "Message type is required", + "metadata": "Metadata", + "metadata-required": "Metadata entries can't be empty.", + "output": "Output", + "test": "Test", + "help": "Help" + }, + "tenant": { + "tenant": "Tenant", + "tenants": "Tenants", + "management": "Tenant management", + "add": "Add Tenant", + "admins": "Admins", + "manage-tenant-admins": "Manage tenant admins", + "delete": "Delete tenant", + "add-tenant-text": "Add new tenant", + "no-tenants-text": "No tenants found", + "tenant-details": "Tenant details", + "delete-tenant-title": "Are you sure you want to delete the tenant '{{tenantTitle}}'?", + "delete-tenant-text": "Be careful, after the confirmation the tenant and all related data will become unrecoverable.", + "delete-tenants-title": "Are you sure you want to delete { count, plural, 1 {1 tenant} other {# tenants} }?", + "delete-tenants-action-title": "Delete { count, plural, 1 {1 tenant} other {# tenants} }", + "delete-tenants-text": "Be careful, after the confirmation all selected tenants will be removed and all related data will become unrecoverable.", + "title": "Title", + "title-required": "Title is required.", + "description": "Description", + "details": "Details", + "events": "Events", + "copyId": "Copy tenant Id", + "idCopiedMessage": "Tenant Id has been copied to clipboard", + "select-tenant": "Select tenant", + "no-tenants-matching": "No tenants matching '{{entity}}' were found.", + "tenant-required": "Tenant is required" + }, + "timeinterval": { + "seconds-interval": "{ seconds, plural, 1 {1 second} other {# seconds} }", + "minutes-interval": "{ minutes, plural, 1 {1 minute} other {# minutes} }", + "hours-interval": "{ hours, plural, 1 {1 hour} other {# hours} }", + "days-interval": "{ days, plural, 1 {1 day} other {# days} }", + "days": "Days", + "hours": "Hours", + "minutes": "Minutes", + "seconds": "Seconds", + "advanced": "Advanced" + }, + "timewindow": { + "days": "{ days, plural, 1 { day } other {# days } }", + "hours": "{ hours, plural, 0 { hour } 1 {1 hour } other {# hours } }", + "minutes": "{ minutes, plural, 0 { minute } 1 {1 minute } other {# minutes } }", + "seconds": "{ seconds, plural, 0 { second } 1 {1 second } other {# seconds } }", + "realtime": "Realtime", + "history": "History", + "last-prefix": "last", + "period": "from {{ startTime }} to {{ endTime }}", + "edit": "Edit timewindow", + "date-range": "Date range", + "last": "Last", + "time-period": "Time period" + }, + "user": { + "user": "User", + "users": "Users", + "customer-users": "Customer Users", + "tenant-admins": "Tenant Admins", + "sys-admin": "System administrator", + "tenant-admin": "Tenant administrator", + "customer": "Customer", + "anonymous": "Anonymous", + "add": "Add User", + "delete": "Delete user", + "add-user-text": "Add new user", + "no-users-text": "No users found", + "user-details": "User details", + "delete-user-title": "Are you sure you want to delete the user '{{userEmail}}'?", + "delete-user-text": "Be careful, after the confirmation the user and all related data will become unrecoverable.", + "delete-users-title": "Are you sure you want to delete { count, plural, 1 {1 user} other {# users} }?", + "delete-users-action-title": "Delete { count, plural, 1 {1 user} other {# users} }", + "delete-users-text": "Be careful, after the confirmation all selected users will be removed and all related data will become unrecoverable.", + "activation-email-sent-message": "Activation email was successfully sent!", + "resend-activation": "Resend activation", + "email": "Email", + "email-required": "Email is required.", + "invalid-email-format": "Invalid email format.", + "first-name": "First Name", + "last-name": "Last Name", + "description": "Description", + "default-dashboard": "Default dashboard", + "always-fullscreen": "Always fullscreen", + "select-user": "Select user", + "no-users-matching": "No users matching '{{entity}}' were found.", + "user-required": "User is required", + "activation-method": "Activation method", + "display-activation-link": "Display activation link", + "send-activation-mail": "Send activation mail", + "activation-link": "User activation link", + "activation-link-text": "In order to activate user use the following activation link :", + "copy-activation-link": "Copy activation link", + "activation-link-copied-message": "User activation link has been copied to clipboard", + "details": "Details" + }, + "value": { + "type": "Value type", + "string": "String", + "string-value": "String value", + "integer": "Integer", + "integer-value": "Integer value", + "invalid-integer-value": "Invalid integer value", + "double": "Double", + "double-value": "Double value", + "boolean": "Boolean", + "boolean-value": "Boolean value", + "false": "False", + "true": "True", + "long": "Long" + }, + "widget": { + "widget-library": "Widgets Library", + "widget-bundle": "Widgets Bundle", + "select-widgets-bundle": "Select widgets bundle", + "management": "Widget management", + "editor": "Widget Editor", + "widget-type-not-found": "Problem loading widget configuration.
Probably associated\n widget type was removed.", + "widget-type-load-error": "Widget wasn't loaded due to the following errors:", + "remove": "Remove widget", + "edit": "Edit widget", + "remove-widget-title": "Are you sure you want to remove the widget '{{widgetTitle}}'?", + "remove-widget-text": "After the confirmation the widget and all related data will become unrecoverable.", + "timeseries": "Time series", + "search-data": "Search data", + "no-data-found": "No data found", + "latest-values": "Latest values", + "rpc": "Control widget", + "alarm": "Alarm widget", + "static": "Static widget", + "select-widget-type": "Select widget type", + "missing-widget-title-error": "Widget title must be specified!", + "widget-saved": "Widget saved", + "unable-to-save-widget-error": "Unable to save widget! Widget has errors!", + "save": "Save widget", + "saveAs": "Save widget as", + "save-widget-type-as": "Save widget type as", + "save-widget-type-as-text": "Please enter new widget title and/or select target widgets bundle", + "toggle-fullscreen": "Toggle fullscreen", + "run": "Run widget", + "title": "Widget title", + "title-required": "Widget title is required.", + "type": "Widget type", + "resources": "Resources", + "resource-url": "JavaScript/CSS URL", + "remove-resource": "Remove resource", + "add-resource": "Add resource", + "html": "HTML", + "tidy": "Tidy", + "css": "CSS", + "settings-schema": "Settings schema", + "datakey-settings-schema": "Data key settings schema", + "javascript": "Javascript", + "remove-widget-type-title": "Are you sure you want to remove the widget type '{{widgetName}}'?", + "remove-widget-type-text": "After the confirmation the widget type and all related data will become unrecoverable.", + "remove-widget-type": "Remove widget type", + "add-widget-type": "Add new widget type", + "widget-type-load-failed-error": "Failed to load widget type!", + "widget-template-load-failed-error": "Failed to load widget template!", + "add": "Add Widget", + "undo": "Undo widget changes", + "export": "Export widget" + }, + "widget-action": { + "header-button": "Widget header button", + "open-dashboard-state": "Navigate to new dashboard state", + "update-dashboard-state": "Update current dashboard state", + "open-dashboard": "Navigate to other dashboard", + "custom": "Custom action", + "target-dashboard-state": "Target dashboard state", + "target-dashboard-state-required": "Target dashboard state is required", + "set-entity-from-widget": "Set entity from widget", + "target-dashboard": "Target dashboard", + "open-right-layout": "Open right dashboard layout (mobile view)" + }, + "widgets-bundle": { + "current": "Current bundle", + "widgets-bundles": "Widgets Bundles", + "add": "Add Widgets Bundle", + "delete": "Delete widgets bundle", + "title": "Title", + "title-required": "Title is required.", + "add-widgets-bundle-text": "Add new widgets bundle", + "no-widgets-bundles-text": "No widgets bundles found", + "empty": "Widgets bundle is empty", + "details": "Details", + "widgets-bundle-details": "Widgets bundle details", + "delete-widgets-bundle-title": "Are you sure you want to delete the widgets bundle '{{widgetsBundleTitle}}'?", + "delete-widgets-bundle-text": "Be careful, after the confirmation the widgets bundle and all related data will become unrecoverable.", + "delete-widgets-bundles-title": "Are you sure you want to delete { count, plural, 1 {1 widgets bundle} other {# widgets bundles} }?", + "delete-widgets-bundles-action-title": "Delete { count, plural, 1 {1 widgets bundle} other {# widgets bundles} }", + "delete-widgets-bundles-text": "Be careful, after the confirmation all selected widgets bundles will be removed and all related data will become unrecoverable.", + "no-widgets-bundles-matching": "No widgets bundles matching '{{widgetsBundle}}' were found.", + "widgets-bundle-required": "Widgets bundle is required.", + "system": "System", + "import": "Import widgets bundle", + "export": "Export widgets bundle", + "export-failed-error": "Unable to export widgets bundle: {{error}}", + "create-new-widgets-bundle": "Create new widgets bundle", + "widgets-bundle-file": "Widgets bundle file", + "invalid-widgets-bundle-file-error": "Unable to import widgets bundle: Invalid widgets bundle data structure." + }, + "widget-config": { + "data": "Data", + "settings": "Settings", + "advanced": "Advanced", + "title": "Title", + "general-settings": "General settings", + "display-title": "Display title", + "drop-shadow": "Drop shadow", + "enable-fullscreen": "Enable fullscreen", + "background-color": "Background color", + "text-color": "Text color", + "padding": "Padding", + "margin": "Margin", + "widget-style": "Widget style", + "title-style": "Title style", + "mobile-mode-settings": "Mobile mode settings", + "order": "Order", + "height": "Height", + "units": "Special symbol to show next to value", + "decimals": "Number of digits after floating point", + "timewindow": "Timewindow", + "use-dashboard-timewindow": "Use dashboard timewindow", + "display-legend": "Display legend", + "datasources": "Datasources", + "maximum-datasources": "Maximum { count, plural, 1 {1 datasource is allowed.} other {# datasources are allowed} }", + "datasource-type": "Type", + "datasource-parameters": "Parameters", + "remove-datasource": "Remove datasource", + "add-datasource": "Add datasource", + "target-device": "Target device", + "alarm-source": "Alarm source", + "actions": "Actions", + "action": "Action", + "add-action": "Add action", + "search-actions": "Search actions", + "action-source": "Action source", + "action-source-required": "Action source is required.", + "action-name": "Name", + "action-name-required": "Action name is required.", + "action-name-not-unique": "Another action with the same name already exists.
Action name should be unique within the same action source.", + "action-icon": "Icon", + "action-type": "Type", + "action-type-required": "Action type is required.", + "edit-action": "Edit action", + "delete-action": "Delete action", + "delete-action-title": "Delete widget action", + "delete-action-text": "Are you sure you want delete widget action with name '{{actionName}}'?" + }, + "widget-type": { + "import": "Import widget type", + "export": "Export widget type", + "export-failed-error": "Unable to export widget type: {{error}}", + "create-new-widget-type": "Create new widget type", + "widget-type-file": "Widget type file", + "invalid-widget-type-file-error": "Unable to import widget type: Invalid widget type data structure." + }, + "icon": { + "icon": "Icon", + "select-icon": "Select icon", + "material-icons": "Material icons", + "show-all": "Show all icons" + }, + "custom": { + "widget-action": { + "action-cell-button": "Action cell button", + "row-click": "On row click", + "marker-click": "On marker click", + "tooltip-tag-action": "Tooltip tag action" + } + }, + "language": { + "language": "Language", + "locales": { + "zh_CN": "Chinese", + "en_US": "English", + "it_IT": "Italian", + "ko_KR": "Korean", + "ru_RU": "Russian", + "es_ES": "Spanish" + } + } +} diff --git a/ui/src/app/locale/locale.constant-es.js b/ui/src/app/locale/locale.constant-es.js deleted file mode 100644 index c6d2f96cbc..0000000000 --- a/ui/src/app/locale/locale.constant-es.js +++ /dev/null @@ -1,1333 +0,0 @@ -/* - * Copyright © 2016-2018 The Thingsboard Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -export default function addLocaleSpanish(locales) { - var es_ES = { - "access": { - "unauthorized": "No autorizado", - "unauthorized-access": "Acceso no autorizado", - "unauthorized-access-text": "Debes iniciar sesión para tener acceso a este recurso!", - "access-forbidden": "Acceso Prohibido", - "access-forbidden-text": "No tienes derechos para acceder a esta ubicación!
Intenta iniciar sesión con otro usuario si todavía quieres acceder a esta ubicación.", - "refresh-token-expired": "La sesión ha expirado", - "refresh-token-failed": "No se puede actualizar la sesión" - }, - "action": { - "activate": "Activar", - "suspend": "Suspender", - "save": "Guardar", - "saveAs": "Guardar como", - "cancel": "Cancelar", - "ok": "OK", - "delete": "Borrar", - "add": "Agregar", - "yes": "Si", - "no": "No", - "update": "Actualizar", - "remove": "Eliminar", - "search": "Buscar", - "assign": "Asignar", - "unassign": "Cancelar asignación", - "share": "Compartir", - "make-private": "Hacer privado", - "apply": "Aplicar", - "apply-changes": "Aplicar cambios", - "edit-mode": "Modo Edición", - "enter-edit-mode": "Modo Edición", - "decline-changes": "Descartar cambios", - "close": "Cerrar", - "back": "Atrás", - "run": "Correr", - "sign-in": "Regístrate!", - "edit": "Editar", - "view": "Ver", - "create": "Crear", - "drag": "Arrastrar", - "refresh": "Refrescar", - "undo": "Deshacer", - "copy": "Copiar", - "paste": "Pegar", - "import": "Importar", - "export": "Exportar", - "share-via": "Compartir vía {{provider}}" - }, - "aggregation": { - "aggregation": "Agregación", - "function": "Función de Agregación", - "limit": "Valores Max", - "group-interval": "Intervalo de agrupación", - "min": "Min", - "max": "Max", - "avg": "Promedio", - "sum": "Suma", - "count": "Cuenta", - "none": "Ninguno" - }, - "admin": { - "general": "General", - "general-settings": "Ajustes General", - "outgoing-mail": "Mail de Salida", - "outgoing-mail-settings": "Ajustes del Mail de Salida", - "system-settings": "Sistema", - "test-mail-sent": "Mail de prueba enviado correctamente!", - "base-url": "URL Base", - "base-url-required": "URL Base requerida.", - "mail-from": "Mail Desde", - "mail-from-required": "Mail Desde requerido.", - "smtp-protocol": "Protocolo SMTP", - "smtp-host": "Host SMTP", - "smtp-host-required": "Host SMTP requerido.", - "smtp-port": "Puerto SMTP", - "smtp-port-required": "Debe ingresar un Puerto SMTP.", - "smtp-port-invalid": "No parece un Puerto SMTP valido.", - "timeout-msec": "Timeout (ms)", - "timeout-required": "Timeout requerido.", - "timeout-invalid": "No parece un Timeout valido.", - "enable-tls": "Habilitar TLS", - "send-test-mail": "Enviar mail de prueba" - }, - "alarm": { // TODO - "alarm": "Alarm", - "alarms": "Alarms", - "select-alarm": "Select alarm", - "no-alarms-matching": "No alarms matching '{{entity}}' were found.", - "alarm-required": "Alarm is required", - "alarm-status": "Alarm status", - "search-status": { - "ANY": "Any", - "ACTIVE": "Active", - "CLEARED": "Cleared", - "ACK": "Acknowledged", - "UNACK": "Unacknowledged" - }, - "display-status": { - "ACTIVE_UNACK": "Active Unacknowledged", - "ACTIVE_ACK": "Active Acknowledged", - "CLEARED_UNACK": "Cleared Unacknowledged", - "CLEARED_ACK": "Cleared Acknowledged" - }, - "no-alarms-prompt": "No alarms found", - "created-time": "Created time", - "type": "Type", - "severity": "Severity", - "originator": "Originator", - "originator-type": "Originator type", - "details": "Details", - "status": "Status", - "alarm-details": "Alarm details", - "start-time": "Start time", - "end-time": "End time", - "ack-time": "Acknowledged time", - "clear-time": "Cleared time", - "severity-critical": "Critical", - "severity-major": "Major", - "severity-minor": "Minor", - "severity-warning": "Warning", - "severity-indeterminate": "Indeterminate", - "acknowledge": "Acknowledge", - "clear": "Clear", - "search": "Search alarms", - "selected-alarms": "{ count, select, 1 {1 alarm} other {# alarms} } selected", - "no-data": "No data to display", - "polling-interval": "Alarms polling interval (sec)", - "polling-interval-required": "Alarms polling interval is required.", - "min-polling-interval-message": "At least 1 sec polling interval is allowed.", - "aknowledge-alarms-title": "Acknowledge { count, select, 1 {1 alarm} other {# alarms} }", - "aknowledge-alarms-text": "Are you sure you want to acknowledge { count, select, 1 {1 alarm} other {# alarms} }?", - "clear-alarms-title": "Clear { count, select, 1 {1 alarm} other {# alarms} }", - "clear-alarms-text": "Are you sure you want to clear { count, select, 1 {1 alarm} other {# alarms} }?" - }, - "alias": { // TODO - "add": "Add alias", - "edit": "Edit alias", - "name": "Alias name", - "name-required": "Alias name is required", - "duplicate-alias": "Alias with same name is already exists.", - "filter-type-single-entity": "Single entity", - "filter-type-entity-list": "Entity list", - "filter-type-entity-name": "Entity name", - "filter-type-state-entity": "Entity from dashboard state", - "filter-type-state-entity-description": "Entity taken from dashboard state parameters", - "filter-type-asset-type": "Asset type", - "filter-type-asset-type-description": "Assets of type '{{assetType}}'", - "filter-type-asset-type-and-name-description": "Assets of type '{{assetType}}' and with name starting with '{{prefix}}'", - "filter-type-device-type": "Device type", - "filter-type-device-type-description": "Devices of type '{{deviceType}}'", - "filter-type-device-type-and-name-description": "Devices of type '{{deviceType}}' and with name starting with '{{prefix}}'", - "filter-type-relations-query": "Relations query", - "filter-type-relations-query-description": "{{entities}} that have {{relationType}} relation {{direction}} {{rootEntity}}", - "filter-type-asset-search-query": "Asset search query", - "filter-type-asset-search-query-description": "Assets with types {{assetTypes}} that have {{relationType}} relation {{direction}} {{rootEntity}}", - "filter-type-device-search-query": "Device search query", - "filter-type-device-search-query-description": "Devices with types {{deviceTypes}} that have {{relationType}} relation {{direction}} {{rootEntity}}", - "entity-filter": "Entity filter", - "resolve-multiple": "Resolve as multiple entities", - "filter-type": "Filter type", - "filter-type-required": "Filter type is required.", - "entity-filter-no-entity-matched": "No entities matching specified filter were found.", - "no-entity-filter-specified": "No entity filter specified", - "root-state-entity": "Use dashboard state entity as root", - "root-entity": "Root entity", - "state-entity-parameter-name": "State entity parameter name", - "default-state-entity": "Default state entity", - "default-entity-parameter-name": "By default", - "max-relation-level": "Max relation level", - "unlimited-level": "Unlimited level", - "state-entity": "Dashboard state entity", - "all-entities": "All entities", - "any-relation": "any" - }, - "asset": { // TODO - "asset": "Asset", - "assets": "Assets", - "management": "Asset management", - "view-assets": "View Assets", - "add": "Add Asset", - "assign-to-customer": "Assign to customer", - "assign-asset-to-customer": "Assign Asset(s) To Customer", - "assign-asset-to-customer-text": "Please select the assets to assign to the customer", - "no-assets-text": "No assets found", - "assign-to-customer-text": "Please select the customer to assign the asset(s)", - "public": "Public", - "assignedToCustomer": "Assigned to customer", - "make-public": "Make asset public", - "make-private": "Make asset private", - "unassign-from-customer": "Unassign from customer", - "delete": "Delete asset", - "asset-public": "Asset is public", - "asset-type": "Asset type", - "asset-type-required": "Asset type is required.", - "select-asset-type": "Select asset type", - "enter-asset-type": "Enter asset type", - "any-asset": "Any asset", - "no-asset-types-matching": "No asset types matching '{{entitySubtype}}' were found.", - "asset-type-list-empty": "No asset types selected.", - "asset-types": "Asset types", - "name": "Name", - "name-required": "Name is required.", - "description": "Description", - "type": "Type", - "type-required": "Type is required.", - "details": "Details", - "events": "Events", - "add-asset-text": "Add new asset", - "asset-details": "Asset details", - "assign-assets": "Assign assets", - "assign-assets-text": "Assign { count, select, 1 {1 asset} other {# assets} } to customer", - "delete-assets": "Delete assets", - "unassign-assets": "Unassign assets", - "unassign-assets-action-title": "Unassign { count, select, 1 {1 asset} other {# assets} } from customer", - "assign-new-asset": "Assign new asset", - "delete-asset-title": "Are you sure you want to delete the asset '{{assetName}}'?", - "delete-asset-text": "Be careful, after the confirmation the asset and all related data will become unrecoverable.", - "delete-assets-title": "Are you sure you want to delete { count, select, 1 {1 asset} other {# assets} }?", - "delete-assets-action-title": "Delete { count, select, 1 {1 asset} other {# assets} }", - "delete-assets-text": "Be careful, after the confirmation all selected assets will be removed and all related data will become unrecoverable.", - "make-public-asset-title": "Are you sure you want to make the asset '{{assetName}}' public?", - "make-public-asset-text": "After the confirmation the asset and all its data will be made public and accessible by others.", - "make-private-asset-title": "Are you sure you want to make the asset '{{assetName}}' private?", - "make-private-asset-text": "After the confirmation the asset and all its data will be made private and won't be accessible by others.", - "unassign-asset-title": "Are you sure you want to unassign the asset '{{assetName}}'?", - "unassign-asset-text": "After the confirmation the asset will be unassigned and won't be accessible by the customer.", - "unassign-asset": "Unassign asset", - "unassign-assets-title": "Are you sure you want to unassign { count, select, 1 {1 asset} other {# assets} }?", - "unassign-assets-text": "After the confirmation all selected assets will be unassigned and won't be accessible by the customer.", - "copyId": "Copy asset Id", - "idCopiedMessage": "Asset Id has been copied to clipboard", - "select-asset": "Select asset", - "no-assets-matching": "No assets matching '{{entity}}' were found.", - "asset-required": "Asset is required", - "name-starts-with": "Asset name starts with" - }, - "attribute": { - "attributes": "Atributos", - "latest-telemetry": "Última telemetría", - "attributes-scope": "Alcance de los atributos del dispositivo", - "scope-latest-telemetry": "Última telemetría", - "scope-client": "Atributos del Cliente", - "scope-server": "Atributos del Servidor", - "scope-shared": "Atributos Compartidos", - "add": "Agregar atributo", - "key": "Clave", - "key-required": "Clave del atributo requerida.", - "value": "Valor", - "value-required": "Valor del atributo requerido.", - "delete-attributes-title": "¿Estás seguro que quieres eliminar { count, select, 1 {1 atributo} other {# atributos} }?", - "delete-attributes-text": "Ten cuidado, luego de confirmar el atributo será eliminado, y la información relacionada será irrecuperable.", - "delete-attributes": "Borrar atributo", - "enter-attribute-value": "Ingresar valor del atributo", - "show-on-widget": "Mostrar en Widget", - "widget-mode": "Widget", - "next-widget": "Widget siguiente", - "prev-widget": "Widget anterior", - "add-to-dashboard": "Agregar al Panel", - "add-widget-to-dashboard": "Agregar widget al Panel", - "selected-attributes": "{ count, select, 1 {1 atributo} other {# atributos} } seleccionados", - "selected-telemetry": "{ count, select, 1 {1 unidad de telemetría } other {# unidades de telemetría} } seleccionadas." - }, - "audit-log": { // TODO - "audit": "Audit", - "audit-logs": "Audit Logs", - "timestamp": "Timestamp", - "entity-type": "Entity Type", - "entity-name": "Entity Name", - "user": "User", - "type": "Type", - "status": "Status", - "details": "Details", - "type-added": "Added", - "type-deleted": "Deleted", - "type-updated": "Updated", - "type-attributes-updated": "Attributes updated", - "type-attributes-deleted": "Attributes deleted", - "type-rpc-call": "RPC call", - "type-credentials-updated": "Credentials updated", - "type-assigned-to-customer": "Assigned to Customer", - "type-unassigned-from-customer": "Unassigned from Customer", - "type-activated": "Activated", - "type-suspended": "Suspended", - "type-credentials-read": "Credentials read", - "type-attributes-read": "Attributes read", - "status-success": "Success", - "status-failure": "Failure", - "audit-log-details": "Audit log details", - "no-audit-logs-prompt": "No logs found", - "action-data": "Action data", - "failure-details": "Failure details", - "search": "Search audit logs", - "clear-search": "Clear search" - }, - "confirm-on-exit": { - "message": "Tienes cambios sin guardar. ¿Estás seguro que quieres abandonar la página?", - "html-message": "Tienes cambios sin guardar.
¿Estás seguro que quieres abandonar la página?", - "title": "Cambios sin guardar" - }, - "contact": { - "country": "País", - "city": "Ciudad", - "state": "Estado/Provincia", - "postal-code": "Código Postal", - "postal-code-invalid": "Solo se permiten dígitos.", - "address": "Dirección", - "address2": "Dirección 2", - "phone": "Teléfono", - "email": "Email", - "no-address": "Sin Dirección" - }, - "common": { - "username": "Usuario", - "password": "Contraseña", - "enter-username": "Ingresa el nombre de usuario.", - "enter-password": "Ingresa la contraseña", - "enter-search": "Ingresa búsqueda" - }, - "content-type": { // TODO - "json": "Json", - "text": "Text", - "binary": "Binary (Base64)" - }, - "customer": { - "customers": "Clientes", - "management": "Gestión de Clientes", - "dashboard": "Panel del Cliente", - "dashboards": "Paneles del Cliente", - "devices": "Panel del Cliente", - "public-dashboards": "Paneles Públicos", - "public-devices": "Dispositivos Públicos", - "add": "Agregar cliente", - "delete": "Borrar cliente", - "manage-customer-users": "Gestionar usuarios del cliente", - "manage-customer-devices": "Gestionar dispositivos del cliente", - "manage-customer-dashboards": "Gestionar paneles del cliente", - "manage-public-devices": "Gestionar dispositivos públicos", - "manage-public-dashboards": "Gestionar paneles públicos", - "add-customer-text": "Agregar nuevo cliente", - "no-customers-text": "No se encontrar clientes", - "customer-details": "Detalles del cliente", - "delete-customer-title": "¿Estás seguro que quieres eliminar el cliente '{{customerTitle}}'?", - "delete-customer-text": "Ten cuidado, luego de confirmar el cliente será eliminado y toda la información relacionada será irrecuperable.", - "delete-customers-title": "¿Estás seguro que quieres eliminar { count, select, 1 {1 cliente} other {# clientes} }?", - "delete-customers-action-title": "Borrar { count, select, 1 {1 cliente} other {# clientes} }", - "delete-customers-text": "Ten cuidado, luego de confirmar todos los clientes seleccionados serán eliminados y su información relacionada será irrecuperable.", - "manage-users": "Gestionar usuarios", - "manage-devices": "Gestionar dispositivos", - "manage-dashboards": "Gestionar paneles", - "title": "Título", - "title-required": "Título requerido.", - "description": "Descripción" - }, - "datetime": { - "date-from": "Fecha desde", - "time-from": "Tiempo desde", - "date-to": "Fecha hasta", - "time-to": "Tiempo hasta" - }, - "dashboard": { - "dashboard": "Panel", - "dashboards": "Paneles", - "management": "Gestión de Paneles", - "view-dashboards": "Ver paneles", - "add": "Agregar Panel", - "assign-dashboard-to-customer": "Asignar panel(es) a cliente", - "assign-dashboard-to-customer-text": "Por favor, seleccione algún panel para asignar al Cliente.", - "assign-to-customer-text": "Por favor, seleccione algún cliente para asignar al(los) panel(es).", - "assign-to-customer": "Asignar a cliente", - "unassign-from-customer": "Desasignar del cliente", - "make-public": "Hacer panel público", - "make-private": "Hacer panel privado", - "no-dashboards-text": "Ningún panel encontrado", - "no-widgets": "Ningún widget configurado", - "add-widget": "Agregar nuevo widget", - "title": "Titulo", - "select-widget-title": "Seleccionar widget", - "select-widget-subtitle": "Lista de tipos de widgets", - "delete": "Eliminar panel", - "title-required": "Título requerido.", - "description": "Descripción", - "details": "Detalles", - "dashboard-details": "Detalles del panel", - "add-dashboard-text": "Agregar nuevo panel", - "assign-dashboards": "Asignar paneles", - "assign-new-dashboard": "Asignar nuevo panel", - "assign-dashboards-text": "Asignar { count, select, 1 {1 panel} other {# paneles} } al cliente", - "delete-dashboards": "Eliminar paneles", - "unassign-dashboards": "Desasignar paneles", - "unassign-dashboards-action-title": "Desasignar { count, select, 1 {1 paneles} other {# paneles} } del cliente", - "delete-dashboard-title": "¿Estás seguro que quieres eliminar el panel '{{dashboardTitle}}'?", - "delete-dashboard-text": "Ten cuidado, el panel seleccionado será eliminado y la información relacionada sera irrecuperable.", - "delete-dashboards-title": "¿Estás seguro que quieres eliminar { count, select, 1 {1 panel} other {# paneles} }?", - "delete-dashboards-action-title": "Eliminar { count, select, 1 {1 panel} other {# paneles} }", - "delete-dashboards-text": "Ten cuidado, los paneles seleccionados serán eliminados y la información relacionada será irrecuperable.", - "unassign-dashboard-title": "¿Estás seguro que quieres desasignar el panel '{{dashboardTitle}}'?", - "unassign-dashboard-text": "Luego de confirmar, el panel será desasignado y no podrá ser accesible por el cliente.", - "unassign-dashboard": "Desasignar panel", - "unassign-dashboards-title": "¿Estás seguro que quieres desasignar { count, select, 1 {1 panel} other {# paneles} }?", - "unassign-dashboards-text": "Luego de confirmar, los paneles seleccionados serán desasignados y no podrán ser accesibles por el cliente.", - "public-dashboard-title": "El panel ahora es público", - "public-dashboard-text": "Tu panel {{dashboardTitle}} es ahora público y podrá ser accedido desde: aquí:", - "public-dashboard-notice": "Nota: No olvides hacer públicos los dispositivos relacionados para acceder a sus datos.", - "make-private-dashboard-title": "¿Estás seguro que quieres hacer el panel '{{dashboardTitle}}' privado?", - "make-private-dashboard-text": "Luego de confirmar, el panel será privado y no podrá ser accesible por otros.", - "make-private-dashboard": "Hacer panel privado", - "socialshare-text": "'{{dashboardTitle}}' powered by ThingsBoard", - "socialshare-title": "'{{dashboardTitle}}' powered by ThingsBoard", - "select-dashboard": "Seleccionar panel", - "no-dashboards-matching": "Panel '{{entity}}' no encontrado.", - "dashboard-required": "Panel requerido.", - "select-existing": "Seleccionar paneles existentes", - "create-new": "Crear nuevo panel", - "new-dashboard-title": "Nuevo título", - "open-dashboard": "Abrir panel", - "set-background": "Definir fondo", - "background-color": "Color de fondo", - "background-image": "Imagen de fondo", - "background-size-mode": "Modo tamaño de fondo", - "no-image": "No se ha seleccionado ningúna imagen", - "drop-image": "Suelte una imagen o haga clic para seleccionar un archivo para cargar.", - "settings": "Ajustes", - "columns-count": "Número de columnas", - "columns-count-required": "Número de columnas requerido.", - "min-columns-count-message": "Solo se permite un número mínimo de 10 columnas.", - "max-columns-count-message": "Solo se permite un número máximo de 1000 columnas.", - "widgets-margins": "Margen entre widgets", - "horizontal-margin": "Margen horizontal", - "horizontal-margin-required": "Margen horizontal requerido.", - "min-horizontal-margin-message": "Solo se permite margen horizontal mínimo de 0.", - "max-horizontal-margin-message": "Solo se permite margen horizontal máximo de 50.", - "vertical-margin": "Margen vertical", - "vertical-margin-required": "Margen vertical requerido.", - "min-vertical-margin-message": "Solo se permite margen vertical mínimo de 0.", - "max-vertical-margin-message": "Solo se permite margen vertical máximo de 50.", - "display-title": "Mostrar título del panel", - "title-color": "Color del título", - "display-device-selection": "Mostrar selección de dispositivo", - "display-dashboard-timewindow": "Mostrar ventana de tiempo", - "display-dashboard-export": "Mostrar exportar", - "import": "Importar panel", - "export": "Exportar panel", - "export-failed-error": "Imposible exportar panel: {{error}}", - "create-new-dashboard": "Crear nuevo panel", - "dashboard-file": "Archivo del panel", - "invalid-dashboard-file-error": "Imposible importar panel: Estructura de datos inválida.", - "dashboard-import-missing-aliases-title": "Configurar alias utilizados por el panel importado", - "create-new-widget": "Crear nuevo widget", - "import-widget": "Importar widget", - "widget-file": "Archivo de widget", - "invalid-widget-file-error": "Imposible importar widget: Estructura de datos inválida.", - "widget-import-missing-aliases-title": "Configurar alias utilizados por el widget", - "open-toolbar": "Abrir toolbar del panel", - "close-toolbar": "Cerrar toolbar", - "configuration-error": "Error de configuración", - "alias-resolution-error-title": "Error de configuración de alias del panel", - "invalid-aliases-config": "No se puede encontrar ningún dispositivo que coincida con algunos de los alias de filtro.
" + - "Póngase en contacto con su administrador para resolver este problema.", - "select-devices": "Seleccionar dispositivos", - "assignedToCustomer": "Asignado al cliente", - "public": "Público", - "public-link": "Link público", - "copy-public-link": "Copiar link público", - "public-link-copied-message": "El link público del panel se ha copiado al portapapeles" - }, - "datakey": { - "settings": "Ajustes", - "advanced": "Avanzado", - "label": "Etiqueta", - "color": "Color", - "data-generation-func": "Función de generación de datos", - "use-data-post-processing-func": "Usar funcíon de post-procesamiendo de datos", - "configuration": "Ajustes de clave de datos", - "timeseries": "Serie de tiempos", - "attributes": "Atributos", - "timeseries-required": "Series de tiempo del dispositivo requerido.", - "timeseries-or-attributes-required": "Series de tiempo/Atributos requeridos.", - "function-types": "Tipos de funciones", - "function-types-required": "Tipos de funciones requerido." - }, - "datasource": { - "type": "Típo de fuente de datos", - "add-datasource-prompt": "Por favor, agrega una fuente de datos" - }, - "details": { - "edit-mode": "Modo Edición", - "toggle-edit-mode": "Ir a Modo Edición" - }, - "device": { - "device": "Dispositivo", - "device-required": "Dispositivo requerido.", - "devices": "Dispositivos", - "management": "Gestión de Dispositivos", - "view-devices": "Ver dispositivos", - "device-alias": "Alias de dispositivo", - "aliases": "Alias de dispositivos", - "no-alias-matching": "'{{alias}}' no encontrado.", - "no-aliases-found": "Ningún alias encontrado.", - "no-key-matching": "'{{key}}' no encontrado.", - "no-keys-found": "Ninguna clave encontrada.", - "create-new-alias": "Crear nuevo alias!", - "create-new-key": "Crear nueva clave!", - "duplicate-alias-error": "Alias duplicado '{{alias}}'.
El alias de los dispositivos deben ser únicos dentro del panel.", - "configure-alias": "Configurar alias '{{alias}}'", - "no-devices-matching": "No se encontró dispositivo '{{entity}}'", - "alias": "Alias", - "alias-required": "Alias de dispositivo requerido.", - "remove-alias": "Eliminar alias", - "add-alias": "Agregar alias", - "name-starts-with": "Nombre empieza con", - "device-list": "Lista de dispositivos", - "use-device-name-filter": "Usar filtro", - "device-list-empty": "Ningún dispositivo seleccionado.", - "device-name-filter-required": "Nombre de filtro requerido.", - "device-name-filter-no-device-matched": "Ningún dispositivo encontrado que comience con '{{device}}'.", - "add": "Agregar dispositivo", - "assign-to-customer": "Asignar a cliente", - "assign-device-to-customer": "Asignar dispositivo(s) a Cliente", - "assign-device-to-customer-text": "Por favor, seleccione los dispositivos que serán asignados al cliente", - "make-public": "Hacer dispositivo público", - "make-private": "Hacer dispositivo privado", - "no-devices-text": "Ningún dispositivo encontrado", - "assign-to-customer-text": "Por favor, seleccione el cliente para asignar el(los) dispositivo(s)", - "device-details": "Detalles del dispositivo", - "add-device-text": "Agregar nuevo dispositivo", - "credentials": "Credenciales", - "manage-credentials": "Gestionar credenciales", - "delete": "Eliminar dispositivo", - "assign-devices": "Asignar dispositivo", - "assign-devices-text": "Asignar { count, select, 1 {1 dispositivo} other {# dispositivos} } al cliente", - "delete-devices": "Eliminar dispositivo", - "unassign-from-customer": "Desasignar del cliente", - "unassign-devices": "Desasignar dispositivos", - "unassign-devices-action-title": "Desasignar { count, select, 1 {1 dispositivo} other {# dispositivos} } del cliente", - "assign-new-device": "Asignar nuevo dispositivo", - "make-public-device-title": "¿Estás seguro que quieres hacer el dispositivo '{{deviceName}}' público?", - "make-public-device-text": "Luego de confirmar, el dispositivo y la información relacionada serán públicos y podrá ser accesible por otros.", - "make-private-device-title": "¿Estás seguro que quieres hacer el dispositivo '{{deviceName}}' privado?", - "make-private-device-text": "Luego de confirmar, el dispositivo y la información relacionada serán privados y no podrá ser accesible por otros.", - "view-credentials": "Ver credenciales", - "delete-device-title": "¿Estás seguro que quieres eliminar el dispositivo '{{deviceName}}'?", - "delete-device-text": "Ten cuidado, luego de confirmar los dispositivos serán eliminados y la información relacionada será irrecuperable.", - "delete-devices-title": "¿Estás seguro que quieres eliminar { count, select, 1 {1 dispositivo} other {# dispositivos} }?", - "delete-devices-action-title": "Eliminar { count, select, 1 {1 dispositivo} other {# dispositivos} }", - "delete-devices-text": "Ten cuidado, luego de confirmar los dispositivos seleccionados serán eliminados y la información relacionada será irrecuperable.", - "unassign-device-title": "¿Estás seguro que quieres desasignar el dispositivo '{{deviceName}}'?", - "unassign-device-text": "Luego de confirmar el dispositivo será desasignado y no podrá ser accesible por el cliente.", - "unassign-device": "Desasignar dispositivo", - "unassign-devices-title": "¿Estás seguro que quieres desasignar { count, select, 1 {1 dispositivo} other {# dispositivos} }?", - "unassign-devices-text": "Luego de confirmar los dispositivos seleccionados serán desasignados y no podrán ser accedidos por el cliente.", - "device-credentials": "Credenciales del dispositivo", - "credentials-type": "Tipo de credencial", - "access-token": "Access token", - "access-token-required": "Access token requerido.", - "access-token-invalid": "Access token debe tener entre 1 a 20 caracteres.", - "rsa-key": "Clave pública RSA", - "rsa-key-required": "Clave pública RSA requerida.", - "secret": "Secreta", - "secret-required": "Secreta requerida.", - "name": "Nombre", - "name-required": "Nombre requerido.", - "description": "Descripción", - "events": "Eventos", - "details": "Detalles", - "copyId": "Copiar ID", - "copyAccessToken": "Copiar access token", - "idCopiedMessage": "Id del dispositivo copiado al portapapeles", - "accessTokenCopiedMessage": "Access token del dispositivo copiado al portapapeles", - "assignedToCustomer": "Asignado al cliente", - "unable-delete-device-alias-title": "Imposible eliminar alias del dispositivo", - "unable-delete-device-alias-text": "Alias '{{deviceAlias}}' no puede ser eliminado. Esta siendo usado por el(los) widget(s):
{{widgetsList}}", - "is-gateway": "Es gateway", - "public": "Público", - "device-public": "Dispositivo público" - }, - "dialog": { - "close": "Cerrar cuadro de diálogo" - }, - "error": { - "unable-to-connect": "Imposible conectar con el servidor! Por favor, revise su conexión a internet.", - "unhandled-error-code": "Código de error no manejado: {{errorCode}}", - "unknown-error": "Error desconocido" - }, - "entity": { // TODO - "entity": "Entity", - "entities": "Entities", - "aliases": "Entity aliases", - "entity-alias": "Entity alias", - "unable-delete-entity-alias-title": "Unable to delete entity alias", - "unable-delete-entity-alias-text": "Entity alias '{{entityAlias}}' can't be deleted as it used by the following widget(s):
{{widgetsList}}", - "duplicate-alias-error": "Duplicate alias found '{{alias}}'.
Entity aliases must be unique whithin the dashboard.", - "missing-entity-filter-error": "Filter is missing for alias '{{alias}}'.", - "configure-alias": "Configure '{{alias}}' alias", - "alias": "Alias", - "alias-required": "Entity alias is required.", - "remove-alias": "Remove entity alias", - "add-alias": "Add entity alias", - "entity-list": "Entity list", - "entity-type": "Entity type", - "entity-types": "Entity types", - "entity-type-list": "Entity type list", - "any-entity": "Any entity", - "enter-entity-type": "Enter entity type", - "no-entities-matching": "No entities matching '{{entity}}' were found.", - "no-entity-types-matching": "No entity types matching '{{entityType}}' were found.", - "name-starts-with": "Name starts with", - "use-entity-name-filter": "Use filter", - "entity-list-empty": "No entities selected.", - "entity-type-list-empty": "No entity types selected.", - "entity-name-filter-required": "Entity name filter is required.", - "entity-name-filter-no-entity-matched": "No entities starting with '{{entity}}' were found.", - "all-subtypes": "All", - "select-entities": "Select entities", - "no-aliases-found": "No aliases found.", - "no-alias-matching": "'{{alias}}' not found.", - "create-new-alias": "Create a new one!", - "key": "Key", - "key-name": "Key name", - "no-keys-found": "No keys found.", - "no-key-matching": "'{{key}}' not found.", - "create-new-key": "Create a new one!", - "type": "Type", - "type-required": "Entity type is required.", - "type-device": "Device", - "type-devices": "Devices", - "list-of-devices": "{ count, select, 1 {One device} other {List of # devices} }", - "device-name-starts-with": "Devices whose names start with '{{prefix}}'", - "type-asset": "Asset", - "type-assets": "Assets", - "list-of-assets": "{ count, select, 1 {One asset} other {List of # assets} }", - "asset-name-starts-with": "Assets whose names start with '{{prefix}}'", - "type-rule": "Rule", - "type-rules": "Rules", - "list-of-rules": "{ count, select, 1 {One rule} other {List of # rules} }", - "rule-name-starts-with": "Rules whose names start with '{{prefix}}'", - "type-plugin": "Plugin", - "type-plugins": "Plugins", - "list-of-plugins": "{ count, select, 1 {One plugin} other {List of # plugins} }", - "plugin-name-starts-with": "Plugins whose names start with '{{prefix}}'", - "type-tenant": "Tenant", - "type-tenants": "Tenants", - "list-of-tenants": "{ count, select, 1 {One tenant} other {List of # tenants} }", - "tenant-name-starts-with": "Tenants whose names start with '{{prefix}}'", - "type-customer": "Customer", - "type-customers": "Customers", - "list-of-customers": "{ count, select, 1 {One customer} other {List of # customers} }", - "customer-name-starts-with": "Customers whose names start with '{{prefix}}'", - "type-user": "User", - "type-users": "Users", - "list-of-users": "{ count, select, 1 {One user} other {List of # users} }", - "user-name-starts-with": "Users whose names start with '{{prefix}}'", - "type-dashboard": "Dashboard", - "type-dashboards": "Dashboards", - "list-of-dashboards": "{ count, select, 1 {One dashboard} other {List of # dashboards} }", - "dashboard-name-starts-with": "Dashboards whose names start with '{{prefix}}'", - "type-alarm": "Alarm", - "type-alarms": "Alarms", - "list-of-alarms": "{ count, select, 1 {One alarms} other {List of # alarms} }", - "alarm-name-starts-with": "Alarms whose names start with '{{prefix}}'", - "type-rulechain": "Rule chain", - "type-rulechains": "Rule chains", - "list-of-rulechains": "{ count, select, 1 {One rule chain} other {List of # rule chains} }", - "rulechain-name-starts-with": "Rule chains whose names start with '{{prefix}}'", - "type-current-customer": "Current Customer", - "search": "Search entities", - "selected-entities": "{ count, select, 1 {1 entity} other {# entities} } selected", - "entity-name": "Entity name", - "details": "Entity details", - "no-entities-prompt": "No entities found", - "no-data": "No data to display" - }, - "event": { - "event-type": "Tipo de evento", - "type-error": "Error", - "type-lc-event": "Ciclo de vida", - "type-stats": "Estadísticas", - "no-events-prompt": "Ningún evento encontrado.", - "error": "Error", - "alarm": "Alarma", - "event-time": "Hora del evento", - "server": "Servidor", - "body": "Cuerpo", - "method": "Método", - "event": "Evento", - "status": "Status", - "success": "Éxito", - "failed": "Fallo", - "messages-processed": "Mensajes procesados", - "errors-occurred": "Ocurrieron errores" - }, - "extension": { // TODO - "extensions": "Extensions", - "selected-extensions": "{ count, select, 1 {1 extension} other {# extensions} } selected", - "type": "Type", - "key": "Key", - "value": "Value", - "id": "Id", - "extension-id": "Extension id", - "extension-type": "Extension type", - "transformer-json": "JSON *", - "unique-id-required": "Current extension id already exists.", - "delete": "Delete extension", - "add": "Add extension", - "edit": "Edit extension", - "delete-extension-title": "Are you sure you want to delete the extension '{{extensionId}}'?", - "delete-extension-text": "Be careful, after the confirmation the extension and all related data will become unrecoverable.", - "delete-extensions-title": "Are you sure you want to delete { count, select, 1 {1 extension} other {# extensions} }?", - "delete-extensions-text": "Be careful, after the confirmation all selected extensions will be removed.", - "converters": "Converters", - "converter-id": "Converter id", - "configuration": "Configuration", - "converter-configurations": "Converter configurations", - "token": "Security token", - "add-converter": "Add converter", - "add-config": "Add converter configuration", - "device-name-expression": "Device name expression", - "device-type-expression": "Device type expression", - "custom": "Custom", - "to-double": "To Double", - "transformer": "Transformer", - "json-required": "Transformer json is required.", - "json-parse": "Unable to parse transformer json.", - "attributes": "Attributes", - "add-attribute": "Add attribute", - "add-map": "Add mapping element", - "timeseries": "Timeseries", - "add-timeseries": "Add timeseries", - "field-required": "Field is required", - "brokers": "Brokers", - "add-broker": "Add broker", - "host": "Host", - "port": "Port", - "port-range": "Port should be in a range from 1 to 65535.", - "ssl": "Ssl", - "credentials": "Credentials", - "username": "Username", - "password": "Password", - "retry-interval": "Retry interval in milliseconds", - "anonymous": "Anonymous", - "basic": "Basic", - "pem": "PEM", - "ca-cert": "CA certificate file *", - "private-key": "Private key file *", - "cert": "Certificate file *", - "no-file": "No file selected.", - "drop-file": "Drop a file or click to select a file to upload.", - "mapping": "Mapping", - "topic-filter": "Topic filter", - "converter-type": "Converter type", - "converter-json": "Json", - "json-name-expression": "Device name json expression", - "topic-name-expression": "Device name topic expression", - "json-type-expression": "Device type json expression", - "topic-type-expression": "Device type topic expression", - "attribute-key-expression": "Attribute key expression", - "attr-json-key-expression": "Attribute key json expression", - "attr-topic-key-expression": "Attribute key topic expression", - "request-id-expression": "Request id expression", - "request-id-json-expression": "Request id json expression", - "request-id-topic-expression": "Request id topic expression", - "response-topic-expression": "Response topic expression", - "value-expression": "Value expression", - "topic": "Topic", - "timeout": "Timeout in milliseconds", - "converter-json-required": "Converter json is required.", - "converter-json-parse": "Unable to parse converter json.", - "filter-expression": "Filter expression", - "connect-requests": "Connect requests", - "add-connect-request": "Add connect request", - "disconnect-requests": "Disconnect requests", - "add-disconnect-request": "Add disconnect request", - "attribute-requests": "Attribute requests", - "add-attribute-request": "Add attribute request", - "attribute-updates": "Attribute updates", - "add-attribute-update": "Add attribute update", - "server-side-rpc": "Server side RPC", - "add-server-side-rpc-request": "Add server-side RPC request", - "device-name-filter": "Device name filter", - "attribute-filter": "Attribute filter", - "method-filter": "Method filter", - "request-topic-expression": "Request topic expression", - "response-timeout": "Response timeout in milliseconds", - "topic-expression": "Topic expression", - "client-scope": "Client scope", - "add-device": "Add device", - "opc-server": "Servers", - "opc-add-server": "Add server", - "opc-add-server-prompt": "Please add server", - "opc-application-name": "Application name", - "opc-application-uri": "Application uri", - "opc-scan-period-in-seconds": "Scan period in seconds", - "opc-security": "Security", - "opc-identity": "Identity", - "opc-keystore": "Keystore", - "opc-type": "Type", - "opc-keystore-type": "Type", - "opc-keystore-location": "Location *", - "opc-keystore-password": "Password", - "opc-keystore-alias": "Alias", - "opc-keystore-key-password": "Key password", - "opc-device-node-pattern": "Device node pattern", - "opc-device-name-pattern": "Device name pattern", - "modbus-server": "Servers/slaves", - "modbus-add-server": "Add server/slave", - "modbus-add-server-prompt": "Please add server/slave", - "modbus-transport": "Transport", - "modbus-port-name": "Serial port name", - "modbus-encoding": "Encoding", - "modbus-parity": "Parity", - "modbus-baudrate": "Baud rate", - "modbus-databits": "Data bits", - "modbus-stopbits": "Stop bits", - "modbus-databits-range": "Data bits should be in a range from 7 to 8.", - "modbus-stopbits-range": "Stop bits should be in a range from 1 to 2.", - "modbus-unit-id": "Unit ID", - "modbus-unit-id-range": "Unit ID should be in a range from 1 to 247.", - "modbus-device-name": "Device name", - "modbus-poll-period": "Poll period (ms)", - "modbus-attributes-poll-period": "Attributes poll period (ms)", - "modbus-timeseries-poll-period": "Timeseries poll period (ms)", - "modbus-poll-period-range": "Poll period should be positive value.", - "modbus-tag": "Tag", - "modbus-function": "Function", - "modbus-register-address": "Register address", - "modbus-register-address-range": "Register address should be in a range from 0 to 65535.", - "modbus-register-bit-index": "Bit index", - "modbus-register-bit-index-range": "Bit index should be in a range from 0 to 15.", - "modbus-register-count": "Register count", - "modbus-register-count-range": "Register count should be a positive value.", - "modbus-byte-order": "Byte order", - - "sync": { - "status": "Status", - "sync": "Sync", - "not-sync": "Not sync", - "last-sync-time": "Last sync time", - "not-available": "Not available" - }, - - "export-extensions-configuration": "Export extensions configuration", - "import-extensions-configuration": "Import extensions configuration", - "import-extensions": "Import extensions", - "import-extension": "Import extension", - "export-extension": "Export extension", - "file": "Extensions file", - "invalid-file-error": "Invalid extension file" - }, - "fullscreen": { - "expand": "Expandir a Pantalla Completa", - "exit": "Salir de Pantalla Completa", - "toggle": "Cambiar el modo de Pantalla Completa", - "fullscreen": "Pantalla Completa" - }, - "function": { - "function": "Función" - }, - "grid": { - "delete-item-title": "¿Estás seguro que quieres eliminar este item?", - "delete-item-text": "Ten cuidado, luego de confirmar el item será eliminado y la información relacionada será irrecuperable.", - "delete-items-title": "¿Estás seguro que quieres eliminar { count, select, 1 {1 item} other {# items} }?", - "delete-items-action-title": "Eliminar { count, select, 1 {1 item} other {# items} }", - "delete-items-text": "Ten cuidado, luego de confirmar los items seleccionados serán eliminados y la información relacionada será irrecuperable.", - "add-item-text": "Agregar nuevo item", - "no-items-text": "Ningún item encontrado", - "item-details": "Detalles del item", - "delete-item": "Borrar Item", - "delete-items": "Borrar Items", - "scroll-to-top": "Ir hacia arriba" - }, - "help": { - "goto-help-page": "Ir a Página de Ayuda" - }, - "home": { - "home": "Principal", - "profile": "Perfil", - "logout": "Salir", - "menu": "Menu", - "avatar": "Avatar", - "open-user-menu": "Abrir menú de usuario" - }, - "import": { - "no-file": "Ningún archivo seleccionado", - "drop-file": "Arrastra un archivo JSON o clickea para seleccionar uno." - }, - "item": { - "selected": "Seleccionado" - }, - "js-func": { - "no-return-error": "La función debe retornar un valor!", - "return-type-mismatch": "La función debe retornar un valor de tipo: '{{type}}'!" - }, - "key-val": { // TODO - "key": "Key", - "value": "Value", - "remove-entry": "Remove entry", - "add-entry": "Add entry", - "no-data": "No entries" - }, - "layout": { // TODO - "layout": "Layout", - "manage": "Manage layouts", - "settings": "Layout settings", - "color": "Color", - "main": "Main", - "right": "Right", - "select": "Select target layout" - }, - "legend": { - "position": "Posición de leyenda", - "show-max": "Mostrar máximo", - "show-min": "Mostrar mínimo", - "show-avg": "Mostrar promedio", - "show-total": "Mostrar total", - "settings": "Ajustes de leyenda.", - "min": "min", - "max": "max", - "avg": "prom", - "total": "total" - }, - "login": { - "login": "Ingresar", - "request-password-reset": "Pedir restablecer contraseña", - "reset-password": "Restablecer contraseña", - "create-password": "Crear contraseña", - "passwords-mismatch-error": "Las contraseñas deben ser las mismas!", - "password-again": "Reingresa la contraseña", - "sign-in": "Iniciar sesión", - "username": "Usuario (email)", - "remember-me": "Recordar", - "forgot-password": "¿Olvidaste tu contraseña?", - "password-reset": "Restablecer Contraseña", - "new-password": "Nueva contraseña", - "new-password-again": "Repita la nueva contraseña", - "password-link-sent-message": "Se ha enviado el enlace de restablecimiento de contraseña con éxito!", - "email": "Email" - }, - "position": { - "top": "Arriba", - "bottom": "Abajo", - "left": "Izquierda", - "right": "Derecha" - }, - "profile": { - "profile": "Perfil", - "change-password": "Cambiar contraseña", - "current-password": "Contraseña actual" - }, - "relation": { // TODO - "relations": "Relations", - "direction": "Direction", - "search-direction": { - "FROM": "From", - "TO": "To" - }, - "direction-type": { - "FROM": "from", - "TO": "to" - }, - "from-relations": "Outbound relations", - "to-relations": "Inbound relations", - "selected-relations": "{ count, select, 1 {1 relation} other {# relations} } selected", - "type": "Type", - "to-entity-type": "To entity type", - "to-entity-name": "To entity name", - "from-entity-type": "From entity type", - "from-entity-name": "From entity name", - "to-entity": "To entity", - "from-entity": "From entity", - "delete": "Delete relation", - "relation-type": "Relation type", - "relation-type-required": "Relation type is required.", - "any-relation-type": "Any type", - "add": "Add relation", - "edit": "Edit relation", - "delete-to-relation-title": "Are you sure you want to delete relation to the entity '{{entityName}}'?", - "delete-to-relation-text": "Be careful, after the confirmation the entity '{{entityName}}' will be unrelated from the current entity.", - "delete-to-relations-title": "Are you sure you want to delete { count, select, 1 {1 relation} other {# relations} }?", - "delete-to-relations-text": "Be careful, after the confirmation all selected relations will be removed and corresponding entities will be unrelated from the current entity.", - "delete-from-relation-title": "Are you sure you want to delete relation from the entity '{{entityName}}'?", - "delete-from-relation-text": "Be careful, after the confirmation current entity will be unrelated from the entity '{{entityName}}'.", - "delete-from-relations-title": "Are you sure you want to delete { count, select, 1 {1 relation} other {# relations} }?", - "delete-from-relations-text": "Be careful, after the confirmation all selected relations will be removed and current entity will be unrelated from the corresponding entities.", - "remove-relation-filter": "Remove relation filter", - "add-relation-filter": "Add relation filter", - "any-relation": "Any relation", - "relation-filters": "Relation filters", - "additional-info": "Additional info (JSON)", - "invalid-additional-info": "Unable to parse additional info json." - }, - "rulechain": { // TODO - "rulechain": "Rule chain", - "rulechains": "Rule chains", - "root": "Root", - "delete": "Delete rule chain", - "name": "Name", - "name-required": "Name is required.", - "description": "Description", - "add": "Add Rule Chain", - "set-root": "Make rule chain root", - "set-root-rulechain-title": "Are you sure you want to make the rule chain '{{ruleChainName}}' root?", - "set-root-rulechain-text": "After the confirmation the rule chain will become root and will handle all incoming transport messages.", - "delete-rulechain-title": "Are you sure you want to delete the rule chain '{{ruleChainName}}'?", - "delete-rulechain-text": "Be careful, after the confirmation the rule chain and all related data will become unrecoverable.", - "delete-rulechains-title": "Are you sure you want to delete { count, select, 1 {1 rule chain} other {# rule chains} }?", - "delete-rulechains-action-title": "Delete { count, select, 1 {1 rule chain} other {# rule chains} }", - "delete-rulechains-text": "Be careful, after the confirmation all selected rule chains will be removed and all related data will become unrecoverable.", - "add-rulechain-text": "Add new rule chain", - "no-rulechains-text": "No rule chains found", - "rulechain-details": "Rule chain details", - "details": "Details", - "events": "Events", - "system": "System", - "import": "Import rule chain", - "export": "Export rule chain", - "export-failed-error": "Unable to export rule chain: {{error}}", - "create-new-rulechain": "Create new rule chain", - "rulechain-file": "Rule chain file", - "invalid-rulechain-file-error": "Unable to import rule chain: Invalid rule chain data structure.", - "copyId": "Copy rule chain Id", - "idCopiedMessage": "Rule chain Id has been copied to clipboard", - "select-rulechain": "Select rule chain", - "no-rulechains-matching": "No rule chains matching '{{entity}}' were found.", - "rulechain-required": "Rule chain is required", - "management": "Rules management", - "debug-mode": "Debug mode" - }, - "rulenode": { // TODO - "details": "Details", - "events": "Events", - "search": "Search nodes", - "open-node-library": "Open node library", - "add": "Add rule node", - "name": "Name", - "name-required": "Name is required.", - "type": "Type", - "description": "Description", - "delete": "Delete rule node", - "select-all-objects": "Select all nodes and connections", - "deselect-all-objects": "Deselect all nodes and connections", - "delete-selected-objects": "Delete selected nodes and connections", - "delete-selected": "Delete selected", - "select-all": "Select all", - "copy-selected": "Copy selected", - "deselect-all": "Deselect all", - "rulenode-details": "Rule node details", - "debug-mode": "Debug mode", - "configuration": "Configuration", - "link": "Link", - "link-details": "Rule node link details", - "add-link": "Add link", - "link-label": "Link label", - "link-label-required": "Link label is required.", - "custom-link-label": "Custom link label", - "custom-link-label-required": "Custom link label is required.", - "type-filter": "Filter", - "type-filter-details": "Filter incoming messages with configured conditions", - "type-enrichment": "Enrichment", - "type-enrichment-details": "Add additional information into Message Metadata", - "type-transformation": "Transformation", - "type-transformation-details": "Change Message payload and Metadata", - "type-action": "Action", - "type-action-details": "Perform special action", - "type-external": "External", - "type-external-details": "Interacts with external system", - "type-rule-chain": "Rule Chain", - "type-rule-chain-details": "Forwards incoming messages to specified Rule Chain", - "type-input": "Input", - "type-input-details": "Logical input of Rule Chain, forwards incoming messages to next related Rule Node", - "directive-is-not-loaded": "Defined configuration directive '{{directiveName}}' is not available.", - "ui-resources-load-error": "Failed to load configuration ui resources.", - "invalid-target-rulechain": "Unable to resolve target rule chain!", - "test-script-function": "Test script function", - "message": "Message", - "message-type": "Message type", - "message-type-required": "Message type is required", - "metadata": "Metadata", - "metadata-required": "Metadata entries can't be empty.", - "output": "Output", - "test": "Test", - "help": "Help" - }, - "tenant": { - "tenants": "Tenants", - "management": "Gestión de Tenant", - "add": "Agregar Tenant", - "admins": "Admins", - "manage-tenant-admins": "Gestionar administradores tenant", - "delete": "Eliminar tenant", - "add-tenant-text": "Agregar nuevo tenant", - "no-tenants-text": "Ningún tenant encontrado", - "tenant-details": "Detalles del Tenant", - "delete-tenant-title": "¿Estás seguro que quieres eliminar el tenant '{{tenantTitle}}'?", - "delete-tenant-text": "Ten cuidado, luego de confirmar el tenant será eliminado y la información relacionada será irrecuperable.", - "delete-tenants-title": "¿Estás seguro que quieres eliminar { count, select, 1 {1 tenant} other {# tenants} }?", - "delete-tenants-action-title": "Eliminar { count, select, 1 {1 tenant} other {# tenants} }", - "delete-tenants-text": "Ten cuidado, luego de confirmar los tenants seleccionados serán eliminados y la información relacionada será irrecuperable.", - "title": "Título", - "title-required": "Título requerido.", - "description": "Descripción" - }, - "timeinterval": { - "seconds-interval": "{ seconds, select, 1 {1 segundo} other {# segundos} }", - "minutes-interval": "{ minutes, select, 1 {1 minuto} other {# minutos} }", - "hours-interval": "{ hours, select, 1 {1 hora} other {# horas} }", - "days-interval": "{ days, select, 1 {1 día} other {# días} }", - "days": "Días", - "hours": "Horas", - "minutes": "Minutos", - "seconds": "Segundos", - "advanced": "Avanzado" - }, - "timewindow": { - "days": "{ days, select, 1 { día } other {# días } }", - "hours": "{ hours, select, 0 { horas } 1 {1 hora } other {# horas } }", - "minutes": "{ minutes, select, 0 { minutos } 1 {1 minuto } other {# minutos } }", - "seconds": "{ seconds, select, 0 { segundos } 1 {1 segundo } other {# segundos } }", - "realtime": "Tiempo-real", - "history": "Histórico", - "last-prefix": "último", - "period": "desde {{ startTime }} hasta {{ endTime }}", - "edit": "Editar ventana de tiempo", - "date-range": "Rango de fechas", - "last": "Últimos", - "time-period": "Período de tiempo" - }, - "user": { - "users": "Usuarios", - "customer-users": "Usuarios del Cliente", - "tenant-admins": "Tenant Admins", - "sys-admin": "Administrador del Sistema", - "tenant-admin": "Administrador Tenant", - "customer": "Cliente", - "anonymous": "Anónimo", - "add": "Agregar usuario", - "delete": "Eliminar usuario", - "add-user-text": "Agregar nuevo usuario", - "no-users-text": "Ningún usuario encontrado", - "user-details": "Detalles del usuario", - "delete-user-title": "¿Estás seguro que quieres eliminar el usuario '{{userEmail}}'?", - "delete-user-text": "Ten cuidado, luego de confirmar el usuario seleccionado será eliminado y la información relacionada será irrecuperable.", - "delete-users-title": "¿Estás seguro que quieres eliminar { count, select, 1 {1 usuario} other {# usuarios} }?", - "delete-users-action-title": "Borrar { count, select, 1 {1 usuario} other {# usuarios} }", - "delete-users-text": "Ten cuidado, luego de confirmar los usuarios seleccionados serán eliminados y la información relacionada será irrecuperable.", - "activation-email-sent-message": "Mail de activación enviado con éxito!", - "resend-activation": "Reenviar activación", - "email": "Email", - "email-required": "Email requerido.", - "first-name": "Nombre", - "last-name": "Apellido", - "description": "Descripción", - "default-dashboard": "Panel por defecto", - "always-fullscreen": "Siempre en pantalla completa" - }, - "value": { - "type": "Tipo de valor", - "string": "Cadena de texto", - "string-value": "Valor de cadena de texto", - "integer": "Nro entero", - "integer-value": "Valor de nro entero", - "invalid-integer-value": "Valor inválido", - "double": "Nro decimal", - "double-value": "Valor nro decimal", - "boolean": "Booleano", - "boolean-value": "Valor booleano", - "false": "Falso", - "true": "Verdadero" - }, - "widget": { - "widget-library": "Bibloteca de Widgets", - "widget-bundle": "Paquetes de Widgets", - "select-widgets-bundle": "Seleccionar paquete de widgets", - "management": "Gestión de Widgets", - "editor": "Editor de widgets", - "widget-type-not-found": "Problema al cargar la configuración del widget.
Probablemente asociado\n El tipo de widget fue eliminado.", - "widget-type-load-error": "Widget no pudo ser cargado debido a estos errores:", - "remove": "Eliminar widget", - "edit": "Editar widget", - "remove-widget-title": "¿Estás seguro que quieres eliminar el widget '{{widgetTitle}}'?", - "remove-widget-text": "Luego de confirmar el widget será eliminado y toda la información relacionada será irrecuperable..", - "timeseries": "Series de tiempo", - "latest-values": "Últimos valores", - "rpc": "Widget de control", - "static": "Widget estático", - "select-widget-type": "Seleccionar tipo de widget", - "missing-widget-title-error": "El titulo del widget debe ser especificado!", - "widget-saved": "Widget guardado", - "unable-to-save-widget-error": "Imposible guardar widget! Tiene errores!", - "save": "Guardar widget", - "saveAs": "Guardar widget como", - "save-widget-type-as": "Guardar tipo de widget como", - "save-widget-type-as-text": "Por favor, ingrese un nuevo titulo y/o seleccione un paquete de destino.", - "toggle-fullscreen": "Cambiar a pantalla completa", - "run": "Correr widget", - "title": "Titulo", - "title-required": "Titulo requerido.", - "type": "Tipo", - "resources": "Recursos", - "resource-url": "JavaScript/CSS URL", - "remove-resource": "Eliminar recurso", - "add-resource": "Agregar recurso", - "html": "HTML", - "tidy": "Tidy", - "css": "CSS", - "settings-schema": "Esquema de configuración", - "datakey-settings-schema": "Esquema de configuración de clave de datos", - "javascript": "Javascript", - "remove-widget-type-title": "¿Estás seguro que quieres eliminar el tipo del widget '{{widgetName}}'?", - "remove-widget-type-text": "Luego de confirmar el tipo será eliminado y la información relacionada será irrecuperable.", - "remove-widget-type": "Eliminar tipo de widget.", - "add-widget-type": "Agregar nuevo tipo de widget", - "widget-type-load-failed-error": "Error al cargar el tipo de widget!", - "widget-template-load-failed-error": "Error al cargar el template del widget!", - "add": "Agregar Widget", - "undo": "Deshacer cambios", - "export": "Exportar widget" - }, - "widget-action": { // TODO - "header-button": "Widget header button", - "open-dashboard-state": "Navigate to new dashboard state", - "update-dashboard-state": "Update current dashboard state", - "open-dashboard": "Navigate to other dashboard", - "custom": "Custom action", - "target-dashboard-state": "Target dashboard state", - "target-dashboard-state-required": "Target dashboard state is required", - "set-entity-from-widget": "Set entity from widget", - "target-dashboard": "Target dashboard", - "open-right-layout": "Open right dashboard layout (mobile view)" - }, - "widgets-bundle": { - "current": "Paquete actual", - "widgets-bundles": "Paquete de Widgets", - "add": "Agregar paquete de widgets", - "delete": "Eliminar paquete de widgets", - "title": "Título", - "title-required": "Título requerido.", - "add-widgets-bundle-text": "Agregar nuevo paquete de widgets", - "no-widgets-bundles-text": "Ningún paquete de widgets encontrado", - "empty": "Paquete de widgets vacío.", - "details": "Detalles", - "widgets-bundle-details": "Detalles del paquete de Widgets", - "delete-widgets-bundle-title": "¿Estás seguro que desea eliminar el paquete de widgets '{{widgetsBundleTitle}}'?", - "delete-widgets-bundle-text": "Ten cuidado, luego de confirmar todos los paquetes seleccionados serán eliminados y su información relacionada será irrecuperable.", - "delete-widgets-bundles-title": "¿Estás seguro que deseas eliminar { count, select, 1 {1 paquete de widgets} other {# paquetes de widgets} }?", - "delete-widgets-bundles-action-title": "Eliminar { count, select, 1 {1 paquete de widgets} other {# paquetes de widgets} }", - "delete-widgets-bundles-text": "Ten cuidado, luego de confirmar todos los paquetes seleccionados serán eliminados y la información relacionada será irrecuperable.", - "no-widgets-bundles-matching": "Ningún paquete '{{widgetsBundle}}' encontrado.", - "widgets-bundle-required": "Paquete de widget requerido.", - "system": "Sistema", - "import": "Importar paquete de widgets", - "export": "Exportar paquete de widgets", - "export-failed-error": "Imposible exportar paquete de widgets: {{error}}", - "create-new-widgets-bundle": "Crear nuevo paquete de widgets", - "widgets-bundle-file": "Archivo de paquete de widgets", - "invalid-widgets-bundle-file-error": "Imposible importar paquete de widgets: Estructura de datos inválida." - }, - "widget-config": { - "data": "Datos", - "settings": "Ajustes", - "advanced": "Avanzado", - "title": "Titulo", - "general-settings": "Ajustes generales", - "display-title": "Mostrar titulo", - "drop-shadow": "Sombra", - "enable-fullscreen": "Habilitar pantalla completa", - "background-color": "Color de fondo", - "text-color": "Color del texto", - "padding": "Relleno", - "title-style": "Estilo de título", - "mobile-mode-settings": "Ajustes mobile.", - "order": "Orden", - "height": "Altura", - "units": "Caracter especial a mostrar en el siguiente valor", - "decimals": "Números de dígitos después de la coma", - "timewindow": "Ventana de tiempo", - "use-dashboard-timewindow": "Usar ventana de tiempo del Panel", - "display-legend": "Mostrar leyenda", - "datasources": "Set de datos", - "datasource-type": "Tipo", - "datasource-parameters": "Parámetros", - "remove-datasource": "Eliminar set de datos", - "add-datasource": "Agregar set de datos", - "target-device": "Dispositivo destino" - }, - "widget-type": { - "import": "Importar tipo de widget", - "export": "Exportar tipo de widget", - "export-failed-error": "Imposible exportar tipo de widget: {{error}}", - "create-new-widget-type": "Crear nuevo tipo de widget", - "widget-type-file": "Tipo de archivo del widget", - "invalid-widget-type-file-error": "Imposible de importar tipo de widget: Estructura de datos inválida." - }, - "icon": { // TODO - "icon": "Icon", - "select-icon": "Select icon", - "material-icons": "Material icons", - "show-all": "Show all icons" - }, - "custom": { // TODO - "widget-action": { - "action-cell-button": "Action cell button", - "row-click": "On row click", - "marker-click": "On marker click", - "tooltip-tag-action": "Tooltip tag action" - } - }, - "language": { - "language": "Lenguaje", - "en_US": "Inglés", - "ko_KR": "Coreano", - "zh_CN": "Chino", - "ru_RU": "Ruso", - "es_ES": "Español" - } - }; - angular.extend(locales, { 'es_ES': es_ES }); -} \ No newline at end of file diff --git a/ui/src/app/locale/locale.constant-es_ES.json b/ui/src/app/locale/locale.constant-es_ES.json new file mode 100644 index 0000000000..9e5951f0c8 --- /dev/null +++ b/ui/src/app/locale/locale.constant-es_ES.json @@ -0,0 +1,1317 @@ +{ + "access": { + "unauthorized": "No autorizado", + "unauthorized-access": "Acceso no autorizado", + "unauthorized-access-text": "Debes iniciar sesión para tener acceso a este recurso!", + "access-forbidden": "Acceso Prohibido", + "access-forbidden-text": "No tienes derechos para acceder a esta ubicación!
Intenta iniciar sesión con otro usuario si todavía quieres acceder a esta ubicación.", + "refresh-token-expired": "La sesión ha expirado", + "refresh-token-failed": "No se puede actualizar la sesión" + }, + "action": { + "activate": "Activar", + "suspend": "Suspender", + "save": "Guardar", + "saveAs": "Guardar como", + "cancel": "Cancelar", + "ok": "OK", + "delete": "Borrar", + "add": "Agregar", + "yes": "Si", + "no": "No", + "update": "Actualizar", + "remove": "Eliminar", + "search": "Buscar", + "assign": "Asignar", + "unassign": "Cancelar asignación", + "share": "Compartir", + "make-private": "Hacer privado", + "apply": "Aplicar", + "apply-changes": "Aplicar cambios", + "edit-mode": "Modo Edición", + "enter-edit-mode": "Modo Edición", + "decline-changes": "Descartar cambios", + "close": "Cerrar", + "back": "Atrás", + "run": "Correr", + "sign-in": "Regístrate!", + "edit": "Editar", + "view": "Ver", + "create": "Crear", + "drag": "Arrastrar", + "refresh": "Refrescar", + "undo": "Deshacer", + "copy": "Copiar", + "paste": "Pegar", + "import": "Importar", + "export": "Exportar", + "share-via": "Compartir vía {{provider}}" + }, + "aggregation": { + "aggregation": "Agregación", + "function": "Función de Agregación", + "limit": "Valores Max", + "group-interval": "Intervalo de agrupación", + "min": "Min", + "max": "Max", + "avg": "Promedio", + "sum": "Suma", + "count": "Cuenta", + "none": "Ninguno" + }, + "admin": { + "general": "General", + "general-settings": "Ajustes General", + "outgoing-mail": "Mail de Salida", + "outgoing-mail-settings": "Ajustes del Mail de Salida", + "system-settings": "Sistema", + "test-mail-sent": "Mail de prueba enviado correctamente!", + "base-url": "URL Base", + "base-url-required": "URL Base requerida.", + "mail-from": "Mail Desde", + "mail-from-required": "Mail Desde requerido.", + "smtp-protocol": "Protocolo SMTP", + "smtp-host": "Host SMTP", + "smtp-host-required": "Host SMTP requerido.", + "smtp-port": "Puerto SMTP", + "smtp-port-required": "Debe ingresar un Puerto SMTP.", + "smtp-port-invalid": "No parece un Puerto SMTP valido.", + "timeout-msec": "Timeout (ms)", + "timeout-required": "Timeout requerido.", + "timeout-invalid": "No parece un Timeout valido.", + "enable-tls": "Habilitar TLS", + "send-test-mail": "Enviar mail de prueba" + }, + "alarm": { + "alarm": "Alarm", + "alarms": "Alarms", + "select-alarm": "Select alarm", + "no-alarms-matching": "No alarms matching '{{entity}}' were found.", + "alarm-required": "Alarm is required", + "alarm-status": "Alarm status", + "search-status": { + "ANY": "Any", + "ACTIVE": "Active", + "CLEARED": "Cleared", + "ACK": "Acknowledged", + "UNACK": "Unacknowledged" + }, + "display-status": { + "ACTIVE_UNACK": "Active Unacknowledged", + "ACTIVE_ACK": "Active Acknowledged", + "CLEARED_UNACK": "Cleared Unacknowledged", + "CLEARED_ACK": "Cleared Acknowledged" + }, + "no-alarms-prompt": "No alarms found", + "created-time": "Created time", + "type": "Type", + "severity": "Severity", + "originator": "Originator", + "originator-type": "Originator type", + "details": "Details", + "status": "Status", + "alarm-details": "Alarm details", + "start-time": "Start time", + "end-time": "End time", + "ack-time": "Acknowledged time", + "clear-time": "Cleared time", + "severity-critical": "Critical", + "severity-major": "Major", + "severity-minor": "Minor", + "severity-warning": "Warning", + "severity-indeterminate": "Indeterminate", + "acknowledge": "Acknowledge", + "clear": "Clear", + "search": "Search alarms", + "selected-alarms": "{ count, plural, 1 {1 alarm} other {# alarms} } selected", + "no-data": "No data to display", + "polling-interval": "Alarms polling interval (sec)", + "polling-interval-required": "Alarms polling interval is required.", + "min-polling-interval-message": "At least 1 sec polling interval is allowed.", + "aknowledge-alarms-title": "Acknowledge { count, plural, 1 {1 alarm} other {# alarms} }", + "aknowledge-alarms-text": "Are you sure you want to acknowledge { count, plural, 1 {1 alarm} other {# alarms} }?", + "clear-alarms-title": "Clear { count, plural, 1 {1 alarm} other {# alarms} }", + "clear-alarms-text": "Are you sure you want to clear { count, plural, 1 {1 alarm} other {# alarms} }?" + }, + "alias": { + "add": "Add alias", + "edit": "Edit alias", + "name": "Alias name", + "name-required": "Alias name is required", + "duplicate-alias": "Alias with same name is already exists.", + "filter-type-single-entity": "Single entity", + "filter-type-entity-list": "Entity list", + "filter-type-entity-name": "Entity name", + "filter-type-state-entity": "Entity from dashboard state", + "filter-type-state-entity-description": "Entity taken from dashboard state parameters", + "filter-type-asset-type": "Asset type", + "filter-type-asset-type-description": "Assets of type '{{assetType}}'", + "filter-type-asset-type-and-name-description": "Assets of type '{{assetType}}' and with name starting with '{{prefix}}'", + "filter-type-device-type": "Device type", + "filter-type-device-type-description": "Devices of type '{{deviceType}}'", + "filter-type-device-type-and-name-description": "Devices of type '{{deviceType}}' and with name starting with '{{prefix}}'", + "filter-type-relations-query": "Relations query", + "filter-type-relations-query-description": "{{entities}} that have {{relationType}} relation {{direction}} {{rootEntity}}", + "filter-type-asset-search-query": "Asset search query", + "filter-type-asset-search-query-description": "Assets with types {{assetTypes}} that have {{relationType}} relation {{direction}} {{rootEntity}}", + "filter-type-device-search-query": "Device search query", + "filter-type-device-search-query-description": "Devices with types {{deviceTypes}} that have {{relationType}} relation {{direction}} {{rootEntity}}", + "entity-filter": "Entity filter", + "resolve-multiple": "Resolve as multiple entities", + "filter-type": "Filter type", + "filter-type-required": "Filter type is required.", + "entity-filter-no-entity-matched": "No entities matching specified filter were found.", + "no-entity-filter-specified": "No entity filter specified", + "root-state-entity": "Use dashboard state entity as root", + "root-entity": "Root entity", + "state-entity-parameter-name": "State entity parameter name", + "default-state-entity": "Default state entity", + "default-entity-parameter-name": "By default", + "max-relation-level": "Max relation level", + "unlimited-level": "Unlimited level", + "state-entity": "Dashboard state entity", + "all-entities": "All entities", + "any-relation": "any" + }, + "asset": { + "asset": "Asset", + "assets": "Assets", + "management": "Asset management", + "view-assets": "View Assets", + "add": "Add Asset", + "assign-to-customer": "Assign to customer", + "assign-asset-to-customer": "Assign Asset(s) To Customer", + "assign-asset-to-customer-text": "Please select the assets to assign to the customer", + "no-assets-text": "No assets found", + "assign-to-customer-text": "Please select the customer to assign the asset(s)", + "public": "Public", + "assignedToCustomer": "Assigned to customer", + "make-public": "Make asset public", + "make-private": "Make asset private", + "unassign-from-customer": "Unassign from customer", + "delete": "Delete asset", + "asset-public": "Asset is public", + "asset-type": "Asset type", + "asset-type-required": "Asset type is required.", + "select-asset-type": "Select asset type", + "enter-asset-type": "Enter asset type", + "any-asset": "Any asset", + "no-asset-types-matching": "No asset types matching '{{entitySubtype}}' were found.", + "asset-type-list-empty": "No asset types selected.", + "asset-types": "Asset types", + "name": "Name", + "name-required": "Name is required.", + "description": "Description", + "type": "Type", + "type-required": "Type is required.", + "details": "Details", + "events": "Events", + "add-asset-text": "Add new asset", + "asset-details": "Asset details", + "assign-assets": "Assign assets", + "assign-assets-text": "Assign { count, plural, 1 {1 asset} other {# assets} } to customer", + "delete-assets": "Delete assets", + "unassign-assets": "Unassign assets", + "unassign-assets-action-title": "Unassign { count, plural, 1 {1 asset} other {# assets} } from customer", + "assign-new-asset": "Assign new asset", + "delete-asset-title": "Are you sure you want to delete the asset '{{assetName}}'?", + "delete-asset-text": "Be careful, after the confirmation the asset and all related data will become unrecoverable.", + "delete-assets-title": "Are you sure you want to delete { count, plural, 1 {1 asset} other {# assets} }?", + "delete-assets-action-title": "Delete { count, plural, 1 {1 asset} other {# assets} }", + "delete-assets-text": "Be careful, after the confirmation all selected assets will be removed and all related data will become unrecoverable.", + "make-public-asset-title": "Are you sure you want to make the asset '{{assetName}}' public?", + "make-public-asset-text": "After the confirmation the asset and all its data will be made public and accessible by others.", + "make-private-asset-title": "Are you sure you want to make the asset '{{assetName}}' private?", + "make-private-asset-text": "After the confirmation the asset and all its data will be made private and won't be accessible by others.", + "unassign-asset-title": "Are you sure you want to unassign the asset '{{assetName}}'?", + "unassign-asset-text": "After the confirmation the asset will be unassigned and won't be accessible by the customer.", + "unassign-asset": "Unassign asset", + "unassign-assets-title": "Are you sure you want to unassign { count, plural, 1 {1 asset} other {# assets} }?", + "unassign-assets-text": "After the confirmation all selected assets will be unassigned and won't be accessible by the customer.", + "copyId": "Copy asset Id", + "idCopiedMessage": "Asset Id has been copied to clipboard", + "select-asset": "Select asset", + "no-assets-matching": "No assets matching '{{entity}}' were found.", + "asset-required": "Asset is required", + "name-starts-with": "Asset name starts with" + }, + "attribute": { + "attributes": "Atributos", + "latest-telemetry": "Última telemetría", + "attributes-scope": "Alcance de los atributos del dispositivo", + "scope-latest-telemetry": "Última telemetría", + "scope-client": "Atributos del Cliente", + "scope-server": "Atributos del Servidor", + "scope-shared": "Atributos Compartidos", + "add": "Agregar atributo", + "key": "Clave", + "key-required": "Clave del atributo requerida.", + "value": "Valor", + "value-required": "Valor del atributo requerido.", + "delete-attributes-title": "¿Estás seguro que quieres eliminar { count, plural, 1 {1 atributo} other {# atributos} }?", + "delete-attributes-text": "Ten cuidado, luego de confirmar el atributo será eliminado, y la información relacionada será irrecuperable.", + "delete-attributes": "Borrar atributo", + "enter-attribute-value": "Ingresar valor del atributo", + "show-on-widget": "Mostrar en Widget", + "widget-mode": "Widget", + "next-widget": "Widget siguiente", + "prev-widget": "Widget anterior", + "add-to-dashboard": "Agregar al Panel", + "add-widget-to-dashboard": "Agregar widget al Panel", + "selected-attributes": "{ count, plural, 1 {1 atributo} other {# atributos} } seleccionados", + "selected-telemetry": "{ count, plural, 1 {1 unidad de telemetría } other {# unidades de telemetría} } seleccionadas." + }, + "audit-log": { + "audit": "Audit", + "audit-logs": "Audit Logs", + "timestamp": "Timestamp", + "entity-type": "Entity Type", + "entity-name": "Entity Name", + "user": "User", + "type": "Type", + "status": "Status", + "details": "Details", + "type-added": "Added", + "type-deleted": "Deleted", + "type-updated": "Updated", + "type-attributes-updated": "Attributes updated", + "type-attributes-deleted": "Attributes deleted", + "type-rpc-call": "RPC call", + "type-credentials-updated": "Credentials updated", + "type-assigned-to-customer": "Assigned to Customer", + "type-unassigned-from-customer": "Unassigned from Customer", + "type-activated": "Activated", + "type-suspended": "Suspended", + "type-credentials-read": "Credentials read", + "type-attributes-read": "Attributes read", + "status-success": "Success", + "status-failure": "Failure", + "audit-log-details": "Audit log details", + "no-audit-logs-prompt": "No logs found", + "action-data": "Action data", + "failure-details": "Failure details", + "search": "Search audit logs", + "clear-search": "Clear search" + }, + "confirm-on-exit": { + "message": "Tienes cambios sin guardar. ¿Estás seguro que quieres abandonar la página?", + "html-message": "Tienes cambios sin guardar.
¿Estás seguro que quieres abandonar la página?", + "title": "Cambios sin guardar" + }, + "contact": { + "country": "País", + "city": "Ciudad", + "state": "Estado/Provincia", + "postal-code": "Código Postal", + "postal-code-invalid": "Solo se permiten dígitos.", + "address": "Dirección", + "address2": "Dirección 2", + "phone": "Teléfono", + "email": "Email", + "no-address": "Sin Dirección" + }, + "common": { + "username": "Usuario", + "password": "Contraseña", + "enter-username": "Ingresa el nombre de usuario.", + "enter-password": "Ingresa la contraseña", + "enter-search": "Ingresa búsqueda" + }, + "content-type": { + "json": "Json", + "text": "Text", + "binary": "Binary (Base64)" + }, + "customer": { + "customers": "Clientes", + "management": "Gestión de Clientes", + "dashboard": "Panel del Cliente", + "dashboards": "Paneles del Cliente", + "devices": "Panel del Cliente", + "public-dashboards": "Paneles Públicos", + "public-devices": "Dispositivos Públicos", + "add": "Agregar cliente", + "delete": "Borrar cliente", + "manage-customer-users": "Gestionar usuarios del cliente", + "manage-customer-devices": "Gestionar dispositivos del cliente", + "manage-customer-dashboards": "Gestionar paneles del cliente", + "manage-public-devices": "Gestionar dispositivos públicos", + "manage-public-dashboards": "Gestionar paneles públicos", + "add-customer-text": "Agregar nuevo cliente", + "no-customers-text": "No se encontrar clientes", + "customer-details": "Detalles del cliente", + "delete-customer-title": "¿Estás seguro que quieres eliminar el cliente '{{customerTitle}}'?", + "delete-customer-text": "Ten cuidado, luego de confirmar el cliente será eliminado y toda la información relacionada será irrecuperable.", + "delete-customers-title": "¿Estás seguro que quieres eliminar { count, plural, 1 {1 cliente} other {# clientes} }?", + "delete-customers-action-title": "Borrar { count, plural, 1 {1 cliente} other {# clientes} }", + "delete-customers-text": "Ten cuidado, luego de confirmar todos los clientes seleccionados serán eliminados y su información relacionada será irrecuperable.", + "manage-users": "Gestionar usuarios", + "manage-devices": "Gestionar dispositivos", + "manage-dashboards": "Gestionar paneles", + "title": "Título", + "title-required": "Título requerido.", + "description": "Descripción" + }, + "datetime": { + "date-from": "Fecha desde", + "time-from": "Tiempo desde", + "date-to": "Fecha hasta", + "time-to": "Tiempo hasta" + }, + "dashboard": { + "dashboard": "Panel", + "dashboards": "Paneles", + "management": "Gestión de Paneles", + "view-dashboards": "Ver paneles", + "add": "Agregar Panel", + "assign-dashboard-to-customer": "Asignar panel(es) a cliente", + "assign-dashboard-to-customer-text": "Por favor, seleccione algún panel para asignar al Cliente.", + "assign-to-customer-text": "Por favor, seleccione algún cliente para asignar al(los) panel(es).", + "assign-to-customer": "Asignar a cliente", + "unassign-from-customer": "Desasignar del cliente", + "make-public": "Hacer panel público", + "make-private": "Hacer panel privado", + "no-dashboards-text": "Ningún panel encontrado", + "no-widgets": "Ningún widget configurado", + "add-widget": "Agregar nuevo widget", + "title": "Titulo", + "select-widget-title": "Seleccionar widget", + "select-widget-subtitle": "Lista de tipos de widgets", + "delete": "Eliminar panel", + "title-required": "Título requerido.", + "description": "Descripción", + "details": "Detalles", + "dashboard-details": "Detalles del panel", + "add-dashboard-text": "Agregar nuevo panel", + "assign-dashboards": "Asignar paneles", + "assign-new-dashboard": "Asignar nuevo panel", + "assign-dashboards-text": "Asignar { count, plural, 1 {1 panel} other {# paneles} } al cliente", + "delete-dashboards": "Eliminar paneles", + "unassign-dashboards": "Desasignar paneles", + "unassign-dashboards-action-title": "Desasignar { count, plural, 1 {1 paneles} other {# paneles} } del cliente", + "delete-dashboard-title": "¿Estás seguro que quieres eliminar el panel '{{dashboardTitle}}'?", + "delete-dashboard-text": "Ten cuidado, el panel seleccionado será eliminado y la información relacionada sera irrecuperable.", + "delete-dashboards-title": "¿Estás seguro que quieres eliminar { count, plural, 1 {1 panel} other {# paneles} }?", + "delete-dashboards-action-title": "Eliminar { count, plural, 1 {1 panel} other {# paneles} }", + "delete-dashboards-text": "Ten cuidado, los paneles seleccionados serán eliminados y la información relacionada será irrecuperable.", + "unassign-dashboard-title": "¿Estás seguro que quieres desasignar el panel '{{dashboardTitle}}'?", + "unassign-dashboard-text": "Luego de confirmar, el panel será desasignado y no podrá ser accesible por el cliente.", + "unassign-dashboard": "Desasignar panel", + "unassign-dashboards-title": "¿Estás seguro que quieres desasignar { count, plural, 1 {1 panel} other {# paneles} }?", + "unassign-dashboards-text": "Luego de confirmar, los paneles seleccionados serán desasignados y no podrán ser accesibles por el cliente.", + "public-dashboard-title": "El panel ahora es público", + "public-dashboard-text": "Tu panel {{dashboardTitle}} es ahora público y podrá ser accedido desde: aquí:", + "public-dashboard-notice": "Nota: No olvides hacer públicos los dispositivos relacionados para acceder a sus datos.", + "make-private-dashboard-title": "¿Estás seguro que quieres hacer el panel '{{dashboardTitle}}' privado?", + "make-private-dashboard-text": "Luego de confirmar, el panel será privado y no podrá ser accesible por otros.", + "make-private-dashboard": "Hacer panel privado", + "socialshare-text": "'{{dashboardTitle}}' powered by ThingsBoard", + "socialshare-title": "'{{dashboardTitle}}' powered by ThingsBoard", + "select-dashboard": "Seleccionar panel", + "no-dashboards-matching": "Panel '{{entity}}' no encontrado.", + "dashboard-required": "Panel requerido.", + "select-existing": "Seleccionar paneles existentes", + "create-new": "Crear nuevo panel", + "new-dashboard-title": "Nuevo título", + "open-dashboard": "Abrir panel", + "set-background": "Definir fondo", + "background-color": "Color de fondo", + "background-image": "Imagen de fondo", + "background-size-mode": "Modo tamaño de fondo", + "no-image": "No se ha seleccionado ningúna imagen", + "drop-image": "Suelte una imagen o haga clic para seleccionar un archivo para cargar.", + "settings": "Ajustes", + "columns-count": "Número de columnas", + "columns-count-required": "Número de columnas requerido.", + "min-columns-count-message": "Solo se permite un número mínimo de 10 columnas.", + "max-columns-count-message": "Solo se permite un número máximo de 1000 columnas.", + "widgets-margins": "Margen entre widgets", + "horizontal-margin": "Margen horizontal", + "horizontal-margin-required": "Margen horizontal requerido.", + "min-horizontal-margin-message": "Solo se permite margen horizontal mínimo de 0.", + "max-horizontal-margin-message": "Solo se permite margen horizontal máximo de 50.", + "vertical-margin": "Margen vertical", + "vertical-margin-required": "Margen vertical requerido.", + "min-vertical-margin-message": "Solo se permite margen vertical mínimo de 0.", + "max-vertical-margin-message": "Solo se permite margen vertical máximo de 50.", + "display-title": "Mostrar título del panel", + "title-color": "Color del título", + "display-device-selection": "Mostrar selección de dispositivo", + "display-dashboard-timewindow": "Mostrar ventana de tiempo", + "display-dashboard-export": "Mostrar exportar", + "import": "Importar panel", + "export": "Exportar panel", + "export-failed-error": "Imposible exportar panel: {{error}}", + "create-new-dashboard": "Crear nuevo panel", + "dashboard-file": "Archivo del panel", + "invalid-dashboard-file-error": "Imposible importar panel: Estructura de datos inválida.", + "dashboard-import-missing-aliases-title": "Configurar alias utilizados por el panel importado", + "create-new-widget": "Crear nuevo widget", + "import-widget": "Importar widget", + "widget-file": "Archivo de widget", + "invalid-widget-file-error": "Imposible importar widget: Estructura de datos inválida.", + "widget-import-missing-aliases-title": "Configurar alias utilizados por el widget", + "open-toolbar": "Abrir toolbar del panel", + "close-toolbar": "Cerrar toolbar", + "configuration-error": "Error de configuración", + "alias-resolution-error-title": "Error de configuración de alias del panel", + "invalid-aliases-config": "No se puede encontrar ningún dispositivo que coincida con algunos de los alias de filtro.
Póngase en contacto con su administrador para resolver este problema.", + "select-devices": "Seleccionar dispositivos", + "assignedToCustomer": "Asignado al cliente", + "public": "Público", + "public-link": "Link público", + "copy-public-link": "Copiar link público", + "public-link-copied-message": "El link público del panel se ha copiado al portapapeles" + }, + "datakey": { + "settings": "Ajustes", + "advanced": "Avanzado", + "label": "Etiqueta", + "color": "Color", + "data-generation-func": "Función de generación de datos", + "use-data-post-processing-func": "Usar funcíon de post-procesamiendo de datos", + "configuration": "Ajustes de clave de datos", + "timeseries": "Serie de tiempos", + "attributes": "Atributos", + "timeseries-required": "Series de tiempo del dispositivo requerido.", + "timeseries-or-attributes-required": "Series de tiempo/Atributos requeridos.", + "function-types": "Tipos de funciones", + "function-types-required": "Tipos de funciones requerido." + }, + "datasource": { + "type": "Típo de fuente de datos", + "add-datasource-prompt": "Por favor, agrega una fuente de datos" + }, + "details": { + "edit-mode": "Modo Edición", + "toggle-edit-mode": "Ir a Modo Edición" + }, + "device": { + "device": "Dispositivo", + "device-required": "Dispositivo requerido.", + "devices": "Dispositivos", + "management": "Gestión de Dispositivos", + "view-devices": "Ver dispositivos", + "device-alias": "Alias de dispositivo", + "aliases": "Alias de dispositivos", + "no-alias-matching": "'{{alias}}' no encontrado.", + "no-aliases-found": "Ningún alias encontrado.", + "no-key-matching": "'{{key}}' no encontrado.", + "no-keys-found": "Ninguna clave encontrada.", + "create-new-alias": "Crear nuevo alias!", + "create-new-key": "Crear nueva clave!", + "duplicate-alias-error": "Alias duplicado '{{alias}}'.
El alias de los dispositivos deben ser únicos dentro del panel.", + "configure-alias": "Configurar alias '{{alias}}'", + "no-devices-matching": "No se encontró dispositivo '{{entity}}'", + "alias": "Alias", + "alias-required": "Alias de dispositivo requerido.", + "remove-alias": "Eliminar alias", + "add-alias": "Agregar alias", + "name-starts-with": "Nombre empieza con", + "device-list": "Lista de dispositivos", + "use-device-name-filter": "Usar filtro", + "device-list-empty": "Ningún dispositivo seleccionado.", + "device-name-filter-required": "Nombre de filtro requerido.", + "device-name-filter-no-device-matched": "Ningún dispositivo encontrado que comience con '{{device}}'.", + "add": "Agregar dispositivo", + "assign-to-customer": "Asignar a cliente", + "assign-device-to-customer": "Asignar dispositivo(s) a Cliente", + "assign-device-to-customer-text": "Por favor, seleccione los dispositivos que serán asignados al cliente", + "make-public": "Hacer dispositivo público", + "make-private": "Hacer dispositivo privado", + "no-devices-text": "Ningún dispositivo encontrado", + "assign-to-customer-text": "Por favor, seleccione el cliente para asignar el(los) dispositivo(s)", + "device-details": "Detalles del dispositivo", + "add-device-text": "Agregar nuevo dispositivo", + "credentials": "Credenciales", + "manage-credentials": "Gestionar credenciales", + "delete": "Eliminar dispositivo", + "assign-devices": "Asignar dispositivo", + "assign-devices-text": "Asignar { count, plural, 1 {1 dispositivo} other {# dispositivos} } al cliente", + "delete-devices": "Eliminar dispositivo", + "unassign-from-customer": "Desasignar del cliente", + "unassign-devices": "Desasignar dispositivos", + "unassign-devices-action-title": "Desasignar { count, plural, 1 {1 dispositivo} other {# dispositivos} } del cliente", + "assign-new-device": "Asignar nuevo dispositivo", + "make-public-device-title": "¿Estás seguro que quieres hacer el dispositivo '{{deviceName}}' público?", + "make-public-device-text": "Luego de confirmar, el dispositivo y la información relacionada serán públicos y podrá ser accesible por otros.", + "make-private-device-title": "¿Estás seguro que quieres hacer el dispositivo '{{deviceName}}' privado?", + "make-private-device-text": "Luego de confirmar, el dispositivo y la información relacionada serán privados y no podrá ser accesible por otros.", + "view-credentials": "Ver credenciales", + "delete-device-title": "¿Estás seguro que quieres eliminar el dispositivo '{{deviceName}}'?", + "delete-device-text": "Ten cuidado, luego de confirmar los dispositivos serán eliminados y la información relacionada será irrecuperable.", + "delete-devices-title": "¿Estás seguro que quieres eliminar { count, plural, 1 {1 dispositivo} other {# dispositivos} }?", + "delete-devices-action-title": "Eliminar { count, plural, 1 {1 dispositivo} other {# dispositivos} }", + "delete-devices-text": "Ten cuidado, luego de confirmar los dispositivos seleccionados serán eliminados y la información relacionada será irrecuperable.", + "unassign-device-title": "¿Estás seguro que quieres desasignar el dispositivo '{{deviceName}}'?", + "unassign-device-text": "Luego de confirmar el dispositivo será desasignado y no podrá ser accesible por el cliente.", + "unassign-device": "Desasignar dispositivo", + "unassign-devices-title": "¿Estás seguro que quieres desasignar { count, plural, 1 {1 dispositivo} other {# dispositivos} }?", + "unassign-devices-text": "Luego de confirmar los dispositivos seleccionados serán desasignados y no podrán ser accedidos por el cliente.", + "device-credentials": "Credenciales del dispositivo", + "credentials-type": "Tipo de credencial", + "access-token": "Access token", + "access-token-required": "Access token requerido.", + "access-token-invalid": "Access token debe tener entre 1 a 20 caracteres.", + "rsa-key": "Clave pública RSA", + "rsa-key-required": "Clave pública RSA requerida.", + "secret": "Secreta", + "secret-required": "Secreta requerida.", + "name": "Nombre", + "name-required": "Nombre requerido.", + "description": "Descripción", + "events": "Eventos", + "details": "Detalles", + "copyId": "Copiar ID", + "copyAccessToken": "Copiar access token", + "idCopiedMessage": "Id del dispositivo copiado al portapapeles", + "accessTokenCopiedMessage": "Access token del dispositivo copiado al portapapeles", + "assignedToCustomer": "Asignado al cliente", + "unable-delete-device-alias-title": "Imposible eliminar alias del dispositivo", + "unable-delete-device-alias-text": "Alias '{{deviceAlias}}' no puede ser eliminado. Esta siendo usado por el(los) widget(s):
{{widgetsList}}", + "is-gateway": "Es gateway", + "public": "Público", + "device-public": "Dispositivo público" + }, + "dialog": { + "close": "Cerrar cuadro de diálogo" + }, + "error": { + "unable-to-connect": "Imposible conectar con el servidor! Por favor, revise su conexión a internet.", + "unhandled-error-code": "Código de error no manejado: {{errorCode}}", + "unknown-error": "Error desconocido" + }, + "entity": { + "entity": "Entity", + "entities": "Entities", + "aliases": "Entity aliases", + "entity-alias": "Entity alias", + "unable-delete-entity-alias-title": "Unable to delete entity alias", + "unable-delete-entity-alias-text": "Entity alias '{{entityAlias}}' can't be deleted as it used by the following widget(s):
{{widgetsList}}", + "duplicate-alias-error": "Duplicate alias found '{{alias}}'.
Entity aliases must be unique whithin the dashboard.", + "missing-entity-filter-error": "Filter is missing for alias '{{alias}}'.", + "configure-alias": "Configure '{{alias}}' alias", + "alias": "Alias", + "alias-required": "Entity alias is required.", + "remove-alias": "Remove entity alias", + "add-alias": "Add entity alias", + "entity-list": "Entity list", + "entity-type": "Entity type", + "entity-types": "Entity types", + "entity-type-list": "Entity type list", + "any-entity": "Any entity", + "enter-entity-type": "Enter entity type", + "no-entities-matching": "No entities matching '{{entity}}' were found.", + "no-entity-types-matching": "No entity types matching '{{entityType}}' were found.", + "name-starts-with": "Name starts with", + "use-entity-name-filter": "Use filter", + "entity-list-empty": "No entities selected.", + "entity-type-list-empty": "No entity types selected.", + "entity-name-filter-required": "Entity name filter is required.", + "entity-name-filter-no-entity-matched": "No entities starting with '{{entity}}' were found.", + "all-subtypes": "All", + "select-entities": "Select entities", + "no-aliases-found": "No aliases found.", + "no-alias-matching": "'{{alias}}' not found.", + "create-new-alias": "Create a new one!", + "key": "Key", + "key-name": "Key name", + "no-keys-found": "No keys found.", + "no-key-matching": "'{{key}}' not found.", + "create-new-key": "Create a new one!", + "type": "Type", + "type-required": "Entity type is required.", + "type-device": "Device", + "type-devices": "Devices", + "list-of-devices": "{ count, plural, 1 {One device} other {List of # devices} }", + "device-name-starts-with": "Devices whose names start with '{{prefix}}'", + "type-asset": "Asset", + "type-assets": "Assets", + "list-of-assets": "{ count, plural, 1 {One asset} other {List of # assets} }", + "asset-name-starts-with": "Assets whose names start with '{{prefix}}'", + "type-rule": "Rule", + "type-rules": "Rules", + "list-of-rules": "{ count, plural, 1 {One rule} other {List of # rules} }", + "rule-name-starts-with": "Rules whose names start with '{{prefix}}'", + "type-plugin": "Plugin", + "type-plugins": "Plugins", + "list-of-plugins": "{ count, plural, 1 {One plugin} other {List of # plugins} }", + "plugin-name-starts-with": "Plugins whose names start with '{{prefix}}'", + "type-tenant": "Tenant", + "type-tenants": "Tenants", + "list-of-tenants": "{ count, plural, 1 {One tenant} other {List of # tenants} }", + "tenant-name-starts-with": "Tenants whose names start with '{{prefix}}'", + "type-customer": "Customer", + "type-customers": "Customers", + "list-of-customers": "{ count, plural, 1 {One customer} other {List of # customers} }", + "customer-name-starts-with": "Customers whose names start with '{{prefix}}'", + "type-user": "User", + "type-users": "Users", + "list-of-users": "{ count, plural, 1 {One user} other {List of # users} }", + "user-name-starts-with": "Users whose names start with '{{prefix}}'", + "type-dashboard": "Dashboard", + "type-dashboards": "Dashboards", + "list-of-dashboards": "{ count, plural, 1 {One dashboard} other {List of # dashboards} }", + "dashboard-name-starts-with": "Dashboards whose names start with '{{prefix}}'", + "type-alarm": "Alarm", + "type-alarms": "Alarms", + "list-of-alarms": "{ count, plural, 1 {One alarms} other {List of # alarms} }", + "alarm-name-starts-with": "Alarms whose names start with '{{prefix}}'", + "type-rulechain": "Rule chain", + "type-rulechains": "Rule chains", + "list-of-rulechains": "{ count, plural, 1 {One rule chain} other {List of # rule chains} }", + "rulechain-name-starts-with": "Rule chains whose names start with '{{prefix}}'", + "type-current-customer": "Current Customer", + "search": "Search entities", + "selected-entities": "{ count, plural, 1 {1 entity} other {# entities} } selected", + "entity-name": "Entity name", + "details": "Entity details", + "no-entities-prompt": "No entities found", + "no-data": "No data to display" + }, + "event": { + "event-type": "Tipo de evento", + "type-error": "Error", + "type-lc-event": "Ciclo de vida", + "type-stats": "Estadísticas", + "no-events-prompt": "Ningún evento encontrado.", + "error": "Error", + "alarm": "Alarma", + "event-time": "Hora del evento", + "server": "Servidor", + "body": "Cuerpo", + "method": "Método", + "event": "Evento", + "status": "Status", + "success": "Éxito", + "failed": "Fallo", + "messages-processed": "Mensajes procesados", + "errors-occurred": "Ocurrieron errores" + }, + "extension": { + "extensions": "Extensions", + "selected-extensions": "{ count, plural, 1 {1 extension} other {# extensions} } selected", + "type": "Type", + "key": "Key", + "value": "Value", + "id": "Id", + "extension-id": "Extension id", + "extension-type": "Extension type", + "transformer-json": "JSON *", + "unique-id-required": "Current extension id already exists.", + "delete": "Delete extension", + "add": "Add extension", + "edit": "Edit extension", + "delete-extension-title": "Are you sure you want to delete the extension '{{extensionId}}'?", + "delete-extension-text": "Be careful, after the confirmation the extension and all related data will become unrecoverable.", + "delete-extensions-title": "Are you sure you want to delete { count, plural, 1 {1 extension} other {# extensions} }?", + "delete-extensions-text": "Be careful, after the confirmation all selected extensions will be removed.", + "converters": "Converters", + "converter-id": "Converter id", + "configuration": "Configuration", + "converter-configurations": "Converter configurations", + "token": "Security token", + "add-converter": "Add converter", + "add-config": "Add converter configuration", + "device-name-expression": "Device name expression", + "device-type-expression": "Device type expression", + "custom": "Custom", + "to-double": "To Double", + "transformer": "Transformer", + "json-required": "Transformer json is required.", + "json-parse": "Unable to parse transformer json.", + "attributes": "Attributes", + "add-attribute": "Add attribute", + "add-map": "Add mapping element", + "timeseries": "Timeseries", + "add-timeseries": "Add timeseries", + "field-required": "Field is required", + "brokers": "Brokers", + "add-broker": "Add broker", + "host": "Host", + "port": "Port", + "port-range": "Port should be in a range from 1 to 65535.", + "ssl": "Ssl", + "credentials": "Credentials", + "username": "Username", + "password": "Password", + "retry-interval": "Retry interval in milliseconds", + "anonymous": "Anonymous", + "basic": "Basic", + "pem": "PEM", + "ca-cert": "CA certificate file *", + "private-key": "Private key file *", + "cert": "Certificate file *", + "no-file": "No file selected.", + "drop-file": "Drop a file or click to select a file to upload.", + "mapping": "Mapping", + "topic-filter": "Topic filter", + "converter-type": "Converter type", + "converter-json": "Json", + "json-name-expression": "Device name json expression", + "topic-name-expression": "Device name topic expression", + "json-type-expression": "Device type json expression", + "topic-type-expression": "Device type topic expression", + "attribute-key-expression": "Attribute key expression", + "attr-json-key-expression": "Attribute key json expression", + "attr-topic-key-expression": "Attribute key topic expression", + "request-id-expression": "Request id expression", + "request-id-json-expression": "Request id json expression", + "request-id-topic-expression": "Request id topic expression", + "response-topic-expression": "Response topic expression", + "value-expression": "Value expression", + "topic": "Topic", + "timeout": "Timeout in milliseconds", + "converter-json-required": "Converter json is required.", + "converter-json-parse": "Unable to parse converter json.", + "filter-expression": "Filter expression", + "connect-requests": "Connect requests", + "add-connect-request": "Add connect request", + "disconnect-requests": "Disconnect requests", + "add-disconnect-request": "Add disconnect request", + "attribute-requests": "Attribute requests", + "add-attribute-request": "Add attribute request", + "attribute-updates": "Attribute updates", + "add-attribute-update": "Add attribute update", + "server-side-rpc": "Server side RPC", + "add-server-side-rpc-request": "Add server-side RPC request", + "device-name-filter": "Device name filter", + "attribute-filter": "Attribute filter", + "method-filter": "Method filter", + "request-topic-expression": "Request topic expression", + "response-timeout": "Response timeout in milliseconds", + "topic-expression": "Topic expression", + "client-scope": "Client scope", + "add-device": "Add device", + "opc-server": "Servers", + "opc-add-server": "Add server", + "opc-add-server-prompt": "Please add server", + "opc-application-name": "Application name", + "opc-application-uri": "Application uri", + "opc-scan-period-in-seconds": "Scan period in seconds", + "opc-security": "Security", + "opc-identity": "Identity", + "opc-keystore": "Keystore", + "opc-type": "Type", + "opc-keystore-type": "Type", + "opc-keystore-location": "Location *", + "opc-keystore-password": "Password", + "opc-keystore-alias": "Alias", + "opc-keystore-key-password": "Key password", + "opc-device-node-pattern": "Device node pattern", + "opc-device-name-pattern": "Device name pattern", + "modbus-server": "Servers/slaves", + "modbus-add-server": "Add server/slave", + "modbus-add-server-prompt": "Please add server/slave", + "modbus-transport": "Transport", + "modbus-port-name": "Serial port name", + "modbus-encoding": "Encoding", + "modbus-parity": "Parity", + "modbus-baudrate": "Baud rate", + "modbus-databits": "Data bits", + "modbus-stopbits": "Stop bits", + "modbus-databits-range": "Data bits should be in a range from 7 to 8.", + "modbus-stopbits-range": "Stop bits should be in a range from 1 to 2.", + "modbus-unit-id": "Unit ID", + "modbus-unit-id-range": "Unit ID should be in a range from 1 to 247.", + "modbus-device-name": "Device name", + "modbus-poll-period": "Poll period (ms)", + "modbus-attributes-poll-period": "Attributes poll period (ms)", + "modbus-timeseries-poll-period": "Timeseries poll period (ms)", + "modbus-poll-period-range": "Poll period should be positive value.", + "modbus-tag": "Tag", + "modbus-function": "Function", + "modbus-register-address": "Register address", + "modbus-register-address-range": "Register address should be in a range from 0 to 65535.", + "modbus-register-bit-index": "Bit index", + "modbus-register-bit-index-range": "Bit index should be in a range from 0 to 15.", + "modbus-register-count": "Register count", + "modbus-register-count-range": "Register count should be a positive value.", + "modbus-byte-order": "Byte order", + + "sync": { + "status": "Status", + "sync": "Sync", + "not-sync": "Not sync", + "last-sync-time": "Last sync time", + "not-available": "Not available" + }, + + "export-extensions-configuration": "Export extensions configuration", + "import-extensions-configuration": "Import extensions configuration", + "import-extensions": "Import extensions", + "import-extension": "Import extension", + "export-extension": "Export extension", + "file": "Extensions file", + "invalid-file-error": "Invalid extension file" + }, + "fullscreen": { + "expand": "Expandir a Pantalla Completa", + "exit": "Salir de Pantalla Completa", + "toggle": "Cambiar el modo de Pantalla Completa", + "fullscreen": "Pantalla Completa" + }, + "function": { + "function": "Función" + }, + "grid": { + "delete-item-title": "¿Estás seguro que quieres eliminar este item?", + "delete-item-text": "Ten cuidado, luego de confirmar el item será eliminado y la información relacionada será irrecuperable.", + "delete-items-title": "¿Estás seguro que quieres eliminar { count, plural, 1 {1 item} other {# items} }?", + "delete-items-action-title": "Eliminar { count, plural, 1 {1 item} other {# items} }", + "delete-items-text": "Ten cuidado, luego de confirmar los items seleccionados serán eliminados y la información relacionada será irrecuperable.", + "add-item-text": "Agregar nuevo item", + "no-items-text": "Ningún item encontrado", + "item-details": "Detalles del item", + "delete-item": "Borrar Item", + "delete-items": "Borrar Items", + "scroll-to-top": "Ir hacia arriba" + }, + "help": { + "goto-help-page": "Ir a Página de Ayuda" + }, + "home": { + "home": "Principal", + "profile": "Perfil", + "logout": "Salir", + "menu": "Menu", + "avatar": "Avatar", + "open-user-menu": "Abrir menú de usuario" + }, + "import": { + "no-file": "Ningún archivo seleccionado", + "drop-file": "Arrastra un archivo JSON o clickea para seleccionar uno." + }, + "item": { + "selected": "Seleccionado" + }, + "js-func": { + "no-return-error": "La función debe retornar un valor!", + "return-type-mismatch": "La función debe retornar un valor de tipo: '{{type}}'!" + }, + "key-val": { + "key": "Key", + "value": "Value", + "remove-entry": "Remove entry", + "add-entry": "Add entry", + "no-data": "No entries" + }, + "layout": { + "layout": "Layout", + "manage": "Manage layouts", + "settings": "Layout settings", + "color": "Color", + "main": "Main", + "right": "Right", + "select": "Select target layout" + }, + "legend": { + "position": "Posición de leyenda", + "show-max": "Mostrar máximo", + "show-min": "Mostrar mínimo", + "show-avg": "Mostrar promedio", + "show-total": "Mostrar total", + "settings": "Ajustes de leyenda.", + "min": "min", + "max": "max", + "avg": "prom", + "total": "total" + }, + "login": { + "login": "Ingresar", + "request-password-reset": "Pedir restablecer contraseña", + "reset-password": "Restablecer contraseña", + "create-password": "Crear contraseña", + "passwords-mismatch-error": "Las contraseñas deben ser las mismas!", + "password-again": "Reingresa la contraseña", + "sign-in": "Iniciar sesión", + "username": "Usuario (email)", + "remember-me": "Recordar", + "forgot-password": "¿Olvidaste tu contraseña?", + "password-reset": "Restablecer Contraseña", + "new-password": "Nueva contraseña", + "new-password-again": "Repita la nueva contraseña", + "password-link-sent-message": "Se ha enviado el enlace de restablecimiento de contraseña con éxito!", + "email": "Email" + }, + "position": { + "top": "Arriba", + "bottom": "Abajo", + "left": "Izquierda", + "right": "Derecha" + }, + "profile": { + "profile": "Perfil", + "change-password": "Cambiar contraseña", + "current-password": "Contraseña actual" + }, + "relation": { + "relations": "Relations", + "direction": "Direction", + "search-direction": { + "FROM": "From", + "TO": "To" + }, + "direction-type": { + "FROM": "from", + "TO": "to" + }, + "from-relations": "Outbound relations", + "to-relations": "Inbound relations", + "selected-relations": "{ count, plural, 1 {1 relation} other {# relations} } selected", + "type": "Type", + "to-entity-type": "To entity type", + "to-entity-name": "To entity name", + "from-entity-type": "From entity type", + "from-entity-name": "From entity name", + "to-entity": "To entity", + "from-entity": "From entity", + "delete": "Delete relation", + "relation-type": "Relation type", + "relation-type-required": "Relation type is required.", + "any-relation-type": "Any type", + "add": "Add relation", + "edit": "Edit relation", + "delete-to-relation-title": "Are you sure you want to delete relation to the entity '{{entityName}}'?", + "delete-to-relation-text": "Be careful, after the confirmation the entity '{{entityName}}' will be unrelated from the current entity.", + "delete-to-relations-title": "Are you sure you want to delete { count, plural, 1 {1 relation} other {# relations} }?", + "delete-to-relations-text": "Be careful, after the confirmation all selected relations will be removed and corresponding entities will be unrelated from the current entity.", + "delete-from-relation-title": "Are you sure you want to delete relation from the entity '{{entityName}}'?", + "delete-from-relation-text": "Be careful, after the confirmation current entity will be unrelated from the entity '{{entityName}}'.", + "delete-from-relations-title": "Are you sure you want to delete { count, plural, 1 {1 relation} other {# relations} }?", + "delete-from-relations-text": "Be careful, after the confirmation all selected relations will be removed and current entity will be unrelated from the corresponding entities.", + "remove-relation-filter": "Remove relation filter", + "add-relation-filter": "Add relation filter", + "any-relation": "Any relation", + "relation-filters": "Relation filters", + "additional-info": "Additional info (JSON)", + "invalid-additional-info": "Unable to parse additional info json." + }, + "rulechain": { + "rulechain": "Rule chain", + "rulechains": "Rule chains", + "root": "Root", + "delete": "Delete rule chain", + "name": "Name", + "name-required": "Name is required.", + "description": "Description", + "add": "Add Rule Chain", + "set-root": "Make rule chain root", + "set-root-rulechain-title": "Are you sure you want to make the rule chain '{{ruleChainName}}' root?", + "set-root-rulechain-text": "After the confirmation the rule chain will become root and will handle all incoming transport messages.", + "delete-rulechain-title": "Are you sure you want to delete the rule chain '{{ruleChainName}}'?", + "delete-rulechain-text": "Be careful, after the confirmation the rule chain and all related data will become unrecoverable.", + "delete-rulechains-title": "Are you sure you want to delete { count, plural, 1 {1 rule chain} other {# rule chains} }?", + "delete-rulechains-action-title": "Delete { count, plural, 1 {1 rule chain} other {# rule chains} }", + "delete-rulechains-text": "Be careful, after the confirmation all selected rule chains will be removed and all related data will become unrecoverable.", + "add-rulechain-text": "Add new rule chain", + "no-rulechains-text": "No rule chains found", + "rulechain-details": "Rule chain details", + "details": "Details", + "events": "Events", + "system": "System", + "import": "Import rule chain", + "export": "Export rule chain", + "export-failed-error": "Unable to export rule chain: {{error}}", + "create-new-rulechain": "Create new rule chain", + "rulechain-file": "Rule chain file", + "invalid-rulechain-file-error": "Unable to import rule chain: Invalid rule chain data structure.", + "copyId": "Copy rule chain Id", + "idCopiedMessage": "Rule chain Id has been copied to clipboard", + "select-rulechain": "Select rule chain", + "no-rulechains-matching": "No rule chains matching '{{entity}}' were found.", + "rulechain-required": "Rule chain is required", + "management": "Rules management", + "debug-mode": "Debug mode" + }, + "rulenode": { + "details": "Details", + "events": "Events", + "search": "Search nodes", + "open-node-library": "Open node library", + "add": "Add rule node", + "name": "Name", + "name-required": "Name is required.", + "type": "Type", + "description": "Description", + "delete": "Delete rule node", + "select-all-objects": "Select all nodes and connections", + "deselect-all-objects": "Deselect all nodes and connections", + "delete-selected-objects": "Delete selected nodes and connections", + "delete-selected": "Delete selected", + "select-all": "Select all", + "copy-selected": "Copy selected", + "deselect-all": "Deselect all", + "rulenode-details": "Rule node details", + "debug-mode": "Debug mode", + "configuration": "Configuration", + "link": "Link", + "link-details": "Rule node link details", + "add-link": "Add link", + "link-label": "Link label", + "link-label-required": "Link label is required.", + "custom-link-label": "Custom link label", + "custom-link-label-required": "Custom link label is required.", + "type-filter": "Filter", + "type-filter-details": "Filter incoming messages with configured conditions", + "type-enrichment": "Enrichment", + "type-enrichment-details": "Add additional information into Message Metadata", + "type-transformation": "Transformation", + "type-transformation-details": "Change Message payload and Metadata", + "type-action": "Action", + "type-action-details": "Perform special action", + "type-external": "External", + "type-external-details": "Interacts with external system", + "type-rule-chain": "Rule Chain", + "type-rule-chain-details": "Forwards incoming messages to specified Rule Chain", + "type-input": "Input", + "type-input-details": "Logical input of Rule Chain, forwards incoming messages to next related Rule Node", + "directive-is-not-loaded": "Defined configuration directive '{{directiveName}}' is not available.", + "ui-resources-load-error": "Failed to load configuration ui resources.", + "invalid-target-rulechain": "Unable to resolve target rule chain!", + "test-script-function": "Test script function", + "message": "Message", + "message-type": "Message type", + "message-type-required": "Message type is required", + "metadata": "Metadata", + "metadata-required": "Metadata entries can't be empty.", + "output": "Output", + "test": "Test", + "help": "Help" + }, + "tenant": { + "tenants": "Tenants", + "management": "Gestión de Tenant", + "add": "Agregar Tenant", + "admins": "Admins", + "manage-tenant-admins": "Gestionar administradores tenant", + "delete": "Eliminar tenant", + "add-tenant-text": "Agregar nuevo tenant", + "no-tenants-text": "Ningún tenant encontrado", + "tenant-details": "Detalles del Tenant", + "delete-tenant-title": "¿Estás seguro que quieres eliminar el tenant '{{tenantTitle}}'?", + "delete-tenant-text": "Ten cuidado, luego de confirmar el tenant será eliminado y la información relacionada será irrecuperable.", + "delete-tenants-title": "¿Estás seguro que quieres eliminar { count, plural, 1 {1 tenant} other {# tenants} }?", + "delete-tenants-action-title": "Eliminar { count, plural, 1 {1 tenant} other {# tenants} }", + "delete-tenants-text": "Ten cuidado, luego de confirmar los tenants seleccionados serán eliminados y la información relacionada será irrecuperable.", + "title": "Título", + "title-required": "Título requerido.", + "description": "Descripción" + }, + "timeinterval": { + "seconds-interval": "{ seconds, plural, 1 {1 segundo} other {# segundos} }", + "minutes-interval": "{ minutes, plural, 1 {1 minuto} other {# minutos} }", + "hours-interval": "{ hours, plural, 1 {1 hora} other {# horas} }", + "days-interval": "{ days, plural, 1 {1 día} other {# días} }", + "days": "Días", + "hours": "Horas", + "minutes": "Minutos", + "seconds": "Segundos", + "advanced": "Avanzado" + }, + "timewindow": { + "days": "{ days, plural, 1 { día } other {# días } }", + "hours": "{ hours, plural, 0 { horas } 1 {1 hora } other {# horas } }", + "minutes": "{ minutes, plural, 0 { minutos } 1 {1 minuto } other {# minutos } }", + "seconds": "{ seconds, plural, 0 { segundos } 1 {1 segundo } other {# segundos } }", + "realtime": "Tiempo-real", + "history": "Histórico", + "last-prefix": "último", + "period": "desde {{ startTime }} hasta {{ endTime }}", + "edit": "Editar ventana de tiempo", + "date-range": "Rango de fechas", + "last": "Últimos", + "time-period": "Período de tiempo" + }, + "user": { + "users": "Usuarios", + "customer-users": "Usuarios del Cliente", + "tenant-admins": "Tenant Admins", + "sys-admin": "Administrador del Sistema", + "tenant-admin": "Administrador Tenant", + "customer": "Cliente", + "anonymous": "Anónimo", + "add": "Agregar usuario", + "delete": "Eliminar usuario", + "add-user-text": "Agregar nuevo usuario", + "no-users-text": "Ningún usuario encontrado", + "user-details": "Detalles del usuario", + "delete-user-title": "¿Estás seguro que quieres eliminar el usuario '{{userEmail}}'?", + "delete-user-text": "Ten cuidado, luego de confirmar el usuario seleccionado será eliminado y la información relacionada será irrecuperable.", + "delete-users-title": "¿Estás seguro que quieres eliminar { count, plural, 1 {1 usuario} other {# usuarios} }?", + "delete-users-action-title": "Borrar { count, plural, 1 {1 usuario} other {# usuarios} }", + "delete-users-text": "Ten cuidado, luego de confirmar los usuarios seleccionados serán eliminados y la información relacionada será irrecuperable.", + "activation-email-sent-message": "Mail de activación enviado con éxito!", + "resend-activation": "Reenviar activación", + "email": "Email", + "email-required": "Email requerido.", + "first-name": "Nombre", + "last-name": "Apellido", + "description": "Descripción", + "default-dashboard": "Panel por defecto", + "always-fullscreen": "Siempre en pantalla completa" + }, + "value": { + "type": "Tipo de valor", + "string": "Cadena de texto", + "string-value": "Valor de cadena de texto", + "integer": "Nro entero", + "integer-value": "Valor de nro entero", + "invalid-integer-value": "Valor inválido", + "double": "Nro decimal", + "double-value": "Valor nro decimal", + "boolean": "Booleano", + "boolean-value": "Valor booleano", + "false": "Falso", + "true": "Verdadero" + }, + "widget": { + "widget-library": "Bibloteca de Widgets", + "widget-bundle": "Paquetes de Widgets", + "select-widgets-bundle": "Seleccionar paquete de widgets", + "management": "Gestión de Widgets", + "editor": "Editor de widgets", + "widget-type-not-found": "Problema al cargar la configuración del widget.
Probablemente asociado\n El tipo de widget fue eliminado.", + "widget-type-load-error": "Widget no pudo ser cargado debido a estos errores:", + "remove": "Eliminar widget", + "edit": "Editar widget", + "remove-widget-title": "¿Estás seguro que quieres eliminar el widget '{{widgetTitle}}'?", + "remove-widget-text": "Luego de confirmar el widget será eliminado y toda la información relacionada será irrecuperable..", + "timeseries": "Series de tiempo", + "latest-values": "Últimos valores", + "rpc": "Widget de control", + "static": "Widget estático", + "select-widget-type": "Seleccionar tipo de widget", + "missing-widget-title-error": "El titulo del widget debe ser especificado!", + "widget-saved": "Widget guardado", + "unable-to-save-widget-error": "Imposible guardar widget! Tiene errores!", + "save": "Guardar widget", + "saveAs": "Guardar widget como", + "save-widget-type-as": "Guardar tipo de widget como", + "save-widget-type-as-text": "Por favor, ingrese un nuevo titulo y/o seleccione un paquete de destino.", + "toggle-fullscreen": "Cambiar a pantalla completa", + "run": "Correr widget", + "title": "Titulo", + "title-required": "Titulo requerido.", + "type": "Tipo", + "resources": "Recursos", + "resource-url": "JavaScript/CSS URL", + "remove-resource": "Eliminar recurso", + "add-resource": "Agregar recurso", + "html": "HTML", + "tidy": "Tidy", + "css": "CSS", + "settings-schema": "Esquema de configuración", + "datakey-settings-schema": "Esquema de configuración de clave de datos", + "javascript": "Javascript", + "remove-widget-type-title": "¿Estás seguro que quieres eliminar el tipo del widget '{{widgetName}}'?", + "remove-widget-type-text": "Luego de confirmar el tipo será eliminado y la información relacionada será irrecuperable.", + "remove-widget-type": "Eliminar tipo de widget.", + "add-widget-type": "Agregar nuevo tipo de widget", + "widget-type-load-failed-error": "Error al cargar el tipo de widget!", + "widget-template-load-failed-error": "Error al cargar el template del widget!", + "add": "Agregar Widget", + "undo": "Deshacer cambios", + "export": "Exportar widget" + }, + "widget-action": { + "header-button": "Widget header button", + "open-dashboard-state": "Navigate to new dashboard state", + "update-dashboard-state": "Update current dashboard state", + "open-dashboard": "Navigate to other dashboard", + "custom": "Custom action", + "target-dashboard-state": "Target dashboard state", + "target-dashboard-state-required": "Target dashboard state is required", + "set-entity-from-widget": "Set entity from widget", + "target-dashboard": "Target dashboard", + "open-right-layout": "Open right dashboard layout (mobile view)" + }, + "widgets-bundle": { + "current": "Paquete actual", + "widgets-bundles": "Paquete de Widgets", + "add": "Agregar paquete de widgets", + "delete": "Eliminar paquete de widgets", + "title": "Título", + "title-required": "Título requerido.", + "add-widgets-bundle-text": "Agregar nuevo paquete de widgets", + "no-widgets-bundles-text": "Ningún paquete de widgets encontrado", + "empty": "Paquete de widgets vacío.", + "details": "Detalles", + "widgets-bundle-details": "Detalles del paquete de Widgets", + "delete-widgets-bundle-title": "¿Estás seguro que desea eliminar el paquete de widgets '{{widgetsBundleTitle}}'?", + "delete-widgets-bundle-text": "Ten cuidado, luego de confirmar todos los paquetes seleccionados serán eliminados y su información relacionada será irrecuperable.", + "delete-widgets-bundles-title": "¿Estás seguro que deseas eliminar { count, plural, 1 {1 paquete de widgets} other {# paquetes de widgets} }?", + "delete-widgets-bundles-action-title": "Eliminar { count, plural, 1 {1 paquete de widgets} other {# paquetes de widgets} }", + "delete-widgets-bundles-text": "Ten cuidado, luego de confirmar todos los paquetes seleccionados serán eliminados y la información relacionada será irrecuperable.", + "no-widgets-bundles-matching": "Ningún paquete '{{widgetsBundle}}' encontrado.", + "widgets-bundle-required": "Paquete de widget requerido.", + "system": "Sistema", + "import": "Importar paquete de widgets", + "export": "Exportar paquete de widgets", + "export-failed-error": "Imposible exportar paquete de widgets: {{error}}", + "create-new-widgets-bundle": "Crear nuevo paquete de widgets", + "widgets-bundle-file": "Archivo de paquete de widgets", + "invalid-widgets-bundle-file-error": "Imposible importar paquete de widgets: Estructura de datos inválida." + }, + "widget-config": { + "data": "Datos", + "settings": "Ajustes", + "advanced": "Avanzado", + "title": "Titulo", + "general-settings": "Ajustes generales", + "display-title": "Mostrar titulo", + "drop-shadow": "Sombra", + "enable-fullscreen": "Habilitar pantalla completa", + "background-color": "Color de fondo", + "text-color": "Color del texto", + "padding": "Relleno", + "title-style": "Estilo de título", + "mobile-mode-settings": "Ajustes mobile.", + "order": "Orden", + "height": "Altura", + "units": "Caracter especial a mostrar en el siguiente valor", + "decimals": "Números de dígitos después de la coma", + "timewindow": "Ventana de tiempo", + "use-dashboard-timewindow": "Usar ventana de tiempo del Panel", + "display-legend": "Mostrar leyenda", + "datasources": "Set de datos", + "datasource-type": "Tipo", + "datasource-parameters": "Parámetros", + "remove-datasource": "Eliminar set de datos", + "add-datasource": "Agregar set de datos", + "target-device": "Dispositivo destino" + }, + "widget-type": { + "import": "Importar tipo de widget", + "export": "Exportar tipo de widget", + "export-failed-error": "Imposible exportar tipo de widget: {{error}}", + "create-new-widget-type": "Crear nuevo tipo de widget", + "widget-type-file": "Tipo de archivo del widget", + "invalid-widget-type-file-error": "Imposible de importar tipo de widget: Estructura de datos inválida." + }, + "icon": { + "icon": "Icon", + "select-icon": "Select icon", + "material-icons": "Material icons", + "show-all": "Show all icons" + }, + "custom": { + "widget-action": { + "action-cell-button": "Action cell button", + "row-click": "On row click", + "marker-click": "On marker click", + "tooltip-tag-action": "Tooltip tag action" + } + }, + "language": { + "language": "Lenguaje", + "locales": { + "en_US": "Inglés", + "ko_KR": "Coreano", + "zh_CN": "Chino", + "ru_RU": "Ruso", + "es_ES": "Español", + "it_IT": "Italiano" + } + } +} \ No newline at end of file diff --git a/ui/src/app/locale/locale.constant-it_IT.json b/ui/src/app/locale/locale.constant-it_IT.json new file mode 100644 index 0000000000..1454d36a1b --- /dev/null +++ b/ui/src/app/locale/locale.constant-it_IT.json @@ -0,0 +1,1445 @@ +{ + "access": { + "unauthorized": "Non autorizzato", + "unauthorized-access": "Accesso non autorizzato", + "unauthorized-access-text": "Devi effettuare il login per accedere a questa risorsa!", + "access-forbidden": "Accesso Vietato", + "access-forbidden-text": "Non hai i diritti di accesso a questa posizione!
Prova ad effettuare il login con un diverso account.", + "refresh-token-expired": "Sessione scaduta", + "refresh-token-failed": "Impossibile aggiornare la sessione" + }, + "action": { + "activate": "Attiva", + "suspend": "Sospendi", + "save": "Salva", + "saveAs": "Salva come", + "cancel": "Cancella", + "ok": "OK", + "delete": "Elimina", + "add": "Aggiungi", + "yes": "Sì", + "no": "No", + "update": "Aggiorna", + "remove": "Rimuovi", + "search": "Cerca", + "clear-search": "Cancella ricerca", + "assign": "Assegna", + "unassign": "Annulla assegnazione", + "share": "Condividi", + "make-private": "Rendi privato", + "apply": "Applica", + "apply-changes": "Applica modifiche", + "edit-mode": "Modalità modifica", + "enter-edit-mode": "Attiva la modalità di modifica", + "decline-changes": "Annulla le modifiche", + "close": "Chiudi", + "back": "Indietro", + "run": "Esegui", + "sign-in": "Registrati!", + "edit": "Modifica", + "view": "Visualizza", + "create": "Crea", + "drag": "Trascina", + "refresh": "Aggiorna", + "undo": "Annulla", + "copy": "Copia", + "paste": "Incolla", + "copy-reference": "Copia riferimento", + "paste-reference": "Incolla riferimento", + "import": "Importa", + "export": "Esporta", + "share-via": "Condividi con {{provider}}" + }, + "aggregation": { + "aggregation": "Aggregazione", + "function": "Funzione di aggregazione dei dati", + "limit": "Valori max", + "group-interval": "Intervallo di raggruppamento", + "min": "Min", + "max": "Max", + "avg": "Media", + "sum": "Somma", + "count": "Conteggio", + "none": "Nessuna" + }, + "admin": { + "general": "Generale", + "general-settings": "Impostazioni Generali", + "outgoing-mail": "Posta in uscita", + "outgoing-mail-settings": "Impostazioni Posta in uscita", + "system-settings": "Impostazioni di sistema", + "test-mail-sent": "Mail di test inviata con successo!", + "base-url": "URL di base", + "base-url-required": "URL di base obbligatoria.", + "mail-from": "Mittente", + "mail-from-required": "Mittente obbligatorio.", + "smtp-protocol": "Protocollo SMTP", + "smtp-host": "Host SMTP", + "smtp-host-required": "Host SMTP obbligatorio.", + "smtp-port": "Porta SMTP", + "smtp-port-required": "Porta SMTP obbligatoria.", + "smtp-port-invalid": "Numero di porta SMTP non valido.", + "timeout-msec": "Timeout (msec)", + "timeout-required": "Timeout obbligatorio.", + "timeout-invalid": "Timeout non valido.", + "enable-tls": "Abilita TLS", + "send-test-mail": "Invia mail di test" + }, + "alarm": { + "alarm": "Allarme", + "alarms": "Allarmi", + "select-alarm": "Seleziona un allarme", + "no-alarms-matching": "Nessun allarme corrispondente a '{{entity}}' è stato trovato.", + "alarm-required": "Allarme richiesto", + "alarm-status": "Stato Allarme", + "search-status": { + "ANY": "Qualsiasi", + "ACTIVE": "Attivo", + "CLEARED": "Cancellato", + "ACK": "Riconosciuto", + "UNACK": "Non riconosciuto" + }, + "display-status": { + "ACTIVE_UNACK": "Active Unacknowledged", + "ACTIVE_ACK": "Active Acknowledged", + "CLEARED_UNACK": "Cleared Unacknowledged", + "CLEARED_ACK": "Cleared Acknowledged" + }, + "no-alarms-prompt": "Nessun allarme trovato", + "created-time": "Orario di creazione", + "type": "Tipo", + "severity": "Gravità", + "originator": "Origine", + "originator-type": "Tipo origine", + "details": "Dettagli", + "status": "Stato", + "alarm-details": "Dettagli allarme", + "start-time": "Orario inizio", + "end-time": "Orario fine", + "ack-time": "Orario conferma", + "clear-time": "Orario cancellazione", + "severity-critical": "Critico", + "severity-major": "Maggiore", + "severity-minor": "Minore", + "severity-warning": "Avviso", + "severity-indeterminate": "Indeterminato", + "acknowledge": "Conferma", + "clear": "Cancella", + "search": "Ricerca allarmi", + "selected-alarms": "{ count, plural, 1 {1 allarme selezionato} other {# allarmi selezionati} }", + "no-data": "Nessun dato da visualizzare", + "polling-interval": "Intervallo di polling (sec) Allarmi", + "polling-interval-required": "Intervallo di polling Allarmi richiesto.", + "min-polling-interval-message": "L'intervallo di polling deve essere di almeno 1 sec.", + "aknowledge-alarms-title": "Conferma { count, plural, 1 {1 allarme} other {# allarmi} }", + "aknowledge-alarms-text": "Sei sicuro di voler confermare { count, plural, 1 {1 allarme} other {# allarmi} }?", + "clear-alarms-title": "Elimina { count, plural, 1 {1 allarme} other {# allarmi} }", + "clear-alarms-text": "Sei sicuro di voler eliminare { count, plural, 1 {1 allarme} other {# allarmi} }?" + }, + "alias": { + "add": "Aggiungi alias", + "edit": "Modifica alias", + "name": "Nome Alias", + "name-required": "Nome Alias obbligatorio", + "duplicate-alias": "Un Alias con lo stesso nome è già presente.", + "filter-type-single-entity": "Singola entità", + "filter-type-entity-list": "Lista Entità", + "filter-type-entity-name": "Nome Entità", + "filter-type-state-entity": "Entity from dashboard state", + "filter-type-state-entity-description": "Entità prelevata dai parametri di stato della dashboard", + "filter-type-asset-type": "Tipo di Asset", + "filter-type-asset-type-description": "Asset di tipo '{{assetType}}'", + "filter-type-asset-type-and-name-description": "Asset di tipo '{{assetType}}' e con un nome che inizia per '{{prefix}}'", + "filter-type-device-type": "Tipo di dispositivo", + "filter-type-device-type-description": "Dispositivi di tipo '{{deviceType}}'", + "filter-type-device-type-and-name-description": "Dispositivi di tipo '{{deviceType}}' e con un nome che inizia per '{{prefix}}'", + "filter-type-relations-query": "Relations query", + "filter-type-relations-query-description": "{{entities}} that have {{relationType}} relation {{direction}} {{rootEntity}}", + "filter-type-asset-search-query": "Asset search query", + "filter-type-asset-search-query-description": "Assets with types {{assetTypes}} that have {{relationType}} relation {{direction}} {{rootEntity}}", + "filter-type-device-search-query": "Device search query", + "filter-type-device-search-query-description": "Devices with types {{deviceTypes}} that have {{relationType}} relation {{direction}} {{rootEntity}}", + "entity-filter": "Filtro entità", + "resolve-multiple": "Resolve as multiple entities", + "filter-type": "Tipo di filtro", + "filter-type-required": "Tipo di filtro richiesto.", + "entity-filter-no-entity-matched": "Nessuna entità corrispondente al filtro specificato è stata trovata.", + "no-entity-filter-specified": "Nessun filtro di entità specificato", + "root-state-entity": "Use dashboard state entity as root", + "root-entity": "Entità radice", + "state-entity-parameter-name": "State entity parameter name", + "default-state-entity": "Default state entity", + "default-entity-parameter-name": "By default", + "max-relation-level": "Max relation level", + "unlimited-level": "Unlimited level", + "state-entity": "Dashboard state entity", + "all-entities": "Tutte le entità", + "any-relation": "qualsiasi" + }, + "asset": { + "asset": "Asset", + "assets": "Asset", + "management": "Gestione Asset", + "view-assets": "Visualizza Asset", + "add": "Aggiungi Asset", + "assign-to-customer": "Assegna a cliente", + "assign-asset-to-customer": "Assegna Asset al Cliente", + "assign-asset-to-customer-text": "Seleziona gli asset da assegnare al cliente", + "no-assets-text": "Nessun asset trovato", + "assign-to-customer-text": "Seleziona il cliente a cui assegnare l'asset / gli asset", + "public": "Pubblico", + "assignedToCustomer": "Assegnato al cliente", + "make-public": "Rendi pubblico l'asset", + "make-private": "Rendi privato l'asset", + "unassign-from-customer": "Assegnazione annullata dal cliente", + "delete": "Cancella asset", + "asset-public": "L'Asset è pubblico", + "asset-type": "Tipo di Asset", + "asset-type-required": "Tipo di Asset richiesto.", + "select-asset-type": "Seleziona tipo di asset", + "enter-asset-type": "Inserisci tipo di asset", + "any-asset": "Qualsiasi asset", + "no-asset-types-matching": "Nessun asset corrispondente al tipo '{{entitySubtype}}' è stato trovato.", + "asset-type-list-empty": "Nessun tipo di asset selezionato.", + "asset-types": "Tipi di Asset", + "name": "Nome", + "name-required": "Nome obbligatorio.", + "description": "Descrizione", + "type": "Tipo", + "type-required": "Tipo obbligatorio.", + "details": "Dettagli", + "events": "Eventi", + "add-asset-text": "Aggiungi un nuovo asset", + "asset-details": "Dettagli Asset", + "assign-assets": "Assegna asset", + "assign-assets-text": "Assegna { count, plural, 1 {1 asset} other {# assets} } al cliente", + "delete-assets": "Cancella asset", + "unassign-assets": "Annulla assegnazione asset", + "unassign-assets-action-title": "Unassign { count, plural, 1 {1 asset} other {# assets} } from customer", + "assign-new-asset": "Assegna un nuovo asset", + "delete-asset-title": "Sei sicuro di voler cancellare l'asset '{{assetName}}'?", + "delete-asset-text": "Attenzione, dopo la conferma l'asset e tutti i relativi dati non saranno più recuperabili.", + "delete-assets-title": "Sei sicuro di voler eliminare { count, plural, 1 {1 asset} other {# asset} }?", + "delete-assets-action-title": "Elimina { count, plural, 1 {1 asset} other {# asset} }", + "delete-assets-text": "Attenzione, dopo la modifica tutti gli asset selezionati saranno rimossi e tutti i relativi dati non saranno più recuperabili.", + "make-public-asset-title": "Sei sicuro di voler rendere pubblico l'asset '{{assetName}}'?", + "make-public-asset-text": "Dopo la conferma l'asset e tutti i suoi dati saranno resi pubblici e accessibili dagli altri.", + "make-private-asset-title": "Sei sicuro di voler rendere privato l'asset '{{assetName}}'?", + "make-private-asset-text": "Dopo la conferma l'asset e tutti i suoi dati saranno resi privati e non accessibili dagli altri.", + "unassign-asset-title": "Sei sicuro di voler annullare l'assegnazione dell'asset '{{assetName}}'?", + "unassign-asset-text": "Dopo la conferma l'assegnazione dell'asset sarà annullata e l'asset non sarà più accessibile dal cliente.", + "unassign-asset": "Annulla assegnazione asset", + "unassign-assets-title": "Sei sicuro di voler annullare l'assegnazione di { count, plural, 1 {1 asset} other {# asset} }?", + "unassign-assets-text": "Dopo la conferma sarà annullata l'assegnazione di tutti gli asset selezionati e questi non saranno più accessibili dal cliente.", + "copyId": "Copia Id asset", + "idCopiedMessage": "Id Asset copiato negli Appunti", + "select-asset": "Seleziona asset", + "no-assets-matching": "Nessun asset corrispondente a '{{entity}}' é stato trovato.", + "asset-required": "Asset obbligatorio", + "name-starts-with": "Asset con nome che inizia per" + }, + "attribute": { + "attributes": "Attributi", + "latest-telemetry": "Ultima telemetria", + "attributes-scope": "Entity attributes scope", + "scope-latest-telemetry": "Ultima telemetria", + "scope-client": "Attributi client", + "scope-server": "Attributi server", + "scope-shared": "Attributi condivisi", + "add": "Aggiungi attributo", + "key": "Chiave", + "last-update-time": "Ultimo aggiornamento", + "key-required": "Attributo chiave richiesto.", + "value": "Valore", + "value-required": "Attributo valore richiesto.", + "delete-attributes-title": "Sei sicuro di voler eliminare { count, plural, 1 {1 attributo} other {# attributi} }?", + "delete-attributes-text": "Attenzione, dopo la conferma tutti gli attributi selezionati saranno rimossi.", + "delete-attributes": "Elimina attributi", + "enter-attribute-value": "Inserisci il valore dell'attributo", + "show-on-widget": "Mostra sul widget", + "widget-mode": "Modalità Widget", + "next-widget": "Widget successivo", + "prev-widget": "Widget precedente", + "add-to-dashboard": "Aggiungi alla dashboard", + "add-widget-to-dashboard": "Aggiungi widget alla dashboard", + "selected-attributes": "{ count, plural, 1 {1 attributo selezionato} other {# attributi selezionati} }", + "selected-telemetry": "{ count, plural, 1 {1 unità di telemetria selezionata} other {# unità di telemetria selezionate} }" + }, + "audit-log": { + "audit": "Audit", + "audit-logs": "Audit Logs", + "timestamp": "Timestamp", + "entity-type": "Tipo Entità", + "entity-name": "Nome Entità", + "user": "Utente", + "type": "Tipo", + "status": "Stato", + "details": "Dettagli", + "type-added": "Aggiunto", + "type-deleted": "Eliminato", + "type-updated": "Aggiornato", + "type-attributes-updated": "Attributi aggiornati", + "type-attributes-deleted": "Attributi eliminati", + "type-rpc-call": "Chiamata RPC", + "type-credentials-updated": "Credenziali aggiornate", + "type-assigned-to-customer": "Assegnato al Cliente", + "type-unassigned-from-customer": "Assegnazione annullata dal Cliente", + "type-activated": "Attivato", + "type-suspended": "Sospeso", + "type-credentials-read": "Credenziali lette", + "type-attributes-read": "Attributi letti", + "status-success": "Success", + "status-failure": "Failure", + "audit-log-details": "Dettaglio log audit", + "no-audit-logs-prompt": "Log non trovati", + "action-data": "Action data", + "failure-details": "Failure details", + "search": "Riceraca log audit", + "clear-search": "Cancella ricerca" + }, + "confirm-on-exit": { + "message": "Alcune modifiche non sono state salvate. Sei sicuro di voler abbandonare questa pagina?", + "html-message": "Alcune modifiche non sono state salvate.
Sei sicuro di voler abbandonare questa pagina?", + "title": "Modifiche non salvate" + }, + "contact": { + "country": "Nazione", + "city": "Città", + "state": "Stato / Provincia", + "postal-code": "CAP", + "postal-code-invalid": "Formato CAP non valido.", + "address": "Indirizzo", + "address2": "Indirizzo 2", + "phone": "Telefono", + "email": "Email", + "no-address": "Nessun indirizzo" + }, + "common": { + "username": "Nome utente", + "password": "Password", + "enter-username": "Inserisci nome utente", + "enter-password": "Inserisci password", + "enter-search": "Enter search" + }, + "content-type": { + "json": "Json", + "text": "Testo", + "binary": "Binario (Base64)" + }, + "customer": { + "customer": "Cliente", + "customers": "Clienti", + "management": "Gestione cliente", + "dashboard": "Dashboard cliente", + "dashboards": "Dashboard cliente", + "devices": "Dispositivi cliente", + "assets": "Asset cliente", + "public-dashboards": "Dashboard pubbliche", + "public-devices": "Dispositivi pubblici", + "public-assets": "Asset pubblici", + "add": "Aggiungi cliente", + "delete": "Elimina cliente", + "manage-customer-users": "Gestisci utenti cliente", + "manage-customer-devices": "Gestisci dispositivi cliente", + "manage-customer-dashboards": "Gestisci dashboard cliente", + "manage-public-devices": "Gestisci dispositivi pubblici", + "manage-public-dashboards": "Gestisci dashboard pubbliche", + "manage-customer-assets": "Gestisci asset cliente", + "manage-public-assets": "Gestisci asset pubblici", + "add-customer-text": "Aggiungi nuovo cliente", + "no-customers-text": "Nessun cliente trovato", + "customer-details": "Dettagli cliente", + "delete-customer-title": "Sei sicuro di voler eliminare il cliente '{{customerTitle}}'?", + "delete-customer-text": "Attenzione, dopo la conferma il cliente e tutti i suoi dati non saranno più recuperabili.", + "delete-customers-title": "Sei sicuro di voler cancellare { count, plural, 1 {1 cliente} other {# clienti} }?", + "delete-customers-action-title": "Elimina { count, plural, 1 {1 cliente} other {# clienti} }", + "delete-customers-text": "Attenzione, dopo la conferma tutti i clienti selezionati saranno rimossi e i loro dati non saranno più recuperabili.", + "manage-users": "Gestisci utenti", + "manage-assets": "Gestisci asset", + "manage-devices": "Gestisci dispositivi", + "manage-dashboards": "Gestisci dashboard", + "title": "Titolo", + "title-required": "Titolo obbligatorio.", + "description": "Descrizione", + "details": "Dettagli", + "events": "Eventi", + "copyId": "Copia Id cliente", + "idCopiedMessage": "Id cliente copiato negli appunti", + "select-customer": "Seleziona cliente", + "no-customers-matching": "Nessun cliente corrispondente a '{{entity}}' è stato trovato.", + "customer-required": "Cliente obbligatorio", + "select-default-customer": "Seleziona cliente di default", + "default-customer": "Cliente di default", + "default-customer-required": "Default customer is required in order to debug dashboard on Tenant level" + }, + "datetime": { + "date-from": "Data da", + "time-from": "Orario da", + "date-to": "Data a", + "time-to": "Orario a" + }, + "dashboard": { + "dashboard": "Dashboard", + "dashboards": "Dashboard", + "management": "Gestione Dashboard", + "view-dashboards": "Mostra Dashboard", + "add": "Aggiungi Dashboard", + "assign-dashboard-to-customer": "Assegna Dashboard al cliente", + "assign-dashboard-to-customer-text": "Seleziona le dashboard da assegnare al client", + "assign-to-customer-text": "Seleziona il cliente a cui assegnare la/le dashboard", + "assign-to-customer": "Assegna al cliente", + "unassign-from-customer": "Unassign from customer", + "make-public": "Rendi pubblica la dashboard", + "make-private": "Rendi privata la dashboard", + "manage-assigned-customers": "Gestisci i clienti assegnati", + "assigned-customers": "Clienti assegnati", + "assign-to-customers": "Assegna Dashboard ai Clienti", + "assign-to-customers-text": "Seleziona i clienti da assegnare alla/alle dashboard", + "unassign-from-customers": "Unassign Dashboard(s) From Customers", + "unassign-from-customers-text": "Seleziona i clienti di cui annullare l'assegnazione alla/alle dashboard", + "no-dashboards-text": "Nessuna dashboard trovata", + "no-widgets": "Nessun widget configurato", + "add-widget": "Aggiungi nuovo widget", + "title": "Titolo", + "select-widget-title": "Seleziona widget", + "select-widget-subtitle": "Elenco tipi di widget disponibili", + "delete": "Elimina dashboard", + "title-required": "Titolo obbligatorio.", + "description": "Descrizione", + "details": "Dettagli", + "dashboard-details": "Dettagli Dashboard", + "add-dashboard-text": "Aggiungi nuova dashboard", + "assign-dashboards": "Assegna dashboard", + "assign-new-dashboard": "Assegna nuova dashboard", + "assign-dashboards-text": "Assegna { count, plural, 1 {1 dashboard} other {# dashboard} } ai clienti", + "unassign-dashboards-action-text": "Annulla assegnazione { count, plural, 1 {1 dashboard} other {# dashboards} } ai clienti", + "delete-dashboards": "Elimina dashboard", + "unassign-dashboards": "Annulla assegnazione dashboard", + "unassign-dashboards-action-title": "Annulla assegnazione { count, plural, 1 {1 dashboard} other {# dashboards} } al cliente", + "delete-dashboard-title": "Sei sicuro di voler cancellare la dashboard '{{dashboardTitle}}'?", + "delete-dashboard-text": "Attenzione, dopo la conferma la dashboard e tutti i suoi dati non saranno più recuperabili.", + "delete-dashboards-title": "Sei sicuro di voler eliminare { count, plural, 1 {1 dashboard} other {# dashboard} }?", + "delete-dashboards-action-title": "Cancella { count, plural, 1 {1 dashboard} other {# dashboard} }", + "delete-dashboards-text": "Attenzione, dopo la conferma tutte le dashboard selezionate saranno eliminate e tutti i loro dati non saranno più recuperabili.", + "unassign-dashboard-title": "Sei sicuro di voler annullare l'assegnazione della dashboard '{{dashboardTitle}}'?", + "unassign-dashboard-text": "Dopo la conferma sarà annullata l'assegnazione della dashboard e questa non sarà più accessibile dal cliente.", + "unassign-dashboard": "Annulla assegnazione dashboard", + "unassign-dashboards-title": "Sei sicuro di voler annullare l'assegnazione di { count, plural, 1 {1 dashboard} other {# dashboard} }?", + "unassign-dashboards-text": "Dopo la conferma sarà annullata l'assegnazione di tutte le dashboards selezionate e queste non saranno più accessibili dal cliente.", + "public-dashboard-title": "La Dashboard è ora pubblica", + "public-dashboard-text": "La dashboard {{dashboardTitle}} è ora pubblica e accessibile al link:", + "public-dashboard-notice": "Nota: Ricorda di rendere pubblici i relativi dispositivi per accedere ai loro dati.", + "make-private-dashboard-title": "Sei sicuro di voler rendere privata la dashboard '{{dashboardTitle}}'?", + "make-private-dashboard-text": "Dopo la conferma la dashboard sarà resa privata e non più accessibile dagli altri.", + "make-private-dashboard": "Rendi privata la dashboard", + "socialshare-text": "'{{dashboardTitle}}' powered by ThingsBoard", + "socialshare-title": "'{{dashboardTitle}}' powered by ThingsBoard", + "select-dashboard": "Seleziona dashboard", + "no-dashboards-matching": "Nessuna dashboard corrispondente a '{{entity}}' è stata trovata.", + "dashboard-required": "Dashboard obbligatoria.", + "select-existing": "Seleziona una dashboard esistente", + "create-new": "Crea nuova dashboard", + "new-dashboard-title": "Titolo nuova dashboard", + "open-dashboard": "Apri dashboard", + "set-background": "Imposta sfondo", + "background-color": "Colore sfondo", + "background-image": "Immagine sfondo", + "background-size-mode": "Background size mode", + "no-image": "Nessuna immagine selezionata", + "drop-image": "Trascina un'immagine o fai clic per selezionare un file da caricare.", + "settings": "Impostazioni", + "columns-count": "Numero colonne", + "columns-count-required": "Numero colonne obbligatorio.", + "min-columns-count-message": "Ammesso un numero minimo di colonne pari a 10.", + "max-columns-count-message": "Ammesso un numero massimo di colonne pari a 1000.", + "widgets-margins": "Margine tra i widget", + "horizontal-margin": "Margine orizzontale", + "horizontal-margin-required": "Margine orizzontale obbligatorio.", + "min-horizontal-margin-message": "Ammesso un margine orizzontale minimo pari a 0.", + "max-horizontal-margin-message": "Ammesso un margine orizzontale massimo pari a 50.", + "vertical-margin": "Margine verticale", + "vertical-margin-required": "Margine verticale obbligatorio.", + "min-vertical-margin-message": "Ammesso un margine verticale minimo pari a 0.", + "max-vertical-margin-message": "Ammesso un margine verticale massimo pari a 50.", + "autofill-height": "Auto fill layout height", + "mobile-layout": "Impostazioni layout mobile", + "mobile-row-height": "Mobile row height, px", + "mobile-row-height-required": "Mobile row height value is required.", + "min-mobile-row-height-message": "Only 5 pixels is allowed as minimum mobile row height value.", + "max-mobile-row-height-message": "Only 200 pixels is allowed as maximum mobile row height value.", + "display-title": "Mostra titolo dashboard", + "toolbar-always-open": "Mantieni aperta la barra degli strumenti", + "title-color": "Colore titolo", + "display-dashboards-selection": "Mostra selezione dashboard", + "display-entities-selection": "Mostra selezione entità", + "display-dashboard-timewindow": "Display timewindow", + "display-dashboard-export": "Mostra esportazione", + "import": "Importa dashboard", + "export": "Esporta dashboard", + "export-failed-error": "Impossibile esportare la dashboard: {{error}}", + "create-new-dashboard": "Crea nuova dashboard", + "dashboard-file": "File dashboard", + "invalid-dashboard-file-error": "Impossibile importare la dashboard: struttura dati della dashboard non valida.", + "dashboard-import-missing-aliases-title": "Configura alias utilizzati dalla dashboard importata", + "create-new-widget": "Crea nuovo widget", + "import-widget": "Importa widget", + "widget-file": "Widget file", + "invalid-widget-file-error": "Impossibile importare il widget: struttura dati del widget non valida.", + "widget-import-missing-aliases-title": "Configura gli alias utilizzati dai widget importati", + "open-toolbar": "Apri barra degli strumenti", + "close-toolbar": "Chiudi barra degli strumenti", + "configuration-error": "Errore di configurazione", + "alias-resolution-error-title": "Errore di configurazione degli alias della dashboard", + "invalid-aliases-config": "Impossibile trovare un dispositivo corrispondente ad un qualche filtro degli alias.
Contatta l'amministratore per risolvere il problema.", + "select-devices": "Seleziona dispositivi", + "assignedToCustomer": "Assegnato al cliente", + "assignedToCustomers": "Assegnato ai clienti", + "public": "Pubblico", + "public-link": "Link pubblico", + "copy-public-link": "Copia link pubblico", + "public-link-copied-message": "Link pubblico della dashboard copiato negli appunti", + "manage-states": "Manage dashboard states", + "states": "Dashboard states", + "search-states": "Search dashboard states", + "selected-states": "{ count, plural, 1 {1 dashboard state} other {# dashboard states} } selected", + "edit-state": "Edit dashboard state", + "delete-state": "Delete dashboard state", + "add-state": "Add dashboard state", + "state": "Dashboard state", + "state-name": "Nome", + "state-name-required": "Dashboard state name is required.", + "state-id": "State Id", + "state-id-required": "Dashboard state id is required.", + "state-id-exists": "Dashboard state with the same id is already exists.", + "is-root-state": "Root state", + "delete-state-title": "Delete dashboard state", + "delete-state-text": "Are you sure you want delete dashboard state with name '{{stateName}}'?", + "show-details": "Mostra dettagli", + "hide-details": "Nascondi dettagli", + "select-state": "Select target state", + "state-controller": "Stato controller" + }, + "datakey": { + "settings": "Impostazioni", + "advanced": "Avanzate", + "label": "Etichetta", + "color": "Colore", + "units": "Simbolo speciale da mostrare accanto al valore", + "decimals": "Numero cifre decimali", + "data-generation-func": "Funzione generazione dati", + "use-data-post-processing-func": "Use data post-processing function", + "configuration": "Data key configuration", + "timeseries": "Serie temporali", + "attributes": "Attributi", + "alarm": "Campi allarme", + "timeseries-required": "Entity timeseries are required.", + "timeseries-or-attributes-required": "Entity timeseries/attributes are required.", + "maximum-timeseries-or-attributes": "Maximum { count, plural, 1 {1 timeseries/attribute is allowed.} other {# timeseries/attributes are allowed} }", + "alarm-fields-required": "Campi allarme obbligatori.", + "function-types": "Tipi funzione", + "function-types-required": "Tipi funzione obbligatorio.", + "maximum-function-types": "Massimo { count, plural, 1 {1 tipo di funzione consentito.} other {# tipi di funzione consentiti} }" + }, + "datasource": { + "type": "Tipo sorgente dati", + "name": "Nome", + "add-datasource-prompt": "Aggiungi una sorgente dati" + }, + "details": { + "edit-mode": "Modalità modifica", + "toggle-edit-mode": "Toggle edit mode" + }, + "device": { + "device": "Dispositivo", + "device-required": "Dispositivo richiesto.", + "devices": "Dispositivi", + "management": "Gestione dispositivo", + "view-devices": "Visualizza Dispositivi", + "device-alias": "Alias dispositivo", + "aliases": "Alias dispositivo", + "no-alias-matching": "'{{alias}}' non trovato.", + "no-aliases-found": "Nessun alias trovato.", + "no-key-matching": "'{{key}}' non trovata.", + "no-keys-found": "Nessuna chiave trovata.", + "create-new-alias": "Create a new one!", + "create-new-key": "Create a new one!", + "duplicate-alias-error": "Duplicate alias found '{{alias}}'.
Device aliases must be unique whithin the dashboard.", + "configure-alias": "Configura alias '{{alias}}'", + "no-devices-matching": "Nessun dispositivo corrispondente a '{{entity}}' é stato trovato.", + "alias": "Alias", + "alias-required": "Alias dispositivo richesto.", + "remove-alias": "Rimuovi alias dispositivo", + "add-alias": "Aggiungi alias dispositivo", + "name-starts-with": "Device name starts with", + "device-list": "Lista dispositivi", + "use-device-name-filter": "Usa filtro", + "device-list-empty": "Nessun dispositivo selezionato.", + "device-name-filter-required": "Device name filter is required.", + "device-name-filter-no-device-matched": "No devices starting with '{{device}}' were found.", + "add": "Aggiungi Dispositivo", + "assign-to-customer": "Assigna al cliente", + "assign-device-to-customer": "Assegna dispositivo/dispositivi al Cliente", + "assign-device-to-customer-text": "Seleziona i dispositivi da assegnare al cliente", + "make-public": "Rendi pubblico il dispositivo", + "make-private": "rendi privato il dispositivo", + "no-devices-text": "Nessun dispositivo trovato", + "assign-to-customer-text": "Seleziona il cliente a cui assegnare il dispositivo/i dispositivi", + "device-details": "Dettagli dispositivo", + "add-device-text": "Aggiungi nuovo dispositivo", + "credentials": "Credenziali", + "manage-credentials": "Gestisci credenziali", + "delete": "Elimina dispositivo", + "assign-devices": "Assegna dispositivi", + "assign-devices-text": "Assegna { count, plural, 1 {1 dispositivo} other {# dispositivi} } al cliente", + "delete-devices": "Elimina dispositivi", + "unassign-from-customer": "Annulla assegnazione al cliente", + "unassign-devices": "Annulla assegnazione dispositivi", + "unassign-devices-action-title": "Annulla assegnazione { count, plural, 1 {1 dispositivo} other {# dispositivi} } al cliente", + "assign-new-device": "Assegna nuovo dispositivo", + "make-public-device-title": "Sei sicuro di voler rendere pubblico il dispositivo '{{deviceName}}'?", + "make-public-device-text": "Dopo la conferma il dispositivo e tutti i suoi dati saranno resi pubblici e accessibili dagli altri.", + "make-private-device-title": "Sei sicuro di voler rendere privato il dispositivo '{{deviceName}}'?", + "make-private-device-text": "Dopo la conferma il dispositivo e tutti i suoi dati saranno resi privati e non più accessibili da altri utenti.", + "view-credentials": "Visualizza credenziali", + "delete-device-title": "Sei sicuro di voler eliminare il dispositivo '{{deviceName}}'?", + "delete-device-text": "Attenzione, dopo la conferma il dispositivo e tutti i suoi dati non saranno più recuperabili.", + "delete-devices-title": "Sei sicuro di voler eliminare { count, plural, 1 {1 dispositivo} other {# dispositivi} }?", + "delete-devices-action-title": "Elimina { count, plural, 1 {1 dispositivo} other {# dispositivi} }", + "delete-devices-text": "Attenzione, dopo la conferma tutti i dispositivi selezionati saranno elimininati e i relativi dati non saranno più recuperabili.", + "unassign-device-title": "Sei sicuro di voler annullare l'assegnazione del dispositivo '{{deviceName}}'?", + "unassign-device-text": "Dopo la conferma sarà annullata l'assegnazione del dispositivo e questo non sarà più accessibile dal cliente.", + "unassign-device": "Annulla assegnazione dispositivo", + "unassign-devices-title": "Sei sicuro di voler annullare la'ssegnazione di { count, plural, 1 {1 dispositivo} other {# dispositivi} }?", + "unassign-devices-text": "Dopo la conferma sarà annullata l'assegnazione di tutti i dispositivi selezionati e questi non saranno più accessibili dal cliente.", + "device-credentials": "Credenziali Dispositivo", + "credentials-type": "Tipo credenziali", + "access-token": "Token di accesso", + "access-token-required": "Token di accesso obbligatorio.", + "access-token-invalid": "Il token di accesso deve avere una lunghezza compresa tra 1 e 20 caratteri.", + "rsa-key": "Chiave pubblica RSA", + "rsa-key-required": "Chiave pubblica RSA obbligatoria.", + "secret": "Secret", + "secret-required": "Secret obbligatorio.", + "device-type": "Tipo dispositivo", + "device-type-required": "Tipo dispositivo obbligatorio.", + "select-device-type": "Seleziona tipo dispositivo", + "enter-device-type": "Inserisci typo dispositivo", + "any-device": "Qualsiasi dispositivo", + "no-device-types-matching": "Nessun dispositivo corrispondente a '{{entitySubtype}}' è stato trovato.", + "device-type-list-empty": "Nessun tipo di dispositivo selezionato.", + "device-types": "Tipi dispositivo", + "name": "Nome", + "name-required": "Nome obbligatorio.", + "description": "Descrizione", + "events": "Eventi", + "details": "Dettagli", + "copyId": "Copia Id dispositivo", + "copyAccessToken": "Copia token di accesso", + "idCopiedMessage": "Id dispositivo copiato negli Appunti", + "accessTokenCopiedMessage": "Token di accesso del dispositivo copiato negli Appunti", + "assignedToCustomer": "Assegnato al cliente", + "unable-delete-device-alias-title": "Impossibile rimuovere l'alias del dispositivo", + "unable-delete-device-alias-text": "L'alias del dispositivo '{{deviceAlias}}' non può essere eliminato perchè utilizzato dai seguenti widget:
{{widgetsList}}", + "is-gateway": "E' un gateway", + "public": "Pubblico", + "device-public": "Il dispositivo è pubblico", + "select-device": "Seleziona dispositivo" + }, + "dialog": { + "close": "Close dialog" + }, + "error": { + "unable-to-connect": "Impossibile connettersi al server! Controlla la connessione ad Internet.", + "unhandled-error-code": "Codice errore non gestito: {{errorCode}}", + "unknown-error": "Errore sconosciuto" + }, + "entity": { + "entity": "Entità", + "entities": "Entità", + "aliases": "Alias entità", + "entity-alias": "Alias entità", + "unable-delete-entity-alias-title": "Impossibile eliminare alias entità", + "unable-delete-entity-alias-text": "L'alias dell'entità '{{entityAlias}}' non può essere eliminato perchè utilizzato dai seguenti widget:
{{widgetsList}}", + "duplicate-alias-error": "Trovato un duplicato dell'alias '{{alias}}'.
Gli alias dell'entità devono essere univoci all'interno della dashboard.", + "missing-entity-filter-error": "Filter is missing for alias '{{alias}}'.", + "configure-alias": "Configura '{{alias}}' alias", + "alias": "Alias", + "alias-required": "Alias entità obbligatorio.", + "remove-alias": "Rimuovi alias entità", + "add-alias": "Aggiungi alias entità", + "entity-list": "Lista entità", + "entity-type": "Tipo entità", + "entity-types": "Tipi entità", + "entity-type-list": "Lista tipo entità", + "any-entity": "Qualsiasi entità", + "enter-entity-type": "Inserisci tipo entità", + "no-entities-matching": "Nessuna entità corrispondente a '{{entity}}' è stata trovata.", + "no-entity-types-matching": "Nessun tipo di entità corrispondente a '{{entityType}}' è stato trovato.", + "name-starts-with": "Nome inizia per", + "use-entity-name-filter": "Usa filtro", + "entity-list-empty": "Nessuna entità selezionata.", + "entity-type-list-empty": "Nessun tipo di entità selezionato.", + "entity-name-filter-required": "Filtro nome entità obbligatorio.", + "entity-name-filter-no-entity-matched": "No entities starting with '{{entity}}' were found.", + "all-subtypes": "Tutte", + "select-entities": "Seleziona entità", + "no-aliases-found": "Nessun alias trovato.", + "no-alias-matching": "'{{alias}}' non trovato.", + "create-new-alias": "Create a new one!", + "key": "Chiave", + "key-name": "Nome chiave", + "no-keys-found": "Nessuna chiave trovata.", + "no-key-matching": "'{{key}}' non trovata.", + "create-new-key": "Create a new one!", + "type": "Tipo", + "type-required": "Tipo entità obbligatorio.", + "type-device": "Dispositivo", + "type-devices": "Dispositivi", + "list-of-devices": "{ count, plural, 1 {Un dispositivo} other {Lista di # dispositivi} }", + "device-name-starts-with": "Dispositivi i cui nomi iniziano per '{{prefix}}'", + "type-asset": "Asset", + "type-assets": "Asset", + "list-of-assets": "{ count, plural, 1 {Un asset} other {Lista di # asset} }", + "asset-name-starts-with": "Asset i cui nomi iniziano per '{{prefix}}'", + "type-rule": "Regola", + "type-rules": "Regole", + "list-of-rules": "{ count, plural, 1 {Una regola} other {Lista di # regole} }", + "rule-name-starts-with": "Regole i cui nomi iniziano per '{{prefix}}'", + "type-plugin": "Plugin", + "type-plugins": "Plugin", + "list-of-plugins": "{ count, plural, 1 {Un plugin} other {Lista di # plugin} }", + "plugin-name-starts-with": "Plugin i cui nomi iniziano per '{{prefix}}'", + "type-tenant": "Tenant", + "type-tenants": "Tenants", + "list-of-tenants": "{ count, plural, 1 {One tenant} other {List of # tenants} }", + "tenant-name-starts-with": "Tenants whose names start with '{{prefix}}'", + "type-customer": "Cliente", + "type-customers": "Clienti", + "list-of-customers": "{ count, plural, 1 {Un cliente} other {Lista di # clienti} }", + "customer-name-starts-with": "Clienti i cui nomi iniziano per '{{prefix}}'", + "type-user": "Utente", + "type-users": "Utenti", + "list-of-users": "{ count, plural, 1 {Un utente} other {Lista of # utenti} }", + "user-name-starts-with": "Utenti i cui nomi iniziano per '{{prefix}}'", + "type-dashboard": "Dashboard", + "type-dashboards": "Dashboard", + "list-of-dashboards": "{ count, plural, 1 {Una dashboard} other {Lista di # dashboard} }", + "dashboard-name-starts-with": "Dashboard i cui nomi iniziano per '{{prefix}}'", + "type-alarm": "Allarme", + "type-alarms": "Allarmi", + "list-of-alarms": "{ count, plural, 1 {Un allarme} other {Lista di # allarmi} }", + "alarm-name-starts-with": "Allarmi i cui nomi iniziano per '{{prefix}}'", + "type-rulechain": "Rule chain", + "type-rulechains": "Rule chains", + "list-of-rulechains": "{ count, plural, 1 {One rule chain} other {List of # rule chains} }", + "rulechain-name-starts-with": "Rule chains whose names start with '{{prefix}}'", + "type-current-customer": "Current Customer", + "search": "Ricerca entità", + "selected-entities": "{ count, plural, 1 {1 entità selezionata} other {# entità selezionate} }", + "entity-name": "Nome entità", + "details": "Dettagli entità", + "no-entities-prompt": "Nessuna entità trovata", + "no-data": "Nessun dato da mostrare" + }, + "event": { + "event-type": "Tipo evento", + "type-error": "Errore", + "type-lc-event": "Ciclo di vita evento", + "type-stats": "Statistiche", + "type-debug-rule-node": "Debug", + "type-debug-rule-chain": "Debug", + "no-events-prompt": "Nessun evento trovato", + "error": "Errore", + "alarm": "Allarme", + "event-time": "Orario evento", + "server": "Server", + "body": "Body", + "method": "Metodo", + "type": "Tipo", + "entity": "Entità", + "message-id": "Id Messaggio", + "message-type": "Tipo Messaggio", + "data-type": "Data Type", + "relation-type": "Tipo di relazione", + "metadata": "Metadati", + "data": "Dati", + "event": "Evento", + "status": "Stato", + "success": "Success", + "failed": "Failed", + "messages-processed": "Messaggi elaborati", + "errors-occurred": "Si sono verificati degli errori" + }, + "extension": { + "extensions": "Estensioni", + "selected-extensions": "{ count, plural, 1 {1 estensione selezionata} other {# estensioni selezionate} }", + "type": "Tipo", + "key": "Chiave", + "value": "Valore", + "id": "Id", + "extension-id": "Id Estensione", + "extension-type": "Tipo Estensione", + "transformer-json": "JSON *", + "unique-id-required": "Id estensione corrente già esistente.", + "delete": "Elimina estensione", + "add": "Aggiungi estensione", + "edit": "Modifica estensione", + "delete-extension-title": "Sei sicuro di voler eliminare l'estensione '{{extensionId}}'?", + "delete-extension-text": "Attenzione, dopo la conferma l'estensione e tutti i suoi data non saranno più recuperabili.", + "delete-extensions-title": "Sei sicuro di voler eliminare { count, plural, 1 {1 estensione} other {# estensioni} }?", + "delete-extensions-text": "Attenzione, dopo la conferma tutte le estensioni selezionate saranno eliminate.", + "converters": "Converters", + "converter-id": "Converter id", + "configuration": "Configurazione", + "converter-configurations": "Converter configurations", + "token": "Token di sicurezza", + "add-converter": "Add converter", + "add-config": "Add converter configuration", + "device-name-expression": "Device name expression", + "device-type-expression": "Device type expression", + "custom": "Custom", + "to-double": "To Double", + "transformer": "Transformer", + "json-required": "Transformer json is required.", + "json-parse": "Unable to parse transformer json.", + "attributes": "Attributi", + "add-attribute": "Aggiungi attributo", + "add-map": "Add mapping element", + "timeseries": "Serie temporali", + "add-timeseries": "Add timeseries", + "field-required": "Field is required", + "brokers": "Broker", + "add-broker": "Aggiungi broker", + "host": "Host", + "port": "Porta", + "port-range": "Port should be in a range from 1 to 65535.", + "ssl": "Ssl", + "credentials": "Credenziali", + "username": "Nome utente", + "password": "Password", + "retry-interval": "Retry interval in milliseconds", + "anonymous": "Anonimo", + "basic": "Basic", + "pem": "PEM", + "ca-cert": "CA certificate file *", + "private-key": "File chiave privata *", + "cert": "File certificato *", + "no-file": "Nessun file selezionato.", + "drop-file": "Trascina un file o fai clic per selezionare un file da caricare.", + "mapping": "Mapping", + "topic-filter": "Filtro topic", + "converter-type": "Converter type", + "converter-json": "Json", + "json-name-expression": "Device name json expression", + "topic-name-expression": "Device name topic expression", + "json-type-expression": "Device type json expression", + "topic-type-expression": "Device type topic expression", + "attribute-key-expression": "Attribute key expression", + "attr-json-key-expression": "Attribute key json expression", + "attr-topic-key-expression": "Attribute key topic expression", + "request-id-expression": "Request id expression", + "request-id-json-expression": "Request id json expression", + "request-id-topic-expression": "Request id topic expression", + "response-topic-expression": "Response topic expression", + "value-expression": "Value expression", + "topic": "Topic", + "timeout": "Timeout in millisecondi", + "converter-json-required": "Convertitore json obbligatorio.", + "converter-json-parse": "Unable to parse converter json.", + "filter-expression": "Filter expression", + "connect-requests": "Connect requests", + "add-connect-request": "Add connect request", + "disconnect-requests": "Disconnect requests", + "add-disconnect-request": "Add disconnect request", + "attribute-requests": "Attribute requests", + "add-attribute-request": "Add attribute request", + "attribute-updates": "Attribute updates", + "add-attribute-update": "Add attribute update", + "server-side-rpc": "Server side RPC", + "add-server-side-rpc-request": "Add server-side RPC request", + "device-name-filter": "Device name filter", + "attribute-filter": "Attribute filter", + "method-filter": "Method filter", + "request-topic-expression": "Request topic expression", + "response-timeout": "Response timeout in milliseconds", + "topic-expression": "Topic expression", + "client-scope": "Client scope", + "add-device": "Aggiungi dispositivo", + "opc-server": "Server", + "opc-add-server": "Aggiungi server", + "opc-add-server-prompt": "Aggiungi server", + "opc-application-name": "Nome applicazione", + "opc-application-uri": "Uri applicazione", + "opc-scan-period-in-seconds": "Intervallo di scansione in secondi", + "opc-security": "Sicurezza", + "opc-identity": "Identità", + "opc-keystore": "Keystore", + "opc-type": "Tipo", + "opc-keystore-type": "Tipo", + "opc-keystore-location": "Location *", + "opc-keystore-password": "Password", + "opc-keystore-alias": "Alias", + "opc-keystore-key-password": "Chiave password", + "opc-device-node-pattern": "Device node pattern", + "opc-device-name-pattern": "Device name pattern", + "modbus-server": "Servers/slaves", + "modbus-add-server": "Aggiungi server/slave", + "modbus-add-server-prompt": "Aggiungi server/slave", + "modbus-transport": "Transport", + "modbus-port-name": "Nome porta seriale", + "modbus-encoding": "Codifica", + "modbus-parity": "Parità", + "modbus-baudrate": "Baud rate", + "modbus-databits": "Data bits", + "modbus-stopbits": "Stop bits", + "modbus-databits-range": "Data bits should be in a range from 7 to 8.", + "modbus-stopbits-range": "Stop bits should be in a range from 1 to 2.", + "modbus-unit-id": "Unit ID", + "modbus-unit-id-range": "Unit ID should be in a range from 1 to 247.", + "modbus-device-name": "Nome dispositivo", + "modbus-poll-period": "Intervallo di polling (ms)", + "modbus-attributes-poll-period": "Attributes poll period (ms)", + "modbus-timeseries-poll-period": "Timeseries poll period (ms)", + "modbus-poll-period-range": "L'intervallo di polling deve essere un valore positivo.", + "modbus-tag": "Tag", + "modbus-function": "Funzione", + "modbus-register-address": "Indirizzo registro", + "modbus-register-address-range": "L'indirizzo del registro deve essere compreso tra 0 e 65535.", + "modbus-register-bit-index": "Bit index", + "modbus-register-bit-index-range": "Bit index should be in a range from 0 to 15.", + "modbus-register-count": "Register count", + "modbus-register-count-range": "Register count should be a positive value.", + "modbus-byte-order": "Byte order", + + "sync": { + "status": "Stato", + "sync": "Sincronizzato", + "not-sync": "Non sincronizzato", + "last-sync-time": "Ultima sincronizzazione", + "not-available": "Non disponibile" + }, + + "export-extensions-configuration": "Export extensions configuration", + "import-extensions-configuration": "Import extensions configuration", + "import-extensions": "Importa estensione", + "import-extension": "Importa estensione", + "export-extension": "Esporta estensione", + "file": "File estensione", + "invalid-file-error": "File estensione non valido" + }, + "fullscreen": { + "expand": "Expand to fullscreen", + "exit": "Exit fullscreen", + "toggle": "Toggle fullscreen mode", + "fullscreen": "Fullscreen" + }, + "function": { + "function": "Function" + }, + "grid": { + "delete-item-title": "Are you sure you want to delete this item?", + "delete-item-text": "Be careful, after the confirmation this item and all related data will become unrecoverable.", + "delete-items-title": "Are you sure you want to delete { count, plural, 1 {1 item} other {# items} }?", + "delete-items-action-title": "Delete { count, plural, 1 {1 item} other {# items} }", + "delete-items-text": "Be careful, after the confirmation all selected items will be removed and all related data will become unrecoverable.", + "add-item-text": "Add new item", + "no-items-text": "No items found", + "item-details": "Item details", + "delete-item": "Delete Item", + "delete-items": "Delete Items", + "scroll-to-top": "Scroll to top" + }, + "help": { + "goto-help-page": "Go to help page" + }, + "home": { + "home": "Home", + "profile": "Profilo", + "logout": "Logout", + "menu": "Menu", + "avatar": "Avatar", + "open-user-menu": "Apri menu utente" + }, + "import": { + "no-file": "Nessun file selezionato", + "drop-file": "Trascina un file JSON o fai clic per selezionare un file da caricare." + }, + "item": { + "selected": "Selezionata" + }, + "js-func": { + "no-return-error": "La funzione deve restituire un valore!", + "return-type-mismatch": "La funzione deve restituire un valore di tipo '{{type}}'!", + "tidy": "Tidy" + }, + "key-val": { + "key": "Chiave", + "value": "Valore", + "remove-entry": "Remove entry", + "add-entry": "Add entry", + "no-data": "No entries" + }, + "layout": { + "layout": "Layout", + "manage": "Gestisci layout", + "settings": "Impostazioni layout", + "color": "Colore", + "main": "Main", + "right": "Right", + "select": "Select target layout" + }, + "legend": { + "position": "Posizione Legenda", + "show-max": "Mostra valore max", + "show-min": "Mostra valore min", + "show-avg": "Mostra valore medio", + "show-total": "Mostra valore totale", + "settings": "Impostazioni legenda", + "min": "min", + "max": "max", + "avg": "avg", + "total": "totale" + }, + "login": { + "login": "Login", + "request-password-reset": "Request Password Reset", + "reset-password": "Azzera Password", + "create-password": "Crea Password", + "passwords-mismatch-error": "Le password inserite devono corrispondere!", + "password-again": "Ripeti Password", + "sign-in": "Please sign in", + "username": "Nome utente (email)", + "remember-me": "Ricordami", + "forgot-password": "Password dimenticata?", + "password-reset": "Password reset", + "new-password": "Nuova password", + "new-password-again": "Ripeti nuova password", + "password-link-sent-message": "Link azzeramento password inviato con successo!", + "email": "Email" + }, + "position": { + "top": "Alto", + "bottom": "Basso", + "left": "Sinistra", + "right": "Destra" + }, + "profile": { + "profile": "Profilo", + "change-password": "Modifica Password", + "current-password": "Password attuale" + }, + "relation": { + "relations": "Relations", + "direction": "Direction", + "search-direction": { + "FROM": "Da", + "TO": "A" + }, + "direction-type": { + "FROM": "da", + "TO": "a" + }, + "from-relations": "Outbound relations", + "to-relations": "Inbound relations", + "selected-relations": "{ count, plural, 1 {1 relation} other {# relations} } selected", + "type": "Tipo", + "to-entity-type": "A tipo entità", + "to-entity-name": "A nome entità", + "from-entity-type": "Da tipo entità", + "from-entity-name": "Da nome entità", + "to-entity": "A entità", + "from-entity": "Da entità", + "delete": "Delete relation", + "relation-type": "Relation type", + "relation-type-required": "Relation type is required.", + "any-relation-type": "Ogni tipo", + "add": "Add relation", + "edit": "Edit relation", + "delete-to-relation-title": "Are you sure you want to delete relation to the entity '{{entityName}}'?", + "delete-to-relation-text": "Attenzione, dopo la conferma l'entità '{{entityName}}' sarà scollegata dall'entità corrente.", + "delete-to-relations-title": "Are you sure you want to delete { count, plural, 1 {1 relation} other {# relations} }?", + "delete-to-relations-text": "Be careful, after the confirmation all selected relations will be removed and corresponding entities will be unrelated from the current entity.", + "delete-from-relation-title": "Are you sure you want to delete relation from the entity '{{entityName}}'?", + "delete-from-relation-text": "Be careful, after the confirmation current entity will be unrelated from the entity '{{entityName}}'.", + "delete-from-relations-title": "Are you sure you want to delete { count, plural, 1 {1 relation} other {# relations} }?", + "delete-from-relations-text": "Be careful, after the confirmation all selected relations will be removed and current entity will be unrelated from the corresponding entities.", + "remove-relation-filter": "Remove relation filter", + "add-relation-filter": "Add relation filter", + "any-relation": "Any relation", + "relation-filters": "Relation filters", + "additional-info": "Additional info (JSON)", + "invalid-additional-info": "Unable to parse additional info json." + }, + "rulechain": { + "rulechain": "Rule chain", + "rulechains": "Rule chains", + "root": "Root", + "delete": "Delete rule chain", + "name": "Nome", + "name-required": "Nome obbligatorio.", + "description": "Descrizione", + "add": "Add Rule Chain", + "set-root": "Make rule chain root", + "set-root-rulechain-title": "Are you sure you want to make the rule chain '{{ruleChainName}}' root?", + "set-root-rulechain-text": "After the confirmation the rule chain will become root and will handle all incoming transport messages.", + "delete-rulechain-title": "Are you sure you want to delete the rule chain '{{ruleChainName}}'?", + "delete-rulechain-text": "Be careful, after the confirmation the rule chain and all related data will become unrecoverable.", + "delete-rulechains-title": "Are you sure you want to delete { count, plural, 1 {1 rule chain} other {# rule chains} }?", + "delete-rulechains-action-title": "Delete { count, plural, 1 {1 rule chain} other {# rule chains} }", + "delete-rulechains-text": "Be careful, after the confirmation all selected rule chains will be removed and all related data will become unrecoverable.", + "add-rulechain-text": "Add new rule chain", + "no-rulechains-text": "No rule chains found", + "rulechain-details": "Rule chain details", + "details": "Dettagli", + "events": "Eventi", + "system": "Sistema", + "import": "Import rule chain", + "export": "Export rule chain", + "export-failed-error": "Unable to export rule chain: {{error}}", + "create-new-rulechain": "Create new rule chain", + "rulechain-file": "Rule chain file", + "invalid-rulechain-file-error": "Unable to import rule chain: Invalid rule chain data structure.", + "copyId": "Copy rule chain Id", + "idCopiedMessage": "Rule chain Id has been copied to clipboard", + "select-rulechain": "Select rule chain", + "no-rulechains-matching": "No rule chains matching '{{entity}}' were found.", + "rulechain-required": "Rule chain is required", + "management": "Rules management", + "debug-mode": "Modalità debug" + }, + "rulenode": { + "details": "Dettagli", + "events": "Eventi", + "search": "Ricerca nodi", + "open-node-library": "Apri libreria nodi", + "add": "Add rule node", + "name": "Nome", + "name-required": "Nome obbligatorio.", + "type": "Tipo", + "description": "Descrizione", + "delete": "Delete rule node", + "select-all-objects": "Seleziona tutti i nodi e le connessioni", + "deselect-all-objects": "Deselect all nodes and connections", + "delete-selected-objects": "Cancella nodi e connessioni selezionate", + "delete-selected": "Delete selected", + "select-all": "Seleziona tutto", + "copy-selected": "Copy selected", + "deselect-all": "Deselect all", + "rulenode-details": "Rule node details", + "debug-mode": "Modalità debug", + "configuration": "Configurazione", + "link": "Link", + "link-details": "Rule node link details", + "add-link": "Aggiungi link", + "link-label": "Etichetta link", + "link-label-required": "Etichetta link obbligatoria.", + "custom-link-label": "Custom link label", + "custom-link-label-required": "Custom link label is required.", + "type-filter": "Filtro", + "type-filter-details": "Filter incoming messages with configured conditions", + "type-enrichment": "Enrichment", + "type-enrichment-details": "Add additional information into Message Metadata", + "type-transformation": "Transformation", + "type-transformation-details": "Change Message payload and Metadata", + "type-action": "Azioni", + "type-action-details": "Perform special action", + "type-external": "External", + "type-external-details": "Interacts with external system", + "type-rule-chain": "Rule Chain", + "type-rule-chain-details": "Forwards incoming messages to specified Rule Chain", + "type-input": "Input", + "type-input-details": "Logical input of Rule Chain, forwards incoming messages to next related Rule Node", + "directive-is-not-loaded": "Defined configuration directive '{{directiveName}}' is not available.", + "ui-resources-load-error": "Failed to load configuration ui resources.", + "invalid-target-rulechain": "Unable to resolve target rule chain!", + "test-script-function": "Test script function", + "message": "Messaggio", + "message-type": "Tipo messaggio", + "message-type-required": "Tipo messaggio obbligatorio", + "metadata": "Metadata", + "metadata-required": "Metadata entries can't be empty.", + "output": "Output", + "test": "Test", + "help": "Aiuto" + }, + "tenant": { + "tenant": "Tenant", + "tenants": "Tenant", + "management": "Gestione Tenant", + "add": "Aggiungi Tenant", + "admins": "Amministratori", + "manage-tenant-admins": "Gestisci amministratori tenant", + "delete": "Cancella tenant", + "add-tenant-text": "Aggiungi nuovo tenant", + "no-tenants-text": "Nessun tenant trovato", + "tenant-details": "Dettagli tenant", + "delete-tenant-title": "Sei sicuro di voler eliminare il tenant '{{tenantTitle}}'?", + "delete-tenant-text": "Attenzione, dopo la conferma il tenant e tutti i suoi dati non saranno più recuperabili.", + "delete-tenants-title": "Sei sicuro di voler eliminare { count, plural, 1 {1 tenant} other {# tenant} }?", + "delete-tenants-action-title": "Elimina { count, plural, 1 {1 tenant} other {# tenant} }", + "delete-tenants-text": "Attenzione, dopo la conferma tutti i tenant selezionati saranno eliminati e tutti i loro dati non saranno più recuperabili.", + "title": "Titolo", + "title-required": "Titolo obbligatorio.", + "description": "Descrizione", + "details": "Dettagli", + "events": "Eventi", + "copyId": "Copia Id tenant", + "idCopiedMessage": "Id tenant copiato negli appunti", + "select-tenant": "Seleziona tenant", + "no-tenants-matching": "Nessun tenant corrispondente a '{{entity}}' è stato trovato.", + "tenant-required": "Tenant obbligatorio" + }, + "timeinterval": { + "seconds-interval": "{ seconds, plural, 1 {1 secondo} other {# secondi} }", + "minutes-interval": "{ minutes, plural, 1 {1 minuto} other {# minuti} }", + "hours-interval": "{ hours, plural, 1 {1 ora} other {# ore} }", + "days-interval": "{ days, plural, 1 {1 giorno} other {# giorni} }", + "days": "Giorni", + "hours": "Ore", + "minutes": "Minuti", + "seconds": "Secondi", + "advanced": "Avanzate" + }, + "timewindow": { + "days": "{ days, plural, 1 { giorno } other {# giorni } }", + "hours": "{ hours, plural, 0 { hour } 1 {1 ora } other {# ore } }", + "minutes": "{ minutes, plural, 0 { minute } 1 {1 minuto } other {# minuti } }", + "seconds": "{ seconds, plural, 0 { second } 1 {1 secondo } other {# secondi } }", + "realtime": "Realtime", + "history": "Cronologia", + "last-prefix": "last", + "period": "from {{ startTime }} to {{ endTime }}", + "edit": "Edit timewindow", + "date-range": "Date range", + "last": "Last", + "time-period": "Time period" + }, + "user": { + "user": "Utente", + "users": "Utenti", + "customer-users": "Customer Users", + "tenant-admins": "Amministratori Tenant", + "sys-admin": "Amministratore di sistema", + "tenant-admin": "Amministratore tenant", + "customer": "Cliente", + "anonymous": "Anonimo", + "add": "Aggiungi Utente", + "delete": "Elimina utente", + "add-user-text": "Aggiungi nuovo utente", + "no-users-text": "Nessun utente trovato", + "user-details": "Dettagli utente", + "delete-user-title": "Sei sicuro di voler eliminare l'utente '{{userEmail}}'?", + "delete-user-text": "Attenzione, dopo la conferma l'utente e tutti i suoi dati non saranno più recuperabili.", + "delete-users-title": "Sei sicuro di voler eliminare { count, plural, 1 {1 utente} other {# utenti} }?", + "delete-users-action-title": "Elimina { count, plural, 1 {1 utente} other {# utenti} }", + "delete-users-text": "Attenzione, dopo la conferma tutti gli utenti selezionati saranno eliminati e tutti i relativi dati non saranno più recuperabili.", + "activation-email-sent-message": "Email di attivazione inviata con successo!", + "resend-activation": "Resend activation", + "email": "Email", + "email-required": "Email obbligatoria.", + "invalid-email-format": "Formato email non valido.", + "first-name": "Nome", + "last-name": "Cognome", + "description": "Descrizione", + "default-dashboard": "Dashboard di default", + "always-fullscreen": "Always fullscreen", + "select-user": "Seleziona utente", + "no-users-matching": "Nessun utente corrispondente a '{{entity}}' è stato trovato.", + "user-required": "Utente obbligatorio", + "activation-method": "Metodo di attivazione", + "display-activation-link": "Mostra link di attivazione", + "send-activation-mail": "Invia email di attivazione", + "activation-link": "Link attivazione utente", + "activation-link-text": "Per attivare l'utente utilizza il seguente link di attivazione :", + "copy-activation-link": "Copia link di attivazione", + "activation-link-copied-message": "Link di attivazione utente copiato negli appunti", + "details": "Dettagli" + }, + "value": { + "type": "Tipo valore", + "string": "String", + "string-value": "Valore string", + "integer": "Integer", + "integer-value": "Valore integer", + "invalid-integer-value": "Valore integer non valido", + "double": "Double", + "double-value": "Valore double", + "boolean": "Boolean", + "boolean-value": "Valore boolean", + "false": "Falso", + "true": "Vero", + "long": "Long" + }, + "widget": { + "widget-library": "Libreria Widget", + "widget-bundle": "Bundle widget", + "select-widgets-bundle": "Seleziona bundle widget", + "management": "Gestione widget", + "editor": "Editor Widget", + "widget-type-not-found": "Problem loading widget configuration.
Probably associated\n widget type was removed.", + "widget-type-load-error": "Widget non caricato a causa dei seguenti errori:", + "remove": "Elimina widget", + "edit": "Modifica widget", + "remove-widget-title": "sei sicuro di voler eliminare il widget '{{widgetTitle}}'?", + "remove-widget-text": "Dopo la conferma il widget e tutti i suoi dati non saranno più recuperabili.", + "timeseries": "Time series", + "search-data": "Cerca dati", + "no-data-found": "Nessun dato trovato", + "latest-values": "Ultimi valori", + "rpc": "Control widget", + "alarm": "Alarm widget", + "static": "Static widget", + "select-widget-type": "Seleziona tipo widget", + "missing-widget-title-error": "Il tiolo del widget deve essere specificato!", + "widget-saved": "Widget salvato", + "unable-to-save-widget-error": "Impossibile salvare il widget! Sono presenti degli errori!", + "save": "Salva widget", + "saveAs": "Salva widget come", + "save-widget-type-as": "Salva tipo widget come", + "save-widget-type-as-text": "Please enter new widget title and/or select target widgets bundle", + "toggle-fullscreen": "Toggle fullscreen", + "run": "Esegui widget", + "title": "Titolo widget", + "title-required": "Titolo widget obbligatorio.", + "type": "Tipo widget", + "resources": "Risorse", + "resource-url": "JavaScript/CSS URL", + "remove-resource": "Rimuovi risorsa", + "add-resource": "Aggiungi risorsa", + "html": "HTML", + "tidy": "Tidy", + "css": "CSS", + "settings-schema": "Impostazioni schema", + "datakey-settings-schema": "Data key settings schema", + "javascript": "Javascript", + "remove-widget-type-title": "Sei sicuro di voler rimuovere il tipo di widget '{{widgetName}}'?", + "remove-widget-type-text": "Dopo la conferma il tipo di widget e tutti i suoi dati non saranno più recuperabili.", + "remove-widget-type": "Rimuovi tipo widget", + "add-widget-type": "Aggiungi nuovo tipo widget", + "widget-type-load-failed-error": "Caricamento tipo widget fallito!", + "widget-template-load-failed-error": "Caricamento template widget fallito!", + "add": "Aggiungi Widget", + "undo": "Annulla modifiche widget", + "export": "Esporta widget" + }, + "widget-action": { + "header-button": "Widget header button", + "open-dashboard-state": "Navigate to new dashboard state", + "update-dashboard-state": "Update current dashboard state", + "open-dashboard": "Navigate to other dashboard", + "custom": "Custom action", + "target-dashboard-state": "Target dashboard state", + "target-dashboard-state-required": "Target dashboard state is required", + "set-entity-from-widget": "Set entity from widget", + "target-dashboard": "Target dashboard", + "open-right-layout": "Open right dashboard layout (mobile view)" + }, + "widgets-bundle": { + "current": "Bundle corrente", + "widgets-bundles": "Bundle Widget", + "add": "Aggiungi Bundle Widget", + "delete": "Cancella bundle widget", + "title": "Titolo", + "title-required": "Titolo obbligatorio.", + "add-widgets-bundle-text": "Aggiungi nuovo bundle widget", + "no-widgets-bundles-text": "Nessun bundle widget trovato", + "empty": "Bundle widget vuoto", + "details": "Dettagli", + "widgets-bundle-details": "Dettagli bundle widget", + "delete-widgets-bundle-title": "Sei sicuro di voler eliminare il bundle widget '{{widgetsBundleTitle}}'?", + "delete-widgets-bundle-text": "Attenzione, dopo la conferma il bundle widget e tutti i suoi dati non saranno più recuperabili.", + "delete-widgets-bundles-title": "Sei sicuro di voler eliminare { count, plural, 1 {1 bundle widget} other {# bundle widget} }?", + "delete-widgets-bundles-action-title": "Elimina { count, plural, 1 {1 bundle widget} other {# bundle widget} }", + "delete-widgets-bundles-text": "Attenzione, dopo la conferma tutti i bundle widget selezionati saranno rimossi e tutti i loro dati non saranno più recuperabili.", + "no-widgets-bundles-matching": "Nessun bundle widget corrispondente a '{{widgetsBundle}}' è stato trovato.", + "widgets-bundle-required": "Bundle widget obbligatorio.", + "system": "Sistema", + "import": "Importa bundle widget", + "export": "Esporta bundle widget", + "export-failed-error": "Impossibile esportare bundle widget: {{error}}", + "create-new-widgets-bundle": "Crea nuovo bundle widget", + "widgets-bundle-file": "File bundle widget", + "invalid-widgets-bundle-file-error": "Impossibile importare bundle widget: struttura dati non valida." + }, + "widget-config": { + "data": "Dati", + "settings": "Impostazioni", + "advanced": "Avanzate", + "title": "Titolo", + "general-settings": "Impostazioni generali", + "display-title": "Mostra titolo", + "drop-shadow": "Drop shadow", + "enable-fullscreen": "Abilita fullscreen", + "background-color": "Colore sfondo", + "text-color": "Colore testo", + "padding": "Padding", + "margin": "Margin", + "widget-style": "Stile Widget", + "title-style": "Stile titolo", + "mobile-mode-settings": "Impostazioni modalità mobile", + "order": "Ordinamento", + "height": "Altezza", + "units": "Simbolo speciale da mostrare vicino al valore", + "decimals": "Numero di cifre decimali", + "timewindow": "Timewindow", + "use-dashboard-timewindow": "Use dashboard timewindow", + "display-legend": "Mostra legenda", + "datasources": "Sorgenti dei dati", + "maximum-datasources": "Massimo { count, plural, 1 {1 sorgente dati consentita.} other {# sorgenti dati consentite} }", + "datasource-type": "Tipo", + "datasource-parameters": "Parametri", + "remove-datasource": "Rimuovi sorgente dati", + "add-datasource": "Aggiungi sorgente dati", + "target-device": "Dispositivo Target", + "alarm-source": "Sorgente Allarme", + "actions": "Azioni", + "action": "Azione", + "add-action": "Aggiungi azione", + "search-actions": "Ricerca azioni", + "action-source": "Sorgente azione", + "action-source-required": "Sorgente azione obbligatoria.", + "action-name": "Nome", + "action-name-required": "Nome azione obbligatorio.", + "action-name-not-unique": "Un'altra azione con lo stesso nome è già presente.
Il nome di una azione dovrebbe essere univoco all'interno della stessa sorgente.", + "action-icon": "Icona", + "action-type": "Tipo", + "action-type-required": "Tipo azione obbligatorio.", + "edit-action": "Modifica azione", + "delete-action": "Cancella azione", + "delete-action-title": "Cancella azione del widget", + "delete-action-text": "Sei sicuro di voler cancellare l'azione del widget '{{actionName}}'?" + }, + "widget-type": { + "import": "Importa un tipo di widget", + "export": "Esporta un tipo di widget", + "export-failed-error": "Impossibile esportare il tipo di widget: {{error}}", + "create-new-widget-type": "Crea un nuovo tipo di widget", + "widget-type-file": "Widget type file", + "invalid-widget-type-file-error": "Impossibile importare un tipo di widget: struttura dati del widget non valida." + }, + "icon": { + "icon": "Icona", + "select-icon": "Seleziona icona", + "material-icons": "Icone Material", + "show-all": "Mostra tutte le icone" + }, + "custom": { + "widget-action": { + "action-cell-button": "Action cell button", + "row-click": "On row click", + "marker-click": "On marker click", + "tooltip-tag-action": "Tooltip tag action" + } + }, + "language": { + "language": "Lingua", + "locales": { + "zh_CN": "Cinese", + "ko_KR": "Coreano", + "en_US": "Inglese", + "it_IT": "Italiano", + "ru_RU": "Russo", + "es_ES": "Spagnolo" + } + } +} diff --git a/ui/src/app/locale/locale.constant-ko.js b/ui/src/app/locale/locale.constant-ko.js deleted file mode 100644 index 91121577e1..0000000000 --- a/ui/src/app/locale/locale.constant-ko.js +++ /dev/null @@ -1,1354 +0,0 @@ -/* - * Copyright © 2016-2018 The Thingsboard Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -export default function addLocaleKorean(locales) { - var ko_KR = { - "access": { - "unauthorized": "권한 없음.", - "unauthorized-access": "허가되지 않은 접근", - "unauthorized-access-text": "이 리소스에 접근하려면 로그인해야 합니다!", - "access-forbidden": "접근 금지", - "access-forbidden-text": "접근 권한이 없습니다.!
만일 이 페이지에 계속 접근하려면 다른 사용자로 로그인 하세요.", - "refresh-token-expired": "세션이 만료되었습니다.", - "refresh-token-failed": "세션을 새로 고칠 수 없습니다." - }, - "action": { - "activate": "활설화", - "suspend": "비활성화", - "save": "저장", - "saveAs": "다른 이름으로 저장", - "cancel": "취소", - "ok": "확인", - "delete": "삭제", - "add": "추가", - "yes": "네", - "no": "아니오", - "update": "업데이트", - "remove": "제거", - "search": "검색", - "clear-search": "Clear search", // TODO - "assign": "할당", - "unassign": "비할당", - "share": "Share", // TODO - "make-private": "Make private", // TODO - "apply": "적용", - "apply-changes": "변경사항 적용", - "edit-mode": "수정 모드", - "enter-edit-mode": "수정 모드 진입", - "decline-changes": "변경사항 포기", - "close": "닫기", - "back": "뒤로", - "run": "실행", - "sign-in": "로그인!", - "edit": "수정", - "view": "보기", - "create": "만들기", - "drag": "끌기", - "refresh": "새로고침", - "undo": "취소", - "copy": "복사", - "paste": "붙여넣기", - "copy-reference": "Copy reference", // TODO - "paste-reference": "Paste reference", // TODO - "import": "가져오기", - "export": "내보내기", - "share-via": "Share via {{provider}}" // TODO - }, - "aggregation": { - "aggregation": "집합", - "function": "데이터 집합 함수", - "limit": "최대 값", - "group-interval": "그룹 간격", - "min": "최소", - "max": "최대", - "avg": "평균", - "sum": "합계", - "count": "숫자", - "none": "없음" - }, - "admin": { - "general": "일반", - "general-settings": "일반 설정", - "outgoing-mail": "메일 전송", - "outgoing-mail-settings": "메일 전송 설정", - "system-settings": "시스템 설정", - "test-mail-sent": "테스트 메일이 성공적으로 전송되었습니다!", - "base-url": "기본 URL", - "base-url-required": "기본 URL을 입력해야 합니다.", - "mail-from": "보내는 사람", - "mail-from-required": "보내는 사람을 입력해야 합니다.", - "smtp-protocol": "SMTP 프로토콜", - "smtp-host": "SMTP 호스트", - "smtp-host-required": "SMTP 호스트를 입력해야 합니다.", - "smtp-port": "SMTP 포트", - "smtp-port-required": "SMTP 포트를 입력해야 합니다.", - "smtp-port-invalid": "올바른 SMTP 포트가 아닙니다.", - "timeout-msec": "제한시간 (msec)", - "timeout-required": "제한시간을 입력해야 합니다.", - "timeout-invalid": "올바른 제한시간이 아닙니다.", - "enable-tls": "TLS 사용", - "send-test-mail": "테스트 메일 보내기" - }, - - "alarm": { // TODO - "alarm": "Alarm", - "alarms": "Alarms", - "select-alarm": "Select alarm", - "no-alarms-matching": "No alarms matching '{{entity}}' were found.", - "alarm-required": "Alarm is required", - "alarm-status": "Alarm status", - "search-status": { - "ANY": "Any", - "ACTIVE": "Active", - "CLEARED": "Cleared", - "ACK": "Acknowledged", - "UNACK": "Unacknowledged" - }, - "display-status": { - "ACTIVE_UNACK": "Active Unacknowledged", - "ACTIVE_ACK": "Active Acknowledged", - "CLEARED_UNACK": "Cleared Unacknowledged", - "CLEARED_ACK": "Cleared Acknowledged" - }, - "no-alarms-prompt": "No alarms found", - "created-time": "Created time", - "type": "Type", - "severity": "Severity", - "originator": "Originator", - "originator-type": "Originator type", - "details": "Details", - "status": "Status", - "alarm-details": "Alarm details", - "start-time": "Start time", - "end-time": "End time", - "ack-time": "Acknowledged time", - "clear-time": "Cleared time", - "severity-critical": "Critical", - "severity-major": "Major", - "severity-minor": "Minor", - "severity-warning": "Warning", - "severity-indeterminate": "Indeterminate", - "acknowledge": "Acknowledge", - "clear": "Clear", - "search": "Search alarms", - "selected-alarms": "{ count, select, 1 {1 alarm} other {# alarms} } selected", - "no-data": "No data to display", - "polling-interval": "Alarms polling interval (sec)", - "polling-interval-required": "Alarms polling interval is required.", - "min-polling-interval-message": "At least 1 sec polling interval is allowed.", - "aknowledge-alarms-title": "Acknowledge { count, select, 1 {1 alarm} other {# alarms} }", - "aknowledge-alarms-text": "Are you sure you want to acknowledge { count, select, 1 {1 alarm} other {# alarms} }?", - "clear-alarms-title": "Clear { count, select, 1 {1 alarm} other {# alarms} }", - "clear-alarms-text": "Are you sure you want to clear { count, select, 1 {1 alarm} other {# alarms} }?" - }, - "alias": { // TODO - "add": "Add alias", - "edit": "Edit alias", - "name": "Alias name", - "name-required": "Alias name is required", - "duplicate-alias": "Alias with same name is already exists.", - "filter-type-single-entity": "Single entity", - "filter-type-entity-list": "Entity list", - "filter-type-entity-name": "Entity name", - "filter-type-state-entity": "Entity from dashboard state", - "filter-type-state-entity-description": "Entity taken from dashboard state parameters", - "filter-type-asset-type": "Asset type", - "filter-type-asset-type-description": "Assets of type '{{assetType}}'", - "filter-type-asset-type-and-name-description": "Assets of type '{{assetType}}' and with name starting with '{{prefix}}'", - "filter-type-device-type": "Device type", - "filter-type-device-type-description": "Devices of type '{{deviceType}}'", - "filter-type-device-type-and-name-description": "Devices of type '{{deviceType}}' and with name starting with '{{prefix}}'", - "filter-type-relations-query": "Relations query", - "filter-type-relations-query-description": "{{entities}} that have {{relationType}} relation {{direction}} {{rootEntity}}", - "filter-type-asset-search-query": "Asset search query", - "filter-type-asset-search-query-description": "Assets with types {{assetTypes}} that have {{relationType}} relation {{direction}} {{rootEntity}}", - "filter-type-device-search-query": "Device search query", - "filter-type-device-search-query-description": "Devices with types {{deviceTypes}} that have {{relationType}} relation {{direction}} {{rootEntity}}", - "entity-filter": "Entity filter", - "resolve-multiple": "Resolve as multiple entities", - "filter-type": "Filter type", - "filter-type-required": "Filter type is required.", - "entity-filter-no-entity-matched": "No entities matching specified filter were found.", - "no-entity-filter-specified": "No entity filter specified", - "root-state-entity": "Use dashboard state entity as root", - "root-entity": "Root entity", - "state-entity-parameter-name": "State entity parameter name", - "default-state-entity": "Default state entity", - "default-entity-parameter-name": "By default", - "max-relation-level": "Max relation level", - "unlimited-level": "Unlimited level", - "state-entity": "Dashboard state entity", - "all-entities": "All entities", - "any-relation": "any" - }, - "asset": { // TODO - "asset": "Asset", - "assets": "Assets", - "management": "Asset management", - "view-assets": "View Assets", - "add": "Add Asset", - "assign-to-customer": "Assign to customer", - "assign-asset-to-customer": "Assign Asset(s) To Customer", - "assign-asset-to-customer-text": "Please select the assets to assign to the customer", - "no-assets-text": "No assets found", - "assign-to-customer-text": "Please select the customer to assign the asset(s)", - "public": "Public", - "assignedToCustomer": "Assigned to customer", - "make-public": "Make asset public", - "make-private": "Make asset private", - "unassign-from-customer": "Unassign from customer", - "delete": "Delete asset", - "asset-public": "Asset is public", - "asset-type": "Asset type", - "asset-type-required": "Asset type is required.", - "select-asset-type": "Select asset type", - "enter-asset-type": "Enter asset type", - "any-asset": "Any asset", - "no-asset-types-matching": "No asset types matching '{{entitySubtype}}' were found.", - "asset-type-list-empty": "No asset types selected.", - "asset-types": "Asset types", - "name": "Name", - "name-required": "Name is required.", - "description": "Description", - "type": "Type", - "type-required": "Type is required.", - "details": "Details", - "events": "Events", - "add-asset-text": "Add new asset", - "asset-details": "Asset details", - "assign-assets": "Assign assets", - "assign-assets-text": "Assign { count, select, 1 {1 asset} other {# assets} } to customer", - "delete-assets": "Delete assets", - "unassign-assets": "Unassign assets", - "unassign-assets-action-title": "Unassign { count, select, 1 {1 asset} other {# assets} } from customer", - "assign-new-asset": "Assign new asset", - "delete-asset-title": "Are you sure you want to delete the asset '{{assetName}}'?", - "delete-asset-text": "Be careful, after the confirmation the asset and all related data will become unrecoverable.", - "delete-assets-title": "Are you sure you want to delete { count, select, 1 {1 asset} other {# assets} }?", - "delete-assets-action-title": "Delete { count, select, 1 {1 asset} other {# assets} }", - "delete-assets-text": "Be careful, after the confirmation all selected assets will be removed and all related data will become unrecoverable.", - "make-public-asset-title": "Are you sure you want to make the asset '{{assetName}}' public?", - "make-public-asset-text": "After the confirmation the asset and all its data will be made public and accessible by others.", - "make-private-asset-title": "Are you sure you want to make the asset '{{assetName}}' private?", - "make-private-asset-text": "After the confirmation the asset and all its data will be made private and won't be accessible by others.", - "unassign-asset-title": "Are you sure you want to unassign the asset '{{assetName}}'?", - "unassign-asset-text": "After the confirmation the asset will be unassigned and won't be accessible by the customer.", - "unassign-asset": "Unassign asset", - "unassign-assets-title": "Are you sure you want to unassign { count, select, 1 {1 asset} other {# assets} }?", - "unassign-assets-text": "After the confirmation all selected assets will be unassigned and won't be accessible by the customer.", - "copyId": "Copy asset Id", - "idCopiedMessage": "Asset Id has been copied to clipboard", - "select-asset": "Select asset", - "no-assets-matching": "No assets matching '{{entity}}' were found.", - "asset-required": "Asset is required", - "name-starts-with": "Asset name starts with" - }, - "attribute": { - "attributes": "속성", - "latest-telemetry": "최근 데이터", - "attributes-scope": "디바이스 속성 범위", - "scope-latest-telemetry": "최근 데이터", - "scope-client": "클라이언트 속성", - "scope-server": "서버 속성", - "scope-shared": "공유 속성", - "add": "속성 추가", - "key": "Key", // TODO - "key-required": "속성 key를 입력하세요.", - "value": "Value", // TODO - "value-required": "속성 value를 입력하세요.", - "delete-attributes-title": "{ count, select, 1 {속성} other {여러 속성들을} } 삭제하시겠습니까??", - "delete-attributes-text": "모든 선택된 속성들이 제거 될 것이므로 주의하십시오.", - "delete-attributes": "속성 삭제", - "enter-attribute-value": "속성 값 입력", - "show-on-widget": "위젯 보기", - "widget-mode": "위젯 모드", - "next-widget": "다음 위젯", - "prev-widget": "이전 위젯", - "add-to-dashboard": "대시보드에 추가", - "add-widget-to-dashboard": "대시보드에 위젯 추가", - "selected-attributes": "{ count, select, 1 {속성 1개} other {속성 #개} } 선택됨", - "selected-telemetry": "{ count, select, 1 {최근 데이터 1개} other {최근 데이터 #개} } 선택됨" - }, - "audit-log": { // TODO - "audit": "Audit", - "audit-logs": "Audit Logs", - "timestamp": "Timestamp", - "entity-type": "Entity Type", - "entity-name": "Entity Name", - "user": "User", - "type": "Type", - "status": "Status", - "details": "Details", - "type-added": "Added", - "type-deleted": "Deleted", - "type-updated": "Updated", - "type-attributes-updated": "Attributes updated", - "type-attributes-deleted": "Attributes deleted", - "type-rpc-call": "RPC call", - "type-credentials-updated": "Credentials updated", - "type-assigned-to-customer": "Assigned to Customer", - "type-unassigned-from-customer": "Unassigned from Customer", - "type-activated": "Activated", - "type-suspended": "Suspended", - "type-credentials-read": "Credentials read", - "type-attributes-read": "Attributes read", - "status-success": "Success", - "status-failure": "Failure", - "audit-log-details": "Audit log details", - "no-audit-logs-prompt": "No logs found", - "action-data": "Action data", - "failure-details": "Failure details", - "search": "Search audit logs", - "clear-search": "Clear search" - }, - "confirm-on-exit": { - "message": "변경 사항을 저장하지 않았습니다. 이 페이지를 나가시겠습니까?", - "html-message": "변경 사항을 저장하지 않았습니다.
이 페이지를 나가시겠습니까?", - "title": "저장되지 않은 변경사항" - }, - "contact": { - "country": "국가", - "city": "시", - "state": "도", - "postal-code": "우편 번호", - "postal-code-invalid": "숫자만 입력하세요.", - "address": "주소", - "address2": "상세주소", - "phone": "전화번호", - "email": "Email", - "no-address": "주소 정보 없음" - }, - "common": { - "username": "사용자명", - "password": "비밀번호", - "enter-username": "사용자명을 입력하세요.", - "enter-password": "비밀번호를 입력하세요.", - "enter-search": "검색어 입력" - }, - "content-type": { // TODO - "json": "Json", - "text": "Text", - "binary": "Binary (Base64)" - }, - "customer": { - "customers": "커스터머", - "management": "커스터머 관리", - "dashboard": "커스터머 대시보드", - "dashboards": "커스터머 대시보드", - "devices": "커스터머 디바이스", - "add": "커스터머 추가", - "delete": "커스터머 삭제", - "manage-customer-users": "커스터머 사용자 관리", - "manage-customer-devices": "커스터머 디바이스 관리", - "manage-customer-dashboards": "커스터머 대시보드 관리", - "manage-public-devices": "Manage public devices", // TODO - "manage-public-dashboards": "Manage public dashboards", // TODO - "manage-customer-assets": "Manage customer assets", // TODO - "manage-public-assets": "Manage public assets", // TODO - "add-customer-text": "커스터머 추가", - "no-customers-text": "커스터머가 없습니다.", - "customer-details": "커스터머 상세정보", - "delete-customer-title": "'{{customerTitle}}' 커스터머를 삭제하시겠습니까?", - "delete-customer-text": "커스터머 및 관련된 모든 데이터를 복구할 수 없으므로 주의하십시오.", - "delete-customers-title": "{ count, select, 1 {커스터머 1개} other {커스터머 #개} }를 삭제하시겠습니까?", - "delete-customers-action-title": "{ count, select, 1 {커스터머 1개} other {커스터머 #개} } 삭제", - "delete-customers-text": "선택된 커스터머는 삭제되고 관련된 모든 데이터를 복구할 수 없으므로 주의하십시오.", - "manage-users": "사용자 관리", - "manage-devices": "디바이스 관리", - "manage-dashboards": "대시보드 관리", - "title": "타이틀", - "title-required": "타이틀을 입력하세요.", - "description": "설명", - "details": "Details", - "events": "Events", - "copyId": "Copy customer Id", - "idCopiedMessage": "Customer Id has been copied to clipboard", - "select-customer": "Select customer", - "no-customers-matching": "No customers matching '{{entity}}' were found.", - "customer-required": "Customer is required", - "select-default-customer": "Select default customer", - "default-customer": "Default customer", - "default-customer-required": "Default customer is required in order to debug dashboard on Tenant level" - }, - "datetime": { - "date-from": "시작 날짜", - "time-from": "시작 시간", - "date-to": "종료 날짜", - "time-to": "종료 시간" - }, - "dashboard": { - "dashboard": "대시보드", - "dashboards": "대시보드", - "management": "대시보드 관리", - "view-dashboards": "대시보드 보기", - "add": "대시보드 추가", - "assign-dashboard-to-customer": "대시보드 커스터머 선택", - "assign-dashboard-to-customer-text": "대시보드 커스터머를 선택하세요.", - "assign-to-customer-text": "대시보드 커스터머를 선택하세요.", - "assign-to-customer": "커스터머 선택", - "unassign-from-customer": "커스터머 해제", - "no-dashboards-text": "대시보드가 없습니다", - "no-widgets": "설정된 위젯 없음", - "add-widget": "위젯 추가", - "title": "타이틀", - "select-widget-title": "위젯 선택", - "select-widget-subtitle": "사용가능한 위젯 타입 목록", - "delete": "대시보드 삭제", - "title-required": "타이틀을 입력하세요.", - "description": "설명", - "details": "상세", - "dashboard-details": "대시보드 상세정보", - "add-dashboard-text": "대시보드 추가", - "assign-dashboards": "대시보드 지정", - "assign-new-dashboard": "새 대시보드 할당", - "assign-dashboards-text": "{ count, select, 1 {대시보드 1개} other {대시보드 #개} }를 커스터머 할당", - "delete-dashboards": "대시보드 삭제", - "unassign-dashboards": "대시보드 할당 취소", - "unassign-dashboards-action-title": "{ count, select, 1 {대시보드 1개} other {대시보드 #개} }를 커스터머 할당 취소", - "delete-dashboard-title": "'{{dashboardTitle}}' 대시보드를 삭제하시겠습니까?", - "delete-dashboard-text": "대시보드 및 관련된 모든 데이터를 복구할 수 없으므로 주의하십시오.", - "delete-dashboards-title": "{ count, select, 1 {대시보드 1개} other {대시보드 #개} }를 삭제하시겠습니까?", - "delete-dashboards-action-title": "{ count, select, 1 {대시보드 1개} other {대시보드 #개} } 삭제", - "delete-dashboards-text": "선택된 대시보드가 삭제되고 관련된 모든 데이터를 복구할 수 없으므로 주의하십시오.", - "unassign-dashboard-title": "'{{dashboardTitle}}' 대시보드 할당을 해제하시겠습니까?", - "unassign-dashboard-text": "대시보드가 할당 해제되고 커스터머는 액세스 할 수 없게됩니다.", - "unassign-dashboard": "대시보드 할달 취소", - "unassign-dashboards-title": "{ count, select, 1 {대시보드 1개} other {대시보드 #개} }의 할당을 취소하시겠습니까?", - "unassign-dashboards-text": "선택된 대시보드가 할당 해제되고 커스터머는 액세스 할 수 없게됩니다.", - "select-dashboard": "대시보드 선택", - "no-dashboards-matching": "'{{entity}}'와 일치하는 대시보드가 없습니다.", - "dashboard-required": "대시보드를 입력하세요.", - "select-existing": "기존 대시보드 선택", - "create-new": "대시보드 생성", - "new-dashboard-title": "새로운 대시보드 타이틀", - "open-dashboard": "대시보드 열기", - "set-background": "대시보드 설정", - "background-color": "배경색", - "background-image": "배경 이미지", - "background-size-mode": "배경 사이즈 모드", - "no-image": "이미지 없음", - "drop-image": "이곳에 이미지를 끌어다놓거나 이곳을 클릭하여 파일을 선택하고 업로드하세요.", - "settings": "설정", - "columns-count": "열 개수", - "columns-count-required": "열 개수를 입력하세요.", - "min-columns-count-message": "열 개수를 최소 10 이상 입력하세요.", - "max-columns-count-message": "열 개수를 최대 100 이하로 입력하세요.", - "widgets-margins": "위젯 사이 여백 크기", - "horizontal-margin": "세로 여백", - "horizontal-margin-required": "세로 여백 값을 입력하세요.", - "min-horizontal-margin-message": "세로 여백 값을 최소 0 이상 입력하세요.", - "max-horizontal-margin-message": "세로 여백 값을 최대 50 이하로 입력하세요.", - "vertical-margin": "가로 여백", - "vertical-margin-required": "가로 여백 값을 입력하세요.", - "min-vertical-margin-message": "가로 여백 값을 최소 0 이상 입력하세요.", - "max-vertical-margin-message": "가로 여백 값을 최대 50 이하로 입력하세요.", - "display-title": "대시보드 타이틀 표시", - "title-color": "타이틀 색상", - "import": "대시보드 가져오기", - "export": "대시보드 내보내기", - "export-failed-error": "대시보드 내보내기를 할 수 없습니다.: {error}", - "create-new-dashboard": "대시보드 생성", - "dashboard-file": "대시보드 파일", - "invalid-dashboard-file-error": "대시보드 가져오기를 할 수 없습니다.: 대시보드 데이터 구조가 잘못되었습니다.", - "dashboard-import-missing-aliases-title": "대시보드 앨리어스를 위해 누락 된 디바이스 선택", - "create-new-widget": "새로운 위젯 생성", - "import-widget": "위젯 가져오기", - "widget-file": "위젯 파일", - "invalid-widget-file-error": "위젯 가져오기를 할 수 없습니다: 위젯 데이터 구조가 잘못되었습니다.", - "widget-import-missing-aliases-title": "위젯에서 사용하는 누락 된 디바이스 선택", - "open-toolbar": "대시보드 툴바 열기", - "close-toolbar": "툴바 닫기", - "configuration-error": "구성 오류", - "alias-resolution-error-title": "대시보드 앨리어스 구성 오류", - "invalid-aliases-config": "일부 앨리어스 필터와 일치하는 디바이스를 찾을 수 없습니다.
이 문제를 해결하려면 관리자에게 문의하십시오.", - "select-devices": "디바이스 선택", - "assignedToCustomer": "커스터머에 할당됨" - }, - "datakey": { - "settings": "설정", - "advanced": "고급", - "label": "Label", - "color": "색상", - "data-generation-func": "데이터 생성 기능", - "use-data-post-processing-func": "데이터 후처리 기능 사용", - "configuration": "데이터 key 구성", - "timeseries": "Timeseries", - "attributes": "Attributes", - "timeseries-required": "디바이스 timeseries 를 입력하세요.", - "timeseries-or-attributes-required": "디바이스 timeseries/attributes 를 입력하세요.", - "maximum-timeseries-or-attributes": "Maximum { count, select, 1 {1 timeseries/attribute is allowed.} other {# timeseries/attributes are allowed} }", // TODO - "alarm-fields-required": "Alarm fields are required.", // TODO - "function-types": "함수 유형", - "function-types-required": "함수 유형을 입력하세요.", - "maximum-function-types": "Maximum { count, select, 1 {1 function type is allowed.} other {# function types are allowed} }" // TODO - }, - "datasource": { - "type": "데이터소스 유형", - "name": "Name", // TODO - "add-datasource-prompt": "데이터소스를 추가하세요." - }, - "details": { - "edit-mode": "편집 모드", - "toggle-edit-mode": "편집 모드 전환" - }, - "device": { - "device": "디바이스", - "device-required": "디바이스를 입력하세요.", - "devices": "디바이스", - "management": "디바이스 관리", - "view-devices": "디바이스 보기", - "device-alias": "디바이스 앨리어스", - "aliases": "디바이스 앨리어스", - "no-alias-matching": "'{{alias}}' 를 찾을 수 없습니다.", - "no-aliases-found": "앨리어스가 없습니다.", - "no-key-matching": "'{{key}}' 를 찾을 수 없습니다.", - "no-keys-found": "Key가 없습니다.", - "create-new-alias": "새로 만들기!", - "create-new-key": "새로 만들기!", - "duplicate-alias-error": "중복된 '{{alias}}' 앨리어스가 있습니다.
디바이스 앨리어스는 대시보드 내에서 고유해야 합니다.", - "configure-alias": "'{{alias}}' 앨리어스 구성", - "no-devices-matching": "'{{entity}}'와 일치하는 디바이스를 찾을 수 없습니다.", - "alias": "앨리어스", - "alias-required": "디바이스 앨리어스를 입력하세요.", - "remove-alias": "디바이스 앨리어스 삭제", - "add-alias": "디바이스 앨리어스 추가", - "name-starts-with": "시작되는 이름", - "device-list": "디바이스 리스트", - "use-device-name-filter": "필터 사용", - "device-list-empty": "선택된 디바이스가 없습니다.", - "device-name-filter-required": "디바이스 필터 이름을 입력하세요.", - "device-name-filter-no-device-matched": "'{{device}}' 로 시작되는 디바이스를 찾을 수 없습니다.", - "add": "디바이스 추가", - "assign-to-customer": "커스터머에게 할당", - "assign-device-to-customer": "디바이스를 커스터머에게 할당", - "assign-device-to-customer-text": "고객에게 할당할 디바이스를 선택하십시오.", - "no-devices-text": "디바이스 없음", - "assign-to-customer-text": "디바이스를 할당할 커스터머를 선택하세요.", - "device-details": "디바이스 상세정보", - "add-device-text": "디바이스 추가", - "credentials": "크리덴셜", - "manage-credentials": "크리덴셜 관리", - "delete": "디바이스 삭제", - "assign-devices": "디바이스 할당", - "assign-devices-text": "{ count, select, 1 {디바이스 1개} other {디바이스 #개} }를 커서터머에 할당", - "delete-devices": "디바이스 삭제", - "unassign-from-customer": "커스터머 할당 해제", - "unassign-devices": "디바이스 할당 취소", - "unassign-devices-action-title": "{ count, select, 1 {디바이스 1개} other {디바이스 #개} }를 커스터머에게서 할당 해제", - "assign-new-device": "새로운 디바이스 할당", - "view-credentials": "크리덴셜 보기", - "delete-device-title": "'{{deviceName}}' 디바이스를 삭제하시겠습니까?", - "delete-device-text": "디바이스 및 관련된 모든 데이터를 복구할 수 없으므로 주의하십시오.", - "delete-devices-title": "{ count, select, 1 {디바이스 1개} other {디바이스 #개} }를 삭제하시겠습니까?", - "delete-devices-action-title": "{ count, select, 1 {디바이스 1개} other {디바이스 #개} } 삭제", - "delete-devices-text": "선택된 디바이스가 삭제되고 관련된 모든 데이터를 복구할 수 없으므로 주의하십시오.", - "unassign-device-title": "'{{deviceName}}' 디바이스 할당을 해제하시겠습니까?", - "unassign-device-text": "디바이스가 할당 해제되고 커스터머는 액세스 할 수 없게됩니다.", - "unassign-device": "디바이스 할당 취소", - "unassign-devices-title": "{ count, select, 1 {디바이스 1개} other {디바이스 #개} }의 할당을 해제하시겠습니까??", - "unassign-devices-text": "선택된 디바이스가 할당 해제되고 커스터머는 액세스 할 수 없게됩니다.", - "device-credentials": "디바이스 크리덴셜", - "credentials-type": "크리덴셜 타입", - "access-token": "억세스 토큰", - "access-token-required": "액세스 토큰을 입력하세요.", - "access-token-invalid": "액세스 토큰 길이는 1 - 20 자 여야합니다.", - "rsa-key": "RSA public key", - "rsa-key-required": "RSA public key 를 입력하세요.", - "secret": "시크릿", - "secret-required": "시크릿을 입력하세요.", - "name": "이름", - "name-required": "이름을 입력하세요.", - "description": "설명", - "events": "이벤트", - "details": "상세", - "copyId": "디바이스 아이디 복사", - "copyAccessToken": "억세스 토큰 복사", - "idCopiedMessage": "디바이스 아이디가 클립보드에 복사되었습니다.", - "accessTokenCopiedMessage": "디바이스 억세스 토큰이 클립보드에 복사되었습니다.", - "assignedToCustomer": "커스터머에 할당됨", - "unable-delete-device-alias-title": "디바이스 앨리어스를 삭제할 수 없습니다.", - "unable-delete-device-alias-text": "'{{deviceAlias}}' 디바이스 앨리어스를 삭제할 수 없습니다. 다음 위젯에서 사용하고 있습니다.
{{widgetsList}}", - "is-gateway": "게이트웨이 여부" - }, - "dialog": { - "close": "다이얼로그 닫기" - }, - "error": { - "unable-to-connect": "서버에 연결할 수 없습니다! 인터넷 연결을 확인하십시오.", - "unhandled-error-code": "처리되지 않은 오류 코드: {{errorCode}}", - "unknown-error": "알 수 없는 오류" - }, - "entity": { // TODO - "entity": "Entity", - "entities": "Entities", - "aliases": "Entity aliases", - "entity-alias": "Entity alias", - "unable-delete-entity-alias-title": "Unable to delete entity alias", - "unable-delete-entity-alias-text": "Entity alias '{{entityAlias}}' can't be deleted as it used by the following widget(s):
{{widgetsList}}", - "duplicate-alias-error": "Duplicate alias found '{{alias}}'.
Entity aliases must be unique whithin the dashboard.", - "missing-entity-filter-error": "Filter is missing for alias '{{alias}}'.", - "configure-alias": "Configure '{{alias}}' alias", - "alias": "Alias", - "alias-required": "Entity alias is required.", - "remove-alias": "Remove entity alias", - "add-alias": "Add entity alias", - "entity-list": "Entity list", - "entity-type": "Entity type", - "entity-types": "Entity types", - "entity-type-list": "Entity type list", - "any-entity": "Any entity", - "enter-entity-type": "Enter entity type", - "no-entities-matching": "No entities matching '{{entity}}' were found.", - "no-entity-types-matching": "No entity types matching '{{entityType}}' were found.", - "name-starts-with": "Name starts with", - "use-entity-name-filter": "Use filter", - "entity-list-empty": "No entities selected.", - "entity-type-list-empty": "No entity types selected.", - "entity-name-filter-required": "Entity name filter is required.", - "entity-name-filter-no-entity-matched": "No entities starting with '{{entity}}' were found.", - "all-subtypes": "All", - "select-entities": "Select entities", - "no-aliases-found": "No aliases found.", - "no-alias-matching": "'{{alias}}' not found.", - "create-new-alias": "Create a new one!", - "key": "Key", - "key-name": "Key name", - "no-keys-found": "No keys found.", - "no-key-matching": "'{{key}}' not found.", - "create-new-key": "Create a new one!", - "type": "Type", - "type-required": "Entity type is required.", - "type-device": "Device", - "type-devices": "Devices", - "list-of-devices": "{ count, select, 1 {One device} other {List of # devices} }", - "device-name-starts-with": "Devices whose names start with '{{prefix}}'", - "type-asset": "Asset", - "type-assets": "Assets", - "list-of-assets": "{ count, select, 1 {One asset} other {List of # assets} }", - "asset-name-starts-with": "Assets whose names start with '{{prefix}}'", - "type-rule": "Rule", - "type-rules": "Rules", - "list-of-rules": "{ count, select, 1 {One rule} other {List of # rules} }", - "rule-name-starts-with": "Rules whose names start with '{{prefix}}'", - "type-plugin": "Plugin", - "type-plugins": "Plugins", - "list-of-plugins": "{ count, select, 1 {One plugin} other {List of # plugins} }", - "plugin-name-starts-with": "Plugins whose names start with '{{prefix}}'", - "type-tenant": "Tenant", - "type-tenants": "Tenants", - "list-of-tenants": "{ count, select, 1 {One tenant} other {List of # tenants} }", - "tenant-name-starts-with": "Tenants whose names start with '{{prefix}}'", - "type-customer": "Customer", - "type-customers": "Customers", - "list-of-customers": "{ count, select, 1 {One customer} other {List of # customers} }", - "customer-name-starts-with": "Customers whose names start with '{{prefix}}'", - "type-user": "User", - "type-users": "Users", - "list-of-users": "{ count, select, 1 {One user} other {List of # users} }", - "user-name-starts-with": "Users whose names start with '{{prefix}}'", - "type-dashboard": "Dashboard", - "type-dashboards": "Dashboards", - "list-of-dashboards": "{ count, select, 1 {One dashboard} other {List of # dashboards} }", - "dashboard-name-starts-with": "Dashboards whose names start with '{{prefix}}'", - "type-alarm": "Alarm", - "type-alarms": "Alarms", - "list-of-alarms": "{ count, select, 1 {One alarms} other {List of # alarms} }", - "alarm-name-starts-with": "Alarms whose names start with '{{prefix}}'", - "type-rulechain": "Rule chain", - "type-rulechains": "Rule chains", - "list-of-rulechains": "{ count, select, 1 {One rule chain} other {List of # rule chains} }", - "rulechain-name-starts-with": "Rule chains whose names start with '{{prefix}}'", - "type-current-customer": "Current Customer", - "search": "Search entities", - "selected-entities": "{ count, select, 1 {1 entity} other {# entities} } selected", - "entity-name": "Entity name", - "details": "Entity details", - "no-entities-prompt": "No entities found", - "no-data": "No data to display" - }, - "event": { - "event-type": "이벤트 타입", - "type-error": "에러", - "type-lc-event": "주기적 이벤트", - "type-stats": "통계", - "type-debug-rule-node": "Debug", // TODO - "type-debug-rule-chain": "Debug", // TODO - "no-events-prompt": "이벤트 없음", - "error": "에러", - "alarm": "알람", - "event-time": "이벤트 발생 시간", - "server": "서버", - "body": "Body", - "method": "Method", - "type": "Type", // TODO - "entity": "Entity", // TODO - "message-id": "Message Id", // TODO - "message-type": "Message Type", // TODO - "data-type": "Data Type", // TODO - "relation-type": "Relation Type", // TODO - "metadata": "Metadata", // TODO - "data": "Data", // TODO - "event": "이벤트", - "status": "상태", - "success": "성공", - "failed": "실패", - "messages-processed": "처리된 메시지", - "errors-occurred": "오류가 발생했습니다" - }, - "extension": { // TODO - "extensions": "Extensions", - "selected-extensions": "{ count, select, 1 {1 extension} other {# extensions} } selected", - "type": "Type", - "key": "Key", - "value": "Value", - "id": "Id", - "extension-id": "Extension id", - "extension-type": "Extension type", - "transformer-json": "JSON *", - "unique-id-required": "Current extension id already exists.", - "delete": "Delete extension", - "add": "Add extension", - "edit": "Edit extension", - "delete-extension-title": "Are you sure you want to delete the extension '{{extensionId}}'?", - "delete-extension-text": "Be careful, after the confirmation the extension and all related data will become unrecoverable.", - "delete-extensions-title": "Are you sure you want to delete { count, select, 1 {1 extension} other {# extensions} }?", - "delete-extensions-text": "Be careful, after the confirmation all selected extensions will be removed.", - "converters": "Converters", - "converter-id": "Converter id", - "configuration": "Configuration", - "converter-configurations": "Converter configurations", - "token": "Security token", - "add-converter": "Add converter", - "add-config": "Add converter configuration", - "device-name-expression": "Device name expression", - "device-type-expression": "Device type expression", - "custom": "Custom", - "to-double": "To Double", - "transformer": "Transformer", - "json-required": "Transformer json is required.", - "json-parse": "Unable to parse transformer json.", - "attributes": "Attributes", - "add-attribute": "Add attribute", - "add-map": "Add mapping element", - "timeseries": "Timeseries", - "add-timeseries": "Add timeseries", - "field-required": "Field is required", - "brokers": "Brokers", - "add-broker": "Add broker", - "host": "Host", - "port": "Port", - "port-range": "Port should be in a range from 1 to 65535.", - "ssl": "Ssl", - "credentials": "Credentials", - "username": "Username", - "password": "Password", - "retry-interval": "Retry interval in milliseconds", - "anonymous": "Anonymous", - "basic": "Basic", - "pem": "PEM", - "ca-cert": "CA certificate file *", - "private-key": "Private key file *", - "cert": "Certificate file *", - "no-file": "No file selected.", - "drop-file": "Drop a file or click to select a file to upload.", - "mapping": "Mapping", - "topic-filter": "Topic filter", - "converter-type": "Converter type", - "converter-json": "Json", - "json-name-expression": "Device name json expression", - "topic-name-expression": "Device name topic expression", - "json-type-expression": "Device type json expression", - "topic-type-expression": "Device type topic expression", - "attribute-key-expression": "Attribute key expression", - "attr-json-key-expression": "Attribute key json expression", - "attr-topic-key-expression": "Attribute key topic expression", - "request-id-expression": "Request id expression", - "request-id-json-expression": "Request id json expression", - "request-id-topic-expression": "Request id topic expression", - "response-topic-expression": "Response topic expression", - "value-expression": "Value expression", - "topic": "Topic", - "timeout": "Timeout in milliseconds", - "converter-json-required": "Converter json is required.", - "converter-json-parse": "Unable to parse converter json.", - "filter-expression": "Filter expression", - "connect-requests": "Connect requests", - "add-connect-request": "Add connect request", - "disconnect-requests": "Disconnect requests", - "add-disconnect-request": "Add disconnect request", - "attribute-requests": "Attribute requests", - "add-attribute-request": "Add attribute request", - "attribute-updates": "Attribute updates", - "add-attribute-update": "Add attribute update", - "server-side-rpc": "Server side RPC", - "add-server-side-rpc-request": "Add server-side RPC request", - "device-name-filter": "Device name filter", - "attribute-filter": "Attribute filter", - "method-filter": "Method filter", - "request-topic-expression": "Request topic expression", - "response-timeout": "Response timeout in milliseconds", - "topic-expression": "Topic expression", - "client-scope": "Client scope", - "add-device": "Add device", - "opc-server": "Servers", - "opc-add-server": "Add server", - "opc-add-server-prompt": "Please add server", - "opc-application-name": "Application name", - "opc-application-uri": "Application uri", - "opc-scan-period-in-seconds": "Scan period in seconds", - "opc-security": "Security", - "opc-identity": "Identity", - "opc-keystore": "Keystore", - "opc-type": "Type", - "opc-keystore-type": "Type", - "opc-keystore-location": "Location *", - "opc-keystore-password": "Password", - "opc-keystore-alias": "Alias", - "opc-keystore-key-password": "Key password", - "opc-device-node-pattern": "Device node pattern", - "opc-device-name-pattern": "Device name pattern", - "modbus-server": "Servers/slaves", - "modbus-add-server": "Add server/slave", - "modbus-add-server-prompt": "Please add server/slave", - "modbus-transport": "Transport", - "modbus-port-name": "Serial port name", - "modbus-encoding": "Encoding", - "modbus-parity": "Parity", - "modbus-baudrate": "Baud rate", - "modbus-databits": "Data bits", - "modbus-stopbits": "Stop bits", - "modbus-databits-range": "Data bits should be in a range from 7 to 8.", - "modbus-stopbits-range": "Stop bits should be in a range from 1 to 2.", - "modbus-unit-id": "Unit ID", - "modbus-unit-id-range": "Unit ID should be in a range from 1 to 247.", - "modbus-device-name": "Device name", - "modbus-poll-period": "Poll period (ms)", - "modbus-attributes-poll-period": "Attributes poll period (ms)", - "modbus-timeseries-poll-period": "Timeseries poll period (ms)", - "modbus-poll-period-range": "Poll period should be positive value.", - "modbus-tag": "Tag", - "modbus-function": "Function", - "modbus-register-address": "Register address", - "modbus-register-address-range": "Register address should be in a range from 0 to 65535.", - "modbus-register-bit-index": "Bit index", - "modbus-register-bit-index-range": "Bit index should be in a range from 0 to 15.", - "modbus-register-count": "Register count", - "modbus-register-count-range": "Register count should be a positive value.", - "modbus-byte-order": "Byte order", - - "sync": { - "status": "Status", - "sync": "Sync", - "not-sync": "Not sync", - "last-sync-time": "Last sync time", - "not-available": "Not available" - }, - - "export-extensions-configuration": "Export extensions configuration", - "import-extensions-configuration": "Import extensions configuration", - "import-extensions": "Import extensions", - "import-extension": "Import extension", - "export-extension": "Export extension", - "file": "Extensions file", - "invalid-file-error": "Invalid extension file" - }, - "fullscreen": { - "expand": "전체화면으로 확장", - "exit": "전체화면 종료", - "toggle": "전체화면 모드 전환", - "fullscreen": "전체화면" - }, - "function": { - "function": "기능" - }, - "grid": { - "delete-item-title": "이 항목을 삭제 하시겠습니까?", - "delete-item-text": "항목과 모든 관련 데이터를 복구 할 수 없으므로 주의하십시오.", - "delete-items-title": "{ count, select, 1 {아이템 1개} other {아이템 #개} }를 삭제하시겠습니까?", - "delete-items-action-title": "{ count, select, 1 {아이템 1개} other {아이템 #개} } 삭제", - "delete-items-text": "선택한 모든 아이템이 제거되고 관련된 모든 데이터는 복구 할 수 없으므로 주의하십시오.", - "add-item-text": "새로운 아이템 추가", - "no-items-text": "아이템이 없습니다.", - "item-details": "아이템 상세", - "delete-item": "아이템 삭제", - "delete-items": "아이템 삭제", - "scroll-to-top": "스크롤 맨 위로" - }, - "help": { - "goto-help-page": "도움" - }, - "home": { - "home": "홈", - "profile": "프로파일", - "logout": "로그아웃", - "menu": "메뉴", - "avatar": "Avatar", - "open-user-menu": "사용자 메뉴 열기" - }, - "import": { - "no-file": "선택된 파일이 없습니다.", - "drop-file": "JSON 파일을 끌어다 놓거나 클릭하여 업로드 할 파일을 선택하십시오." - }, - "item": { - "selected": "선택됨" - }, - "js-func": { - "no-return-error": "함수는 값을 반환해야 합니다!", - "return-type-mismatch": "함수는 '{{type}}' 유형의 값을 반환해야 합니다!", - "tidy": "Tidy" // TODO - }, - "key-val": { // TODO - "key": "Key", - "value": "Value", - "remove-entry": "Remove entry", - "add-entry": "Add entry", - "no-data": "No entries" - }, - "layout": { // TODO - "layout": "Layout", - "manage": "Manage layouts", - "settings": "Layout settings", - "color": "Color", - "main": "Main", - "right": "Right", - "select": "Select target layout" - }, - "legend": { - "position": "범례 위치", - "show-max": "최대값 표시", - "show-min": "최소값 표시", - "show-avg": "평균값 표시", - "show-total": "총합 표시", - "settings": "범례 설정", - "min": "최소", - "max": "최대", - "avg": "평균", - "total": "합계" - }, - "login": { - "login": "로그인", - "request-password-reset": "비밀번호 재설정", - "reset-password": "비밀번호 재설정", - "create-password": "비밀번호 생성", - "passwords-mismatch-error": "입력된 비밀번호는 같아야 합니다!", - "password-again": "비밀번호 확인", - "sign-in": "로그인", - "username": "사용자명 (이메일)", - "remember-me": "아이디 저장", - "forgot-password": "비밀번호찾기", - "password-reset": "비밀번호 재설정", - "new-password": "새 비밀번호", - "new-password-again": "새 비밀번호 확인", - "password-link-sent-message": "비밀번호 재설정 링크가 성공적으로 전송되었습니다!", - "email": "이메일" - }, - "position": { - "top": "상단", - "bottom": "하단", - "left": "왼쪽", - "right": "오른쪽" - }, - "profile": { - "profile": "프로파일", - "change-password": "비밀번호 변경", - "current-password": "현재 비밀번호" - }, - "relation": { // TODO - "relations": "Relations", - "direction": "Direction", - "search-direction": { - "FROM": "From", - "TO": "To" - }, - "direction-type": { - "FROM": "from", - "TO": "to" - }, - "from-relations": "Outbound relations", - "to-relations": "Inbound relations", - "selected-relations": "{ count, select, 1 {1 relation} other {# relations} } selected", - "type": "Type", - "to-entity-type": "To entity type", - "to-entity-name": "To entity name", - "from-entity-type": "From entity type", - "from-entity-name": "From entity name", - "to-entity": "To entity", - "from-entity": "From entity", - "delete": "Delete relation", - "relation-type": "Relation type", - "relation-type-required": "Relation type is required.", - "any-relation-type": "Any type", - "add": "Add relation", - "edit": "Edit relation", - "delete-to-relation-title": "Are you sure you want to delete relation to the entity '{{entityName}}'?", - "delete-to-relation-text": "Be careful, after the confirmation the entity '{{entityName}}' will be unrelated from the current entity.", - "delete-to-relations-title": "Are you sure you want to delete { count, select, 1 {1 relation} other {# relations} }?", - "delete-to-relations-text": "Be careful, after the confirmation all selected relations will be removed and corresponding entities will be unrelated from the current entity.", - "delete-from-relation-title": "Are you sure you want to delete relation from the entity '{{entityName}}'?", - "delete-from-relation-text": "Be careful, after the confirmation current entity will be unrelated from the entity '{{entityName}}'.", - "delete-from-relations-title": "Are you sure you want to delete { count, select, 1 {1 relation} other {# relations} }?", - "delete-from-relations-text": "Be careful, after the confirmation all selected relations will be removed and current entity will be unrelated from the corresponding entities.", - "remove-relation-filter": "Remove relation filter", - "add-relation-filter": "Add relation filter", - "any-relation": "Any relation", - "relation-filters": "Relation filters", - "additional-info": "Additional info (JSON)", - "invalid-additional-info": "Unable to parse additional info json." - }, - "rulechain": { // TODO - "rulechain": "Rule chain", - "rulechains": "Rule chains", - "root": "Root", - "delete": "Delete rule chain", - "name": "Name", - "name-required": "Name is required.", - "description": "Description", - "add": "Add Rule Chain", - "set-root": "Make rule chain root", - "set-root-rulechain-title": "Are you sure you want to make the rule chain '{{ruleChainName}}' root?", - "set-root-rulechain-text": "After the confirmation the rule chain will become root and will handle all incoming transport messages.", - "delete-rulechain-title": "Are you sure you want to delete the rule chain '{{ruleChainName}}'?", - "delete-rulechain-text": "Be careful, after the confirmation the rule chain and all related data will become unrecoverable.", - "delete-rulechains-title": "Are you sure you want to delete { count, select, 1 {1 rule chain} other {# rule chains} }?", - "delete-rulechains-action-title": "Delete { count, select, 1 {1 rule chain} other {# rule chains} }", - "delete-rulechains-text": "Be careful, after the confirmation all selected rule chains will be removed and all related data will become unrecoverable.", - "add-rulechain-text": "Add new rule chain", - "no-rulechains-text": "No rule chains found", - "rulechain-details": "Rule chain details", - "details": "Details", - "events": "Events", - "system": "System", - "import": "Import rule chain", - "export": "Export rule chain", - "export-failed-error": "Unable to export rule chain: {{error}}", - "create-new-rulechain": "Create new rule chain", - "rulechain-file": "Rule chain file", - "invalid-rulechain-file-error": "Unable to import rule chain: Invalid rule chain data structure.", - "copyId": "Copy rule chain Id", - "idCopiedMessage": "Rule chain Id has been copied to clipboard", - "select-rulechain": "Select rule chain", - "no-rulechains-matching": "No rule chains matching '{{entity}}' were found.", - "rulechain-required": "Rule chain is required", - "management": "Rules management", - "debug-mode": "Debug mode" - }, - "rulenode": { // TODO - "details": "Details", - "events": "Events", - "search": "Search nodes", - "open-node-library": "Open node library", - "add": "Add rule node", - "name": "Name", - "name-required": "Name is required.", - "type": "Type", - "description": "Description", - "delete": "Delete rule node", - "select-all-objects": "Select all nodes and connections", - "deselect-all-objects": "Deselect all nodes and connections", - "delete-selected-objects": "Delete selected nodes and connections", - "delete-selected": "Delete selected", - "select-all": "Select all", - "copy-selected": "Copy selected", - "deselect-all": "Deselect all", - "rulenode-details": "Rule node details", - "debug-mode": "Debug mode", - "configuration": "Configuration", - "link": "Link", - "link-details": "Rule node link details", - "add-link": "Add link", - "link-label": "Link label", - "link-label-required": "Link label is required.", - "custom-link-label": "Custom link label", - "custom-link-label-required": "Custom link label is required.", - "type-filter": "Filter", - "type-filter-details": "Filter incoming messages with configured conditions", - "type-enrichment": "Enrichment", - "type-enrichment-details": "Add additional information into Message Metadata", - "type-transformation": "Transformation", - "type-transformation-details": "Change Message payload and Metadata", - "type-action": "Action", - "type-action-details": "Perform special action", - "type-external": "External", - "type-external-details": "Interacts with external system", - "type-rule-chain": "Rule Chain", - "type-rule-chain-details": "Forwards incoming messages to specified Rule Chain", - "type-input": "Input", - "type-input-details": "Logical input of Rule Chain, forwards incoming messages to next related Rule Node", - "directive-is-not-loaded": "Defined configuration directive '{{directiveName}}' is not available.", - "ui-resources-load-error": "Failed to load configuration ui resources.", - "invalid-target-rulechain": "Unable to resolve target rule chain!", - "test-script-function": "Test script function", - "message": "Message", - "message-type": "Message type", - "message-type-required": "Message type is required", - "metadata": "Metadata", - "metadata-required": "Metadata entries can't be empty.", - "output": "Output", - "test": "Test", - "help": "Help" - }, - "tenant": { - "tenants": "테넌트", - "management": "테넌트 관리", - "add": "테넌트 추가", - "admins": "Admins", - "manage-tenant-admins": "테넌트 관리자 관리", - "delete": "테넌트 삭제", - "add-tenant-text": "테넌트 추가", - "no-tenants-text": "테넌트가 없습니다.", - "tenant-details": "테넌트 상세정보", - "delete-tenant-title": "'{{tenantTitle}}' 테넌트를 삭제하시겠습니까?", - "delete-tenant-text": "테넌트와 관련된 모든 정보를 복구할 수 없으므로 주의하십시오.", - "delete-tenants-title": "{ count, select, 1 {테넌트 1개} other {테넌트 #개} }를 삭제하시겠습니까?", - "delete-tenants-action-title": "{ count, select, 1 {테넌트 1개} other {테넌트 #개} } 삭제", - "delete-tenants-text": "선택된 테넌트가 삭제되고 관련된 모든 정보를 복구할 수 없으므로 주의하십시오.", - "title": "타이틀", - "title-required": "타이틀을 입력하세요.", - "description": "설명", - "details": "Details", // TODO - "events": "Events", // TODO - "copyId": "Copy tenant Id", // TODO - "idCopiedMessage": "Tenant Id has been copied to clipboard", // TODO - "select-tenant": "Select tenant", // TODO - "no-tenants-matching": "No tenants matching '{{entity}}' were found.", - "tenant-required": "Tenant is required" // TODO - }, - "timeinterval": { - "seconds-interval": "{ seconds, select, 1 {1 second} other {# seconds} }", - "minutes-interval": "{ minutes, select, 1 {1 minute} other {# minutes} }", - "hours-interval": "{ hours, select, 1 {1 hour} other {# hours} }", - "days-interval": "{ days, select, 1 {1 day} other {# days} }", - "days": "Days", - "hours": "Hours", - "minutes": "Minutes", - "seconds": "Seconds", - "advanced": "고급" - }, - "timewindow": { - "days": "{ days, select, 1 { day } other {# days } }", - "hours": "{ hours, select, 0 { hour } 1 {1 hour } other {# hours } }", - "minutes": "{ minutes, select, 0 { minute } 1 {1 minute } other {# minutes } }", - "seconds": "{ seconds, select, 0 { second } 1 {1 second } other {# seconds } }", - "realtime": "Realtime", - "history": "History", - "last-prefix": "last", - "period": "from {{ startTime }} to {{ endTime }}", - "edit": "타임윈도우 편집", - "date-range": "날짜 범위", - "last": "Last", - "time-period": "기간" - }, - "user": { - "users": "사용자", - "customer-users": "커스터머 사용자", - "tenant-admins": "테넌트 관리자", - "sys-admin": "시스템 관리자", - "tenant-admin": "테넌트 관리자", - "customer": "커스터머", - "anonymous": "Anonymous", - "add": "사용자 추가", - "delete": "사용자 삭제", - "add-user-text": "새로운 사용자 추가", - "no-users-text": "사용자가 없습니다.", - "user-details": "사용자 상세정보", - "delete-user-title": "'{{userEmail}}' 사용자를 삭제하시겠습니까?", - "delete-user-text": "사용자와 관련된 모든 데이터를 복구할 수 없으므로 주의하십시오.", - "delete-users-title": "{ count, select, 1 {사용자 1명} other {사용자 #명} }을 삭제하시겠니까?", - "delete-users-action-title": "{ count, select, 1 {사용자 1명} other {사용자 #명} } 삭제", - "delete-users-text": "선택된 사용자가 삭제된고 관련된 모든 데이터를 복구할 수 없으므로 주의하십시오.", - "activation-email-sent-message": "활성화 이메일을 보냈습니다!", - "resend-activation": "활성화 재전송", - "email": "Email", - "email-required": "Email을 입력하세요.", - "first-name": "이름", - "last-name": "성", - "description": "설명", - "default-dashboard": "기본 대시보드", - "always-fullscreen": "항상 전체화면", - "select-user": "Select user", // TODO - "no-users-matching": "No users matching '{{entity}}' were found.", // TODO - "user-required": "User is required", // TODO - "activation-method": "Activation method", // TODO - "display-activation-link": "Display activation link", // TODO - "send-activation-mail": "Send activation mail", // TODO - "activation-link": "User activation link", // TODO - "activation-link-text": "In order to activate user use the following activation link :", // TODO - "copy-activation-link": "Copy activation link", // TODO - "activation-link-copied-message": "User activation link has been copied to clipboard", // TODO - "details": "Details" // TODO - }, - "value": { - "type": "Value type", - "string": "String", - "string-value": "String value", - "integer": "Integer", - "integer-value": "Integer value", - "invalid-integer-value": "Invalid integer value", - "double": "Double", - "double-value": "Double value", - "boolean": "Boolean", - "boolean-value": "Boolean value", - "false": "False", - "true": "True" - }, - "widget": { - "widget-library": "위젯 저장소", - "widget-bundle": "위젯 번들", - "select-widgets-bundle": "위젯 번들 선택", - "management": "위젯 관리", - "editor": "위젯 편집기", - "widget-type-not-found": "위젯 구성을 로드하는 중 문제가 발생했습니다.
연결된 위젯 타입이 삭제되었습니다.", - "widget-type-load-error": "다음과 같은 오류로 인해 위젯이로드되지 않았습니다:", - "remove": "위젯 삭제", - "edit": "위젯 수정", - "remove-widget-title": "'{{widgetTitle}}' 위젯을 삭제하시겠습니까?", - "remove-widget-text": "위젯과 관련된 모든 데이터를 복구할 수 없으므로 주의하십시오.", - "timeseries": "Time series", - "latest-values": "Latest values", - "rpc": "Control 위젯", - "static": "Static 위젯", - "select-widget-type": "위젯 타입 선택", - "missing-widget-title-error": "위젯 타이틀을 입력하세요!", - "widget-saved": "위젯이 저장되었습니다.", - "unable-to-save-widget-error": "위젯을 저장할 수 없습니다! 위젯에 오류가 있습니다!", - "save": "위젯 저장", - "saveAs": "다른 이름으로 위젯 저장", - "save-widget-type-as": "다른 이름으로 위젯 타입 저장", - "save-widget-type-as-text": "새로운 위젯 이름과 위젯 번들을 선택하세요.", - "toggle-fullscreen": "전체화면 전환", - "run": "위젯 실행", - "title": "위젯 타이틀", - "title-required": "위젯 타이틀을 입력하세요.", - "type": "위젯 타입", - "resources": "리소스", - "resource-url": "JavaScript/CSS URI", - "remove-resource": "리소스 삭제", - "add-resource": "리소스 추가", - "html": "HTML", - "tidy": "Tidy", - "css": "CSS", - "settings-schema": "스키마 설정", - "datakey-settings-schema": "데이터 키 설정 스키마", - "javascript": "Javascript", - "remove-widget-type-title": "'{{widgetName}}' 위젯 타입을 삭제하시겠습니까?", - "remove-widget-type-text": "위젯 타입과 관련된 모든 데이터를 복구할 수 없으므로 주의하십시오.", - "remove-widget-type": "위젯 타입 삭제", - "add-widget-type": "새로운 위젯 타입 추가", - "widget-type-load-failed-error": "위젯 타입을 로드하지 못했습니다!", - "widget-template-load-failed-error": "위젯 템플릿을 로드하지 못했습니다!", - "add": "위젯 추가", - "undo": "위젯 변경사항 취소", - "export": "위젯 내보내기" - }, - "widget-action": { // TODO - "header-button": "Widget header button", - "open-dashboard-state": "Navigate to new dashboard state", - "update-dashboard-state": "Update current dashboard state", - "open-dashboard": "Navigate to other dashboard", - "custom": "Custom action", - "target-dashboard-state": "Target dashboard state", - "target-dashboard-state-required": "Target dashboard state is required", - "set-entity-from-widget": "Set entity from widget", - "target-dashboard": "Target dashboard", - "open-right-layout": "Open right dashboard layout (mobile view)" - }, - "widgets-bundle": { - "current": "현재 번들", - "widgets-bundles": "위젯 번들", - "add": "위젯 번들 추가", - "delete": "위젯 번들 삭제", - "title": "타이틀", - "title-required": "타이틀을 입력하세요.", - "add-widgets-bundle-text": "위젯 번들 추가", - "no-widgets-bundles-text": "위젯 번들이 없습니다.", - "empty": "위젯 번들이 비어있습니다.", - "details": "상세", - "widgets-bundle-details": "위젯 번들 상세정보", - "delete-widgets-bundle-title": "'{{widgetsBundleTitle}}' 위젯 번들을 삭제하시겠습니까?", - "delete-widgets-bundle-text": "위젯 번들과 관련된 모든 데이터를 복구할 수 없으므로 주의하십시오.", - "delete-widgets-bundles-title": "{ count, select, 1 {위젯 번들 1개} other {위젯 번들 #개} }를 삭제하시겠습니까?", - "delete-widgets-bundles-action-title": "{ count, select, 1 {위젯 번들 1개} other {위젯 번들 #개} } 삭제", - "delete-widgets-bundles-text": "선택된 위젯 번들이 삭제되고 관련된 모든 데이터를 복구할 수 없으므로 주의하십시오.", - "no-widgets-bundles-matching": "'{{widgetsBundle}}' 와(과) 일치하는 위젯 번들을 찾을 수 없습니다.", - "widgets-bundle-required": "위젯 번들을 입력하세요.", - "system": "시스템", - "import": "위젯 번들 가져오기", - "export": "위젯 번들 내보내기", - "export-failed-error": "위젯 번들을 내보내기 할 수 없습니다.: {{error}}", - "create-new-widgets-bundle": "새로운 위젯 번들 생성", - "widgets-bundle-file": "위젯 번들 파일", - "invalid-widgets-bundle-file-error": "위젯 번들을 가져오기 할 수 없습니다.: 잘못된 위젯 번들 데이터 구조입니다." - }, - "widget-config": { - "data": "데이터", - "settings": "설정", - "advanced": "고급", - "title": "타이틀", - "general-settings": "일반 설정", - "display-title": "타이틀 표시", - "drop-shadow": "그림자", - "enable-fullscreen": "전체화면 사용 ", - "background-color": "배경 색", - "text-color": "글자 색", - "padding": "패딩", - "title-style": "타이틀 스타일", - "mobile-mode-settings": "모바일 모드 설정", - "order": "순서", - "height": "높이", - "units": "값 옆에 표시할 특수 기호", - "decimals": "소수점 이하 자릿수", - "timewindow": "타임윈도우", - "use-dashboard-timewindow": "대시보드 타임윈도우", - "display-legend": "범례 표시", - "datasources": "데이터소스", - "datasource-type": "유형", - "datasource-parameters": "파라미터", - "remove-datasource": "데이터소스 삭제", - "add-datasource": "데이터소스 추가", - "target-device": "대상 디바이스" - }, - "widget-type": { - "import": "위젯 타입 가져오기", - "export": "위젯 타입 내보내기", - "export-failed-error": "위젯 타입을 내보내기 할 수 없습니다.: {{error}}", - "create-new-widget-type": "새로운 위젯 타입 생성", - "widget-type-file": "위젯 타입 파일", - "invalid-widget-type-file-error": "위젯 타입을 가져오기 할 수 없습니다.: 잘못된 위젯 타입 데이터 구조입니다." - }, - "icon": { // TODO - "icon": "Icon", - "select-icon": "Select icon", - "material-icons": "Material icons", - "show-all": "Show all icons" - }, - "custom": { - "widget-action": { - "action-cell-button": "Action cell button", - "row-click": "On row click", - "marker-click": "On marker click", - "tooltip-tag-action": "Tooltip tag action" - } - }, - "language": { - "language": "언어", - "en_US": "영어", - "ko_KR": "한글", - "zh_CN": "중국어", - "ru_RU": "러시아어", - "es_ES": "스페인어" - } - }; - angular.extend(locales, { 'ko_KR': ko_KR }); -} \ No newline at end of file diff --git a/ui/src/app/locale/locale.constant-ko_KR.json b/ui/src/app/locale/locale.constant-ko_KR.json new file mode 100644 index 0000000000..a0d9e0dd8e --- /dev/null +++ b/ui/src/app/locale/locale.constant-ko_KR.json @@ -0,0 +1,1339 @@ +{ + "access": { + "unauthorized": "권한 없음.", + "unauthorized-access": "허가되지 않은 접근", + "unauthorized-access-text": "이 리소스에 접근하려면 로그인해야 합니다!", + "access-forbidden": "접근 금지", + "access-forbidden-text": "접근 권한이 없습니다.!
만일 이 페이지에 계속 접근하려면 다른 사용자로 로그인 하세요.", + "refresh-token-expired": "세션이 만료되었습니다.", + "refresh-token-failed": "세션을 새로 고칠 수 없습니다." + }, + "action": { + "activate": "활설화", + "suspend": "비활성화", + "save": "저장", + "saveAs": "다른 이름으로 저장", + "cancel": "취소", + "ok": "확인", + "delete": "삭제", + "add": "추가", + "yes": "네", + "no": "아니오", + "update": "업데이트", + "remove": "제거", + "search": "검색", + "clear-search": "Clear search", + "assign": "할당", + "unassign": "비할당", + "share": "Share", + "make-private": "Make private", + "apply": "적용", + "apply-changes": "변경사항 적용", + "edit-mode": "수정 모드", + "enter-edit-mode": "수정 모드 진입", + "decline-changes": "변경사항 포기", + "close": "닫기", + "back": "뒤로", + "run": "실행", + "sign-in": "로그인!", + "edit": "수정", + "view": "보기", + "create": "만들기", + "drag": "끌기", + "refresh": "새로고침", + "undo": "취소", + "copy": "복사", + "paste": "붙여넣기", + "copy-reference": "Copy reference", + "paste-reference": "Paste reference", + "import": "가져오기", + "export": "내보내기", + "share-via": "Share via {{provider}}" + }, + "aggregation": { + "aggregation": "집합", + "function": "데이터 집합 함수", + "limit": "최대 값", + "group-interval": "그룹 간격", + "min": "최소", + "max": "최대", + "avg": "평균", + "sum": "합계", + "count": "숫자", + "none": "없음" + }, + "admin": { + "general": "일반", + "general-settings": "일반 설정", + "outgoing-mail": "메일 전송", + "outgoing-mail-settings": "메일 전송 설정", + "system-settings": "시스템 설정", + "test-mail-sent": "테스트 메일이 성공적으로 전송되었습니다!", + "base-url": "기본 URL", + "base-url-required": "기본 URL을 입력해야 합니다.", + "mail-from": "보내는 사람", + "mail-from-required": "보내는 사람을 입력해야 합니다.", + "smtp-protocol": "SMTP 프로토콜", + "smtp-host": "SMTP 호스트", + "smtp-host-required": "SMTP 호스트를 입력해야 합니다.", + "smtp-port": "SMTP 포트", + "smtp-port-required": "SMTP 포트를 입력해야 합니다.", + "smtp-port-invalid": "올바른 SMTP 포트가 아닙니다.", + "timeout-msec": "제한시간 (msec)", + "timeout-required": "제한시간을 입력해야 합니다.", + "timeout-invalid": "올바른 제한시간이 아닙니다.", + "enable-tls": "TLS 사용", + "send-test-mail": "테스트 메일 보내기" + }, + + "alarm": { + "alarm": "Alarm", + "alarms": "Alarms", + "select-alarm": "Select alarm", + "no-alarms-matching": "No alarms matching '{{entity}}' were found.", + "alarm-required": "Alarm is required", + "alarm-status": "Alarm status", + "search-status": { + "ANY": "Any", + "ACTIVE": "Active", + "CLEARED": "Cleared", + "ACK": "Acknowledged", + "UNACK": "Unacknowledged" + }, + "display-status": { + "ACTIVE_UNACK": "Active Unacknowledged", + "ACTIVE_ACK": "Active Acknowledged", + "CLEARED_UNACK": "Cleared Unacknowledged", + "CLEARED_ACK": "Cleared Acknowledged" + }, + "no-alarms-prompt": "No alarms found", + "created-time": "Created time", + "type": "Type", + "severity": "Severity", + "originator": "Originator", + "originator-type": "Originator type", + "details": "Details", + "status": "Status", + "alarm-details": "Alarm details", + "start-time": "Start time", + "end-time": "End time", + "ack-time": "Acknowledged time", + "clear-time": "Cleared time", + "severity-critical": "Critical", + "severity-major": "Major", + "severity-minor": "Minor", + "severity-warning": "Warning", + "severity-indeterminate": "Indeterminate", + "acknowledge": "Acknowledge", + "clear": "Clear", + "search": "Search alarms", + "selected-alarms": "{ count, plural, 1 {1 alarm} other {# alarms} } selected", + "no-data": "No data to display", + "polling-interval": "Alarms polling interval (sec)", + "polling-interval-required": "Alarms polling interval is required.", + "min-polling-interval-message": "At least 1 sec polling interval is allowed.", + "aknowledge-alarms-title": "Acknowledge { count, plural, 1 {1 alarm} other {# alarms} }", + "aknowledge-alarms-text": "Are you sure you want to acknowledge { count, plural, 1 {1 alarm} other {# alarms} }?", + "clear-alarms-title": "Clear { count, plural, 1 {1 alarm} other {# alarms} }", + "clear-alarms-text": "Are you sure you want to clear { count, plural, 1 {1 alarm} other {# alarms} }?" + }, + "alias": { + "add": "Add alias", + "edit": "Edit alias", + "name": "Alias name", + "name-required": "Alias name is required", + "duplicate-alias": "Alias with same name is already exists.", + "filter-type-single-entity": "Single entity", + "filter-type-entity-list": "Entity list", + "filter-type-entity-name": "Entity name", + "filter-type-state-entity": "Entity from dashboard state", + "filter-type-state-entity-description": "Entity taken from dashboard state parameters", + "filter-type-asset-type": "Asset type", + "filter-type-asset-type-description": "Assets of type '{{assetType}}'", + "filter-type-asset-type-and-name-description": "Assets of type '{{assetType}}' and with name starting with '{{prefix}}'", + "filter-type-device-type": "Device type", + "filter-type-device-type-description": "Devices of type '{{deviceType}}'", + "filter-type-device-type-and-name-description": "Devices of type '{{deviceType}}' and with name starting with '{{prefix}}'", + "filter-type-relations-query": "Relations query", + "filter-type-relations-query-description": "{{entities}} that have {{relationType}} relation {{direction}} {{rootEntity}}", + "filter-type-asset-search-query": "Asset search query", + "filter-type-asset-search-query-description": "Assets with types {{assetTypes}} that have {{relationType}} relation {{direction}} {{rootEntity}}", + "filter-type-device-search-query": "Device search query", + "filter-type-device-search-query-description": "Devices with types {{deviceTypes}} that have {{relationType}} relation {{direction}} {{rootEntity}}", + "entity-filter": "Entity filter", + "resolve-multiple": "Resolve as multiple entities", + "filter-type": "Filter type", + "filter-type-required": "Filter type is required.", + "entity-filter-no-entity-matched": "No entities matching specified filter were found.", + "no-entity-filter-specified": "No entity filter specified", + "root-state-entity": "Use dashboard state entity as root", + "root-entity": "Root entity", + "state-entity-parameter-name": "State entity parameter name", + "default-state-entity": "Default state entity", + "default-entity-parameter-name": "By default", + "max-relation-level": "Max relation level", + "unlimited-level": "Unlimited level", + "state-entity": "Dashboard state entity", + "all-entities": "All entities", + "any-relation": "any" + }, + "asset": { + "asset": "Asset", + "assets": "Assets", + "management": "Asset management", + "view-assets": "View Assets", + "add": "Add Asset", + "assign-to-customer": "Assign to customer", + "assign-asset-to-customer": "Assign Asset(s) To Customer", + "assign-asset-to-customer-text": "Please select the assets to assign to the customer", + "no-assets-text": "No assets found", + "assign-to-customer-text": "Please select the customer to assign the asset(s)", + "public": "Public", + "assignedToCustomer": "Assigned to customer", + "make-public": "Make asset public", + "make-private": "Make asset private", + "unassign-from-customer": "Unassign from customer", + "delete": "Delete asset", + "asset-public": "Asset is public", + "asset-type": "Asset type", + "asset-type-required": "Asset type is required.", + "select-asset-type": "Select asset type", + "enter-asset-type": "Enter asset type", + "any-asset": "Any asset", + "no-asset-types-matching": "No asset types matching '{{entitySubtype}}' were found.", + "asset-type-list-empty": "No asset types selected.", + "asset-types": "Asset types", + "name": "Name", + "name-required": "Name is required.", + "description": "Description", + "type": "Type", + "type-required": "Type is required.", + "details": "Details", + "events": "Events", + "add-asset-text": "Add new asset", + "asset-details": "Asset details", + "assign-assets": "Assign assets", + "assign-assets-text": "Assign { count, plural, 1 {1 asset} other {# assets} } to customer", + "delete-assets": "Delete assets", + "unassign-assets": "Unassign assets", + "unassign-assets-action-title": "Unassign { count, plural, 1 {1 asset} other {# assets} } from customer", + "assign-new-asset": "Assign new asset", + "delete-asset-title": "Are you sure you want to delete the asset '{{assetName}}'?", + "delete-asset-text": "Be careful, after the confirmation the asset and all related data will become unrecoverable.", + "delete-assets-title": "Are you sure you want to delete { count, plural, 1 {1 asset} other {# assets} }?", + "delete-assets-action-title": "Delete { count, plural, 1 {1 asset} other {# assets} }", + "delete-assets-text": "Be careful, after the confirmation all selected assets will be removed and all related data will become unrecoverable.", + "make-public-asset-title": "Are you sure you want to make the asset '{{assetName}}' public?", + "make-public-asset-text": "After the confirmation the asset and all its data will be made public and accessible by others.", + "make-private-asset-title": "Are you sure you want to make the asset '{{assetName}}' private?", + "make-private-asset-text": "After the confirmation the asset and all its data will be made private and won't be accessible by others.", + "unassign-asset-title": "Are you sure you want to unassign the asset '{{assetName}}'?", + "unassign-asset-text": "After the confirmation the asset will be unassigned and won't be accessible by the customer.", + "unassign-asset": "Unassign asset", + "unassign-assets-title": "Are you sure you want to unassign { count, plural, 1 {1 asset} other {# assets} }?", + "unassign-assets-text": "After the confirmation all selected assets will be unassigned and won't be accessible by the customer.", + "copyId": "Copy asset Id", + "idCopiedMessage": "Asset Id has been copied to clipboard", + "select-asset": "Select asset", + "no-assets-matching": "No assets matching '{{entity}}' were found.", + "asset-required": "Asset is required", + "name-starts-with": "Asset name starts with" + }, + "attribute": { + "attributes": "속성", + "latest-telemetry": "최근 데이터", + "attributes-scope": "디바이스 속성 범위", + "scope-latest-telemetry": "최근 데이터", + "scope-client": "클라이언트 속성", + "scope-server": "서버 속성", + "scope-shared": "공유 속성", + "add": "속성 추가", + "key": "Key", + "key-required": "속성 key를 입력하세요.", + "value": "Value", + "value-required": "속성 value를 입력하세요.", + "delete-attributes-title": "{ count, plural, 1 {속성} other {여러 속성들을} } 삭제하시겠습니까??", + "delete-attributes-text": "모든 선택된 속성들이 제거 될 것이므로 주의하십시오.", + "delete-attributes": "속성 삭제", + "enter-attribute-value": "속성 값 입력", + "show-on-widget": "위젯 보기", + "widget-mode": "위젯 모드", + "next-widget": "다음 위젯", + "prev-widget": "이전 위젯", + "add-to-dashboard": "대시보드에 추가", + "add-widget-to-dashboard": "대시보드에 위젯 추가", + "selected-attributes": "{ count, plural, 1 {속성 1개} other {속성 #개} } 선택됨", + "selected-telemetry": "{ count, plural, 1 {최근 데이터 1개} other {최근 데이터 #개} } 선택됨" + }, + "audit-log": { + "audit": "Audit", + "audit-logs": "Audit Logs", + "timestamp": "Timestamp", + "entity-type": "Entity Type", + "entity-name": "Entity Name", + "user": "User", + "type": "Type", + "status": "Status", + "details": "Details", + "type-added": "Added", + "type-deleted": "Deleted", + "type-updated": "Updated", + "type-attributes-updated": "Attributes updated", + "type-attributes-deleted": "Attributes deleted", + "type-rpc-call": "RPC call", + "type-credentials-updated": "Credentials updated", + "type-assigned-to-customer": "Assigned to Customer", + "type-unassigned-from-customer": "Unassigned from Customer", + "type-activated": "Activated", + "type-suspended": "Suspended", + "type-credentials-read": "Credentials read", + "type-attributes-read": "Attributes read", + "status-success": "Success", + "status-failure": "Failure", + "audit-log-details": "Audit log details", + "no-audit-logs-prompt": "No logs found", + "action-data": "Action data", + "failure-details": "Failure details", + "search": "Search audit logs", + "clear-search": "Clear search" + }, + "confirm-on-exit": { + "message": "변경 사항을 저장하지 않았습니다. 이 페이지를 나가시겠습니까?", + "html-message": "변경 사항을 저장하지 않았습니다.
이 페이지를 나가시겠습니까?", + "title": "저장되지 않은 변경사항" + }, + "contact": { + "country": "국가", + "city": "시", + "state": "도", + "postal-code": "우편 번호", + "postal-code-invalid": "숫자만 입력하세요.", + "address": "주소", + "address2": "상세주소", + "phone": "전화번호", + "email": "Email", + "no-address": "주소 정보 없음" + }, + "common": { + "username": "사용자명", + "password": "비밀번호", + "enter-username": "사용자명을 입력하세요.", + "enter-password": "비밀번호를 입력하세요.", + "enter-search": "검색어 입력" + }, + "content-type": { + "json": "Json", + "text": "Text", + "binary": "Binary (Base64)" + }, + "customer": { + "customers": "커스터머", + "management": "커스터머 관리", + "dashboard": "커스터머 대시보드", + "dashboards": "커스터머 대시보드", + "devices": "커스터머 디바이스", + "add": "커스터머 추가", + "delete": "커스터머 삭제", + "manage-customer-users": "커스터머 사용자 관리", + "manage-customer-devices": "커스터머 디바이스 관리", + "manage-customer-dashboards": "커스터머 대시보드 관리", + "manage-public-devices": "Manage public devices", + "manage-public-dashboards": "Manage public dashboards", + "manage-customer-assets": "Manage customer assets", + "manage-public-assets": "Manage public assets", + "add-customer-text": "커스터머 추가", + "no-customers-text": "커스터머가 없습니다.", + "customer-details": "커스터머 상세정보", + "delete-customer-title": "'{{customerTitle}}' 커스터머를 삭제하시겠습니까?", + "delete-customer-text": "커스터머 및 관련된 모든 데이터를 복구할 수 없으므로 주의하십시오.", + "delete-customers-title": "{ count, plural, 1 {커스터머 1개} other {커스터머 #개} }를 삭제하시겠습니까?", + "delete-customers-action-title": "{ count, plural, 1 {커스터머 1개} other {커스터머 #개} } 삭제", + "delete-customers-text": "선택된 커스터머는 삭제되고 관련된 모든 데이터를 복구할 수 없으므로 주의하십시오.", + "manage-users": "사용자 관리", + "manage-devices": "디바이스 관리", + "manage-dashboards": "대시보드 관리", + "title": "타이틀", + "title-required": "타이틀을 입력하세요.", + "description": "설명", + "details": "Details", + "events": "Events", + "copyId": "Copy customer Id", + "idCopiedMessage": "Customer Id has been copied to clipboard", + "select-customer": "Select customer", + "no-customers-matching": "No customers matching '{{entity}}' were found.", + "customer-required": "Customer is required", + "select-default-customer": "Select default customer", + "default-customer": "Default customer", + "default-customer-required": "Default customer is required in order to debug dashboard on Tenant level" + }, + "datetime": { + "date-from": "시작 날짜", + "time-from": "시작 시간", + "date-to": "종료 날짜", + "time-to": "종료 시간" + }, + "dashboard": { + "dashboard": "대시보드", + "dashboards": "대시보드", + "management": "대시보드 관리", + "view-dashboards": "대시보드 보기", + "add": "대시보드 추가", + "assign-dashboard-to-customer": "대시보드 커스터머 선택", + "assign-dashboard-to-customer-text": "대시보드 커스터머를 선택하세요.", + "assign-to-customer-text": "대시보드 커스터머를 선택하세요.", + "assign-to-customer": "커스터머 선택", + "unassign-from-customer": "커스터머 해제", + "no-dashboards-text": "대시보드가 없습니다", + "no-widgets": "설정된 위젯 없음", + "add-widget": "위젯 추가", + "title": "타이틀", + "select-widget-title": "위젯 선택", + "select-widget-subtitle": "사용가능한 위젯 타입 목록", + "delete": "대시보드 삭제", + "title-required": "타이틀을 입력하세요.", + "description": "설명", + "details": "상세", + "dashboard-details": "대시보드 상세정보", + "add-dashboard-text": "대시보드 추가", + "assign-dashboards": "대시보드 지정", + "assign-new-dashboard": "새 대시보드 할당", + "assign-dashboards-text": "{ count, plural, 1 {대시보드 1개} other {대시보드 #개} }를 커스터머 할당", + "delete-dashboards": "대시보드 삭제", + "unassign-dashboards": "대시보드 할당 취소", + "unassign-dashboards-action-title": "{ count, plural, 1 {대시보드 1개} other {대시보드 #개} }를 커스터머 할당 취소", + "delete-dashboard-title": "'{{dashboardTitle}}' 대시보드를 삭제하시겠습니까?", + "delete-dashboard-text": "대시보드 및 관련된 모든 데이터를 복구할 수 없으므로 주의하십시오.", + "delete-dashboards-title": "{ count, plural, 1 {대시보드 1개} other {대시보드 #개} }를 삭제하시겠습니까?", + "delete-dashboards-action-title": "{ count, plural, 1 {대시보드 1개} other {대시보드 #개} } 삭제", + "delete-dashboards-text": "선택된 대시보드가 삭제되고 관련된 모든 데이터를 복구할 수 없으므로 주의하십시오.", + "unassign-dashboard-title": "'{{dashboardTitle}}' 대시보드 할당을 해제하시겠습니까?", + "unassign-dashboard-text": "대시보드가 할당 해제되고 커스터머는 액세스 할 수 없게됩니다.", + "unassign-dashboard": "대시보드 할달 취소", + "unassign-dashboards-title": "{ count, plural, 1 {대시보드 1개} other {대시보드 #개} }의 할당을 취소하시겠습니까?", + "unassign-dashboards-text": "선택된 대시보드가 할당 해제되고 커스터머는 액세스 할 수 없게됩니다.", + "select-dashboard": "대시보드 선택", + "no-dashboards-matching": "'{{entity}}'와 일치하는 대시보드가 없습니다.", + "dashboard-required": "대시보드를 입력하세요.", + "select-existing": "기존 대시보드 선택", + "create-new": "대시보드 생성", + "new-dashboard-title": "새로운 대시보드 타이틀", + "open-dashboard": "대시보드 열기", + "set-background": "대시보드 설정", + "background-color": "배경색", + "background-image": "배경 이미지", + "background-size-mode": "배경 사이즈 모드", + "no-image": "이미지 없음", + "drop-image": "이곳에 이미지를 끌어다놓거나 이곳을 클릭하여 파일을 선택하고 업로드하세요.", + "settings": "설정", + "columns-count": "열 개수", + "columns-count-required": "열 개수를 입력하세요.", + "min-columns-count-message": "열 개수를 최소 10 이상 입력하세요.", + "max-columns-count-message": "열 개수를 최대 100 이하로 입력하세요.", + "widgets-margins": "위젯 사이 여백 크기", + "horizontal-margin": "세로 여백", + "horizontal-margin-required": "세로 여백 값을 입력하세요.", + "min-horizontal-margin-message": "세로 여백 값을 최소 0 이상 입력하세요.", + "max-horizontal-margin-message": "세로 여백 값을 최대 50 이하로 입력하세요.", + "vertical-margin": "가로 여백", + "vertical-margin-required": "가로 여백 값을 입력하세요.", + "min-vertical-margin-message": "가로 여백 값을 최소 0 이상 입력하세요.", + "max-vertical-margin-message": "가로 여백 값을 최대 50 이하로 입력하세요.", + "display-title": "대시보드 타이틀 표시", + "title-color": "타이틀 색상", + "import": "대시보드 가져오기", + "export": "대시보드 내보내기", + "export-failed-error": "대시보드 내보내기를 할 수 없습니다.: {error}", + "create-new-dashboard": "대시보드 생성", + "dashboard-file": "대시보드 파일", + "invalid-dashboard-file-error": "대시보드 가져오기를 할 수 없습니다.: 대시보드 데이터 구조가 잘못되었습니다.", + "dashboard-import-missing-aliases-title": "대시보드 앨리어스를 위해 누락 된 디바이스 선택", + "create-new-widget": "새로운 위젯 생성", + "import-widget": "위젯 가져오기", + "widget-file": "위젯 파일", + "invalid-widget-file-error": "위젯 가져오기를 할 수 없습니다: 위젯 데이터 구조가 잘못되었습니다.", + "widget-import-missing-aliases-title": "위젯에서 사용하는 누락 된 디바이스 선택", + "open-toolbar": "대시보드 툴바 열기", + "close-toolbar": "툴바 닫기", + "configuration-error": "구성 오류", + "alias-resolution-error-title": "대시보드 앨리어스 구성 오류", + "invalid-aliases-config": "일부 앨리어스 필터와 일치하는 디바이스를 찾을 수 없습니다.
이 문제를 해결하려면 관리자에게 문의하십시오.", + "select-devices": "디바이스 선택", + "assignedToCustomer": "커스터머에 할당됨" + }, + "datakey": { + "settings": "설정", + "advanced": "고급", + "label": "Label", + "color": "색상", + "data-generation-func": "데이터 생성 기능", + "use-data-post-processing-func": "데이터 후처리 기능 사용", + "configuration": "데이터 key 구성", + "timeseries": "Timeseries", + "attributes": "Attributes", + "timeseries-required": "디바이스 timeseries 를 입력하세요.", + "timeseries-or-attributes-required": "디바이스 timeseries/attributes 를 입력하세요.", + "maximum-timeseries-or-attributes": "Maximum { count, plural, 1 {1 timeseries/attribute is allowed.} other {# timeseries/attributes are allowed} }", + "alarm-fields-required": "Alarm fields are required.", + "function-types": "함수 유형", + "function-types-required": "함수 유형을 입력하세요.", + "maximum-function-types": "Maximum { count, plural, 1 {1 function type is allowed.} other {# function types are allowed} }" + }, + "datasource": { + "type": "데이터소스 유형", + "name": "Name", + "add-datasource-prompt": "데이터소스를 추가하세요." + }, + "details": { + "edit-mode": "편집 모드", + "toggle-edit-mode": "편집 모드 전환" + }, + "device": { + "device": "디바이스", + "device-required": "디바이스를 입력하세요.", + "devices": "디바이스", + "management": "디바이스 관리", + "view-devices": "디바이스 보기", + "device-alias": "디바이스 앨리어스", + "aliases": "디바이스 앨리어스", + "no-alias-matching": "'{{alias}}' 를 찾을 수 없습니다.", + "no-aliases-found": "앨리어스가 없습니다.", + "no-key-matching": "'{{key}}' 를 찾을 수 없습니다.", + "no-keys-found": "Key가 없습니다.", + "create-new-alias": "새로 만들기!", + "create-new-key": "새로 만들기!", + "duplicate-alias-error": "중복된 '{{alias}}' 앨리어스가 있습니다.
디바이스 앨리어스는 대시보드 내에서 고유해야 합니다.", + "configure-alias": "'{{alias}}' 앨리어스 구성", + "no-devices-matching": "'{{entity}}'와 일치하는 디바이스를 찾을 수 없습니다.", + "alias": "앨리어스", + "alias-required": "디바이스 앨리어스를 입력하세요.", + "remove-alias": "디바이스 앨리어스 삭제", + "add-alias": "디바이스 앨리어스 추가", + "name-starts-with": "시작되는 이름", + "device-list": "디바이스 리스트", + "use-device-name-filter": "필터 사용", + "device-list-empty": "선택된 디바이스가 없습니다.", + "device-name-filter-required": "디바이스 필터 이름을 입력하세요.", + "device-name-filter-no-device-matched": "'{{device}}' 로 시작되는 디바이스를 찾을 수 없습니다.", + "add": "디바이스 추가", + "assign-to-customer": "커스터머에게 할당", + "assign-device-to-customer": "디바이스를 커스터머에게 할당", + "assign-device-to-customer-text": "고객에게 할당할 디바이스를 선택하십시오.", + "no-devices-text": "디바이스 없음", + "assign-to-customer-text": "디바이스를 할당할 커스터머를 선택하세요.", + "device-details": "디바이스 상세정보", + "add-device-text": "디바이스 추가", + "credentials": "크리덴셜", + "manage-credentials": "크리덴셜 관리", + "delete": "디바이스 삭제", + "assign-devices": "디바이스 할당", + "assign-devices-text": "{ count, plural, 1 {디바이스 1개} other {디바이스 #개} }를 커서터머에 할당", + "delete-devices": "디바이스 삭제", + "unassign-from-customer": "커스터머 할당 해제", + "unassign-devices": "디바이스 할당 취소", + "unassign-devices-action-title": "{ count, plural, 1 {디바이스 1개} other {디바이스 #개} }를 커스터머에게서 할당 해제", + "assign-new-device": "새로운 디바이스 할당", + "view-credentials": "크리덴셜 보기", + "delete-device-title": "'{{deviceName}}' 디바이스를 삭제하시겠습니까?", + "delete-device-text": "디바이스 및 관련된 모든 데이터를 복구할 수 없으므로 주의하십시오.", + "delete-devices-title": "{ count, plural, 1 {디바이스 1개} other {디바이스 #개} }를 삭제하시겠습니까?", + "delete-devices-action-title": "{ count, plural, 1 {디바이스 1개} other {디바이스 #개} } 삭제", + "delete-devices-text": "선택된 디바이스가 삭제되고 관련된 모든 데이터를 복구할 수 없으므로 주의하십시오.", + "unassign-device-title": "'{{deviceName}}' 디바이스 할당을 해제하시겠습니까?", + "unassign-device-text": "디바이스가 할당 해제되고 커스터머는 액세스 할 수 없게됩니다.", + "unassign-device": "디바이스 할당 취소", + "unassign-devices-title": "{ count, plural, 1 {디바이스 1개} other {디바이스 #개} }의 할당을 해제하시겠습니까??", + "unassign-devices-text": "선택된 디바이스가 할당 해제되고 커스터머는 액세스 할 수 없게됩니다.", + "device-credentials": "디바이스 크리덴셜", + "credentials-type": "크리덴셜 타입", + "access-token": "억세스 토큰", + "access-token-required": "액세스 토큰을 입력하세요.", + "access-token-invalid": "액세스 토큰 길이는 1 - 20 자 여야합니다.", + "rsa-key": "RSA public key", + "rsa-key-required": "RSA public key 를 입력하세요.", + "secret": "시크릿", + "secret-required": "시크릿을 입력하세요.", + "name": "이름", + "name-required": "이름을 입력하세요.", + "description": "설명", + "events": "이벤트", + "details": "상세", + "copyId": "디바이스 아이디 복사", + "copyAccessToken": "억세스 토큰 복사", + "idCopiedMessage": "디바이스 아이디가 클립보드에 복사되었습니다.", + "accessTokenCopiedMessage": "디바이스 억세스 토큰이 클립보드에 복사되었습니다.", + "assignedToCustomer": "커스터머에 할당됨", + "unable-delete-device-alias-title": "디바이스 앨리어스를 삭제할 수 없습니다.", + "unable-delete-device-alias-text": "'{{deviceAlias}}' 디바이스 앨리어스를 삭제할 수 없습니다. 다음 위젯에서 사용하고 있습니다.
{{widgetsList}}", + "is-gateway": "게이트웨이 여부" + }, + "dialog": { + "close": "다이얼로그 닫기" + }, + "error": { + "unable-to-connect": "서버에 연결할 수 없습니다! 인터넷 연결을 확인하십시오.", + "unhandled-error-code": "처리되지 않은 오류 코드: {{errorCode}}", + "unknown-error": "알 수 없는 오류" + }, + "entity": { + "entity": "Entity", + "entities": "Entities", + "aliases": "Entity aliases", + "entity-alias": "Entity alias", + "unable-delete-entity-alias-title": "Unable to delete entity alias", + "unable-delete-entity-alias-text": "Entity alias '{{entityAlias}}' can't be deleted as it used by the following widget(s):
{{widgetsList}}", + "duplicate-alias-error": "Duplicate alias found '{{alias}}'.
Entity aliases must be unique whithin the dashboard.", + "missing-entity-filter-error": "Filter is missing for alias '{{alias}}'.", + "configure-alias": "Configure '{{alias}}' alias", + "alias": "Alias", + "alias-required": "Entity alias is required.", + "remove-alias": "Remove entity alias", + "add-alias": "Add entity alias", + "entity-list": "Entity list", + "entity-type": "Entity type", + "entity-types": "Entity types", + "entity-type-list": "Entity type list", + "any-entity": "Any entity", + "enter-entity-type": "Enter entity type", + "no-entities-matching": "No entities matching '{{entity}}' were found.", + "no-entity-types-matching": "No entity types matching '{{entityType}}' were found.", + "name-starts-with": "Name starts with", + "use-entity-name-filter": "Use filter", + "entity-list-empty": "No entities selected.", + "entity-type-list-empty": "No entity types selected.", + "entity-name-filter-required": "Entity name filter is required.", + "entity-name-filter-no-entity-matched": "No entities starting with '{{entity}}' were found.", + "all-subtypes": "All", + "select-entities": "Select entities", + "no-aliases-found": "No aliases found.", + "no-alias-matching": "'{{alias}}' not found.", + "create-new-alias": "Create a new one!", + "key": "Key", + "key-name": "Key name", + "no-keys-found": "No keys found.", + "no-key-matching": "'{{key}}' not found.", + "create-new-key": "Create a new one!", + "type": "Type", + "type-required": "Entity type is required.", + "type-device": "Device", + "type-devices": "Devices", + "list-of-devices": "{ count, plural, 1 {One device} other {List of # devices} }", + "device-name-starts-with": "Devices whose names start with '{{prefix}}'", + "type-asset": "Asset", + "type-assets": "Assets", + "list-of-assets": "{ count, plural, 1 {One asset} other {List of # assets} }", + "asset-name-starts-with": "Assets whose names start with '{{prefix}}'", + "type-rule": "Rule", + "type-rules": "Rules", + "list-of-rules": "{ count, plural, 1 {One rule} other {List of # rules} }", + "rule-name-starts-with": "Rules whose names start with '{{prefix}}'", + "type-plugin": "Plugin", + "type-plugins": "Plugins", + "list-of-plugins": "{ count, plural, 1 {One plugin} other {List of # plugins} }", + "plugin-name-starts-with": "Plugins whose names start with '{{prefix}}'", + "type-tenant": "Tenant", + "type-tenants": "Tenants", + "list-of-tenants": "{ count, plural, 1 {One tenant} other {List of # tenants} }", + "tenant-name-starts-with": "Tenants whose names start with '{{prefix}}'", + "type-customer": "Customer", + "type-customers": "Customers", + "list-of-customers": "{ count, plural, 1 {One customer} other {List of # customers} }", + "customer-name-starts-with": "Customers whose names start with '{{prefix}}'", + "type-user": "User", + "type-users": "Users", + "list-of-users": "{ count, plural, 1 {One user} other {List of # users} }", + "user-name-starts-with": "Users whose names start with '{{prefix}}'", + "type-dashboard": "Dashboard", + "type-dashboards": "Dashboards", + "list-of-dashboards": "{ count, plural, 1 {One dashboard} other {List of # dashboards} }", + "dashboard-name-starts-with": "Dashboards whose names start with '{{prefix}}'", + "type-alarm": "Alarm", + "type-alarms": "Alarms", + "list-of-alarms": "{ count, plural, 1 {One alarms} other {List of # alarms} }", + "alarm-name-starts-with": "Alarms whose names start with '{{prefix}}'", + "type-rulechain": "Rule chain", + "type-rulechains": "Rule chains", + "list-of-rulechains": "{ count, plural, 1 {One rule chain} other {List of # rule chains} }", + "rulechain-name-starts-with": "Rule chains whose names start with '{{prefix}}'", + "type-current-customer": "Current Customer", + "search": "Search entities", + "selected-entities": "{ count, plural, 1 {1 entity} other {# entities} } selected", + "entity-name": "Entity name", + "details": "Entity details", + "no-entities-prompt": "No entities found", + "no-data": "No data to display" + }, + "event": { + "event-type": "이벤트 타입", + "type-error": "에러", + "type-lc-event": "주기적 이벤트", + "type-stats": "통계", + "type-debug-rule-node": "Debug", + "type-debug-rule-chain": "Debug", + "no-events-prompt": "이벤트 없음", + "error": "에러", + "alarm": "알람", + "event-time": "이벤트 발생 시간", + "server": "서버", + "body": "Body", + "method": "Method", + "type": "Type", + "entity": "Entity", + "message-id": "Message Id", + "message-type": "Message Type", + "data-type": "Data Type", + "relation-type": "Relation Type", + "metadata": "Metadata", + "data": "Data", + "event": "이벤트", + "status": "상태", + "success": "성공", + "failed": "실패", + "messages-processed": "처리된 메시지", + "errors-occurred": "오류가 발생했습니다" + }, + "extension": { + "extensions": "Extensions", + "selected-extensions": "{ count, plural, 1 {1 extension} other {# extensions} } selected", + "type": "Type", + "key": "Key", + "value": "Value", + "id": "Id", + "extension-id": "Extension id", + "extension-type": "Extension type", + "transformer-json": "JSON *", + "unique-id-required": "Current extension id already exists.", + "delete": "Delete extension", + "add": "Add extension", + "edit": "Edit extension", + "delete-extension-title": "Are you sure you want to delete the extension '{{extensionId}}'?", + "delete-extension-text": "Be careful, after the confirmation the extension and all related data will become unrecoverable.", + "delete-extensions-title": "Are you sure you want to delete { count, plural, 1 {1 extension} other {# extensions} }?", + "delete-extensions-text": "Be careful, after the confirmation all selected extensions will be removed.", + "converters": "Converters", + "converter-id": "Converter id", + "configuration": "Configuration", + "converter-configurations": "Converter configurations", + "token": "Security token", + "add-converter": "Add converter", + "add-config": "Add converter configuration", + "device-name-expression": "Device name expression", + "device-type-expression": "Device type expression", + "custom": "Custom", + "to-double": "To Double", + "transformer": "Transformer", + "json-required": "Transformer json is required.", + "json-parse": "Unable to parse transformer json.", + "attributes": "Attributes", + "add-attribute": "Add attribute", + "add-map": "Add mapping element", + "timeseries": "Timeseries", + "add-timeseries": "Add timeseries", + "field-required": "Field is required", + "brokers": "Brokers", + "add-broker": "Add broker", + "host": "Host", + "port": "Port", + "port-range": "Port should be in a range from 1 to 65535.", + "ssl": "Ssl", + "credentials": "Credentials", + "username": "Username", + "password": "Password", + "retry-interval": "Retry interval in milliseconds", + "anonymous": "Anonymous", + "basic": "Basic", + "pem": "PEM", + "ca-cert": "CA certificate file *", + "private-key": "Private key file *", + "cert": "Certificate file *", + "no-file": "No file selected.", + "drop-file": "Drop a file or click to select a file to upload.", + "mapping": "Mapping", + "topic-filter": "Topic filter", + "converter-type": "Converter type", + "converter-json": "Json", + "json-name-expression": "Device name json expression", + "topic-name-expression": "Device name topic expression", + "json-type-expression": "Device type json expression", + "topic-type-expression": "Device type topic expression", + "attribute-key-expression": "Attribute key expression", + "attr-json-key-expression": "Attribute key json expression", + "attr-topic-key-expression": "Attribute key topic expression", + "request-id-expression": "Request id expression", + "request-id-json-expression": "Request id json expression", + "request-id-topic-expression": "Request id topic expression", + "response-topic-expression": "Response topic expression", + "value-expression": "Value expression", + "topic": "Topic", + "timeout": "Timeout in milliseconds", + "converter-json-required": "Converter json is required.", + "converter-json-parse": "Unable to parse converter json.", + "filter-expression": "Filter expression", + "connect-requests": "Connect requests", + "add-connect-request": "Add connect request", + "disconnect-requests": "Disconnect requests", + "add-disconnect-request": "Add disconnect request", + "attribute-requests": "Attribute requests", + "add-attribute-request": "Add attribute request", + "attribute-updates": "Attribute updates", + "add-attribute-update": "Add attribute update", + "server-side-rpc": "Server side RPC", + "add-server-side-rpc-request": "Add server-side RPC request", + "device-name-filter": "Device name filter", + "attribute-filter": "Attribute filter", + "method-filter": "Method filter", + "request-topic-expression": "Request topic expression", + "response-timeout": "Response timeout in milliseconds", + "topic-expression": "Topic expression", + "client-scope": "Client scope", + "add-device": "Add device", + "opc-server": "Servers", + "opc-add-server": "Add server", + "opc-add-server-prompt": "Please add server", + "opc-application-name": "Application name", + "opc-application-uri": "Application uri", + "opc-scan-period-in-seconds": "Scan period in seconds", + "opc-security": "Security", + "opc-identity": "Identity", + "opc-keystore": "Keystore", + "opc-type": "Type", + "opc-keystore-type": "Type", + "opc-keystore-location": "Location *", + "opc-keystore-password": "Password", + "opc-keystore-alias": "Alias", + "opc-keystore-key-password": "Key password", + "opc-device-node-pattern": "Device node pattern", + "opc-device-name-pattern": "Device name pattern", + "modbus-server": "Servers/slaves", + "modbus-add-server": "Add server/slave", + "modbus-add-server-prompt": "Please add server/slave", + "modbus-transport": "Transport", + "modbus-port-name": "Serial port name", + "modbus-encoding": "Encoding", + "modbus-parity": "Parity", + "modbus-baudrate": "Baud rate", + "modbus-databits": "Data bits", + "modbus-stopbits": "Stop bits", + "modbus-databits-range": "Data bits should be in a range from 7 to 8.", + "modbus-stopbits-range": "Stop bits should be in a range from 1 to 2.", + "modbus-unit-id": "Unit ID", + "modbus-unit-id-range": "Unit ID should be in a range from 1 to 247.", + "modbus-device-name": "Device name", + "modbus-poll-period": "Poll period (ms)", + "modbus-attributes-poll-period": "Attributes poll period (ms)", + "modbus-timeseries-poll-period": "Timeseries poll period (ms)", + "modbus-poll-period-range": "Poll period should be positive value.", + "modbus-tag": "Tag", + "modbus-function": "Function", + "modbus-register-address": "Register address", + "modbus-register-address-range": "Register address should be in a range from 0 to 65535.", + "modbus-register-bit-index": "Bit index", + "modbus-register-bit-index-range": "Bit index should be in a range from 0 to 15.", + "modbus-register-count": "Register count", + "modbus-register-count-range": "Register count should be a positive value.", + "modbus-byte-order": "Byte order", + + "sync": { + "status": "Status", + "sync": "Sync", + "not-sync": "Not sync", + "last-sync-time": "Last sync time", + "not-available": "Not available" + }, + + "export-extensions-configuration": "Export extensions configuration", + "import-extensions-configuration": "Import extensions configuration", + "import-extensions": "Import extensions", + "import-extension": "Import extension", + "export-extension": "Export extension", + "file": "Extensions file", + "invalid-file-error": "Invalid extension file" + }, + "fullscreen": { + "expand": "전체화면으로 확장", + "exit": "전체화면 종료", + "toggle": "전체화면 모드 전환", + "fullscreen": "전체화면" + }, + "function": { + "function": "기능" + }, + "grid": { + "delete-item-title": "이 항목을 삭제 하시겠습니까?", + "delete-item-text": "항목과 모든 관련 데이터를 복구 할 수 없으므로 주의하십시오.", + "delete-items-title": "{ count, plural, 1 {아이템 1개} other {아이템 #개} }를 삭제하시겠습니까?", + "delete-items-action-title": "{ count, plural, 1 {아이템 1개} other {아이템 #개} } 삭제", + "delete-items-text": "선택한 모든 아이템이 제거되고 관련된 모든 데이터는 복구 할 수 없으므로 주의하십시오.", + "add-item-text": "새로운 아이템 추가", + "no-items-text": "아이템이 없습니다.", + "item-details": "아이템 상세", + "delete-item": "아이템 삭제", + "delete-items": "아이템 삭제", + "scroll-to-top": "스크롤 맨 위로" + }, + "help": { + "goto-help-page": "도움" + }, + "home": { + "home": "홈", + "profile": "프로파일", + "logout": "로그아웃", + "menu": "메뉴", + "avatar": "Avatar", + "open-user-menu": "사용자 메뉴 열기" + }, + "import": { + "no-file": "선택된 파일이 없습니다.", + "drop-file": "JSON 파일을 끌어다 놓거나 클릭하여 업로드 할 파일을 선택하십시오." + }, + "item": { + "selected": "선택됨" + }, + "js-func": { + "no-return-error": "함수는 값을 반환해야 합니다!", + "return-type-mismatch": "함수는 '{{type}}' 유형의 값을 반환해야 합니다!", + "tidy": "Tidy" + }, + "key-val": { + "key": "Key", + "value": "Value", + "remove-entry": "Remove entry", + "add-entry": "Add entry", + "no-data": "No entries" + }, + "layout": { + "layout": "Layout", + "manage": "Manage layouts", + "settings": "Layout settings", + "color": "Color", + "main": "Main", + "right": "Right", + "select": "Select target layout" + }, + "legend": { + "position": "범례 위치", + "show-max": "최대값 표시", + "show-min": "최소값 표시", + "show-avg": "평균값 표시", + "show-total": "총합 표시", + "settings": "범례 설정", + "min": "최소", + "max": "최대", + "avg": "평균", + "total": "합계" + }, + "login": { + "login": "로그인", + "request-password-reset": "비밀번호 재설정", + "reset-password": "비밀번호 재설정", + "create-password": "비밀번호 생성", + "passwords-mismatch-error": "입력된 비밀번호는 같아야 합니다!", + "password-again": "비밀번호 확인", + "sign-in": "로그인", + "username": "사용자명 (이메일)", + "remember-me": "아이디 저장", + "forgot-password": "비밀번호찾기", + "password-reset": "비밀번호 재설정", + "new-password": "새 비밀번호", + "new-password-again": "새 비밀번호 확인", + "password-link-sent-message": "비밀번호 재설정 링크가 성공적으로 전송되었습니다!", + "email": "이메일" + }, + "position": { + "top": "상단", + "bottom": "하단", + "left": "왼쪽", + "right": "오른쪽" + }, + "profile": { + "profile": "프로파일", + "change-password": "비밀번호 변경", + "current-password": "현재 비밀번호" + }, + "relation": { + "relations": "Relations", + "direction": "Direction", + "search-direction": { + "FROM": "From", + "TO": "To" + }, + "direction-type": { + "FROM": "from", + "TO": "to" + }, + "from-relations": "Outbound relations", + "to-relations": "Inbound relations", + "selected-relations": "{ count, plural, 1 {1 relation} other {# relations} } selected", + "type": "Type", + "to-entity-type": "To entity type", + "to-entity-name": "To entity name", + "from-entity-type": "From entity type", + "from-entity-name": "From entity name", + "to-entity": "To entity", + "from-entity": "From entity", + "delete": "Delete relation", + "relation-type": "Relation type", + "relation-type-required": "Relation type is required.", + "any-relation-type": "Any type", + "add": "Add relation", + "edit": "Edit relation", + "delete-to-relation-title": "Are you sure you want to delete relation to the entity '{{entityName}}'?", + "delete-to-relation-text": "Be careful, after the confirmation the entity '{{entityName}}' will be unrelated from the current entity.", + "delete-to-relations-title": "Are you sure you want to delete { count, plural, 1 {1 relation} other {# relations} }?", + "delete-to-relations-text": "Be careful, after the confirmation all selected relations will be removed and corresponding entities will be unrelated from the current entity.", + "delete-from-relation-title": "Are you sure you want to delete relation from the entity '{{entityName}}'?", + "delete-from-relation-text": "Be careful, after the confirmation current entity will be unrelated from the entity '{{entityName}}'.", + "delete-from-relations-title": "Are you sure you want to delete { count, plural, 1 {1 relation} other {# relations} }?", + "delete-from-relations-text": "Be careful, after the confirmation all selected relations will be removed and current entity will be unrelated from the corresponding entities.", + "remove-relation-filter": "Remove relation filter", + "add-relation-filter": "Add relation filter", + "any-relation": "Any relation", + "relation-filters": "Relation filters", + "additional-info": "Additional info (JSON)", + "invalid-additional-info": "Unable to parse additional info json." + }, + "rulechain": { + "rulechain": "Rule chain", + "rulechains": "Rule chains", + "root": "Root", + "delete": "Delete rule chain", + "name": "Name", + "name-required": "Name is required.", + "description": "Description", + "add": "Add Rule Chain", + "set-root": "Make rule chain root", + "set-root-rulechain-title": "Are you sure you want to make the rule chain '{{ruleChainName}}' root?", + "set-root-rulechain-text": "After the confirmation the rule chain will become root and will handle all incoming transport messages.", + "delete-rulechain-title": "Are you sure you want to delete the rule chain '{{ruleChainName}}'?", + "delete-rulechain-text": "Be careful, after the confirmation the rule chain and all related data will become unrecoverable.", + "delete-rulechains-title": "Are you sure you want to delete { count, plural, 1 {1 rule chain} other {# rule chains} }?", + "delete-rulechains-action-title": "Delete { count, plural, 1 {1 rule chain} other {# rule chains} }", + "delete-rulechains-text": "Be careful, after the confirmation all selected rule chains will be removed and all related data will become unrecoverable.", + "add-rulechain-text": "Add new rule chain", + "no-rulechains-text": "No rule chains found", + "rulechain-details": "Rule chain details", + "details": "Details", + "events": "Events", + "system": "System", + "import": "Import rule chain", + "export": "Export rule chain", + "export-failed-error": "Unable to export rule chain: {{error}}", + "create-new-rulechain": "Create new rule chain", + "rulechain-file": "Rule chain file", + "invalid-rulechain-file-error": "Unable to import rule chain: Invalid rule chain data structure.", + "copyId": "Copy rule chain Id", + "idCopiedMessage": "Rule chain Id has been copied to clipboard", + "select-rulechain": "Select rule chain", + "no-rulechains-matching": "No rule chains matching '{{entity}}' were found.", + "rulechain-required": "Rule chain is required", + "management": "Rules management", + "debug-mode": "Debug mode" + }, + "rulenode": { + "details": "Details", + "events": "Events", + "search": "Search nodes", + "open-node-library": "Open node library", + "add": "Add rule node", + "name": "Name", + "name-required": "Name is required.", + "type": "Type", + "description": "Description", + "delete": "Delete rule node", + "select-all-objects": "Select all nodes and connections", + "deselect-all-objects": "Deselect all nodes and connections", + "delete-selected-objects": "Delete selected nodes and connections", + "delete-selected": "Delete selected", + "select-all": "Select all", + "copy-selected": "Copy selected", + "deselect-all": "Deselect all", + "rulenode-details": "Rule node details", + "debug-mode": "Debug mode", + "configuration": "Configuration", + "link": "Link", + "link-details": "Rule node link details", + "add-link": "Add link", + "link-label": "Link label", + "link-label-required": "Link label is required.", + "custom-link-label": "Custom link label", + "custom-link-label-required": "Custom link label is required.", + "type-filter": "Filter", + "type-filter-details": "Filter incoming messages with configured conditions", + "type-enrichment": "Enrichment", + "type-enrichment-details": "Add additional information into Message Metadata", + "type-transformation": "Transformation", + "type-transformation-details": "Change Message payload and Metadata", + "type-action": "Action", + "type-action-details": "Perform special action", + "type-external": "External", + "type-external-details": "Interacts with external system", + "type-rule-chain": "Rule Chain", + "type-rule-chain-details": "Forwards incoming messages to specified Rule Chain", + "type-input": "Input", + "type-input-details": "Logical input of Rule Chain, forwards incoming messages to next related Rule Node", + "directive-is-not-loaded": "Defined configuration directive '{{directiveName}}' is not available.", + "ui-resources-load-error": "Failed to load configuration ui resources.", + "invalid-target-rulechain": "Unable to resolve target rule chain!", + "test-script-function": "Test script function", + "message": "Message", + "message-type": "Message type", + "message-type-required": "Message type is required", + "metadata": "Metadata", + "metadata-required": "Metadata entries can't be empty.", + "output": "Output", + "test": "Test", + "help": "Help" + }, + "tenant": { + "tenants": "테넌트", + "management": "테넌트 관리", + "add": "테넌트 추가", + "admins": "Admins", + "manage-tenant-admins": "테넌트 관리자 관리", + "delete": "테넌트 삭제", + "add-tenant-text": "테넌트 추가", + "no-tenants-text": "테넌트가 없습니다.", + "tenant-details": "테넌트 상세정보", + "delete-tenant-title": "'{{tenantTitle}}' 테넌트를 삭제하시겠습니까?", + "delete-tenant-text": "테넌트와 관련된 모든 정보를 복구할 수 없으므로 주의하십시오.", + "delete-tenants-title": "{ count, plural, 1 {테넌트 1개} other {테넌트 #개} }를 삭제하시겠습니까?", + "delete-tenants-action-title": "{ count, plural, 1 {테넌트 1개} other {테넌트 #개} } 삭제", + "delete-tenants-text": "선택된 테넌트가 삭제되고 관련된 모든 정보를 복구할 수 없으므로 주의하십시오.", + "title": "타이틀", + "title-required": "타이틀을 입력하세요.", + "description": "설명", + "details": "Details", + "events": "Events", + "copyId": "Copy tenant Id", + "idCopiedMessage": "Tenant Id has been copied to clipboard", + "select-tenant": "Select tenant", + "no-tenants-matching": "No tenants matching '{{entity}}' were found.", + "tenant-required": "Tenant is required" + }, + "timeinterval": { + "seconds-interval": "{ seconds, plural, 1 {1 second} other {# seconds} }", + "minutes-interval": "{ minutes, plural, 1 {1 minute} other {# minutes} }", + "hours-interval": "{ hours, plural, 1 {1 hour} other {# hours} }", + "days-interval": "{ days, plural, 1 {1 day} other {# days} }", + "days": "Days", + "hours": "Hours", + "minutes": "Minutes", + "seconds": "Seconds", + "advanced": "고급" + }, + "timewindow": { + "days": "{ days, plural, 1 { day } other {# days } }", + "hours": "{ hours, plural, 0 { hour } 1 {1 hour } other {# hours } }", + "minutes": "{ minutes, plural, 0 { minute } 1 {1 minute } other {# minutes } }", + "seconds": "{ seconds, plural, 0 { second } 1 {1 second } other {# seconds } }", + "realtime": "Realtime", + "history": "History", + "last-prefix": "last", + "period": "from {{ startTime }} to {{ endTime }}", + "edit": "타임윈도우 편집", + "date-range": "날짜 범위", + "last": "Last", + "time-period": "기간" + }, + "user": { + "users": "사용자", + "customer-users": "커스터머 사용자", + "tenant-admins": "테넌트 관리자", + "sys-admin": "시스템 관리자", + "tenant-admin": "테넌트 관리자", + "customer": "커스터머", + "anonymous": "Anonymous", + "add": "사용자 추가", + "delete": "사용자 삭제", + "add-user-text": "새로운 사용자 추가", + "no-users-text": "사용자가 없습니다.", + "user-details": "사용자 상세정보", + "delete-user-title": "'{{userEmail}}' 사용자를 삭제하시겠습니까?", + "delete-user-text": "사용자와 관련된 모든 데이터를 복구할 수 없으므로 주의하십시오.", + "delete-users-title": "{ count, plural, 1 {사용자 1명} other {사용자 #명} }을 삭제하시겠니까?", + "delete-users-action-title": "{ count, plural, 1 {사용자 1명} other {사용자 #명} } 삭제", + "delete-users-text": "선택된 사용자가 삭제된고 관련된 모든 데이터를 복구할 수 없으므로 주의하십시오.", + "activation-email-sent-message": "활성화 이메일을 보냈습니다!", + "resend-activation": "활성화 재전송", + "email": "Email", + "email-required": "Email을 입력하세요.", + "first-name": "이름", + "last-name": "성", + "description": "설명", + "default-dashboard": "기본 대시보드", + "always-fullscreen": "항상 전체화면", + "select-user": "Select user", + "no-users-matching": "No users matching '{{entity}}' were found.", + "user-required": "User is required", + "activation-method": "Activation method", + "display-activation-link": "Display activation link", + "send-activation-mail": "Send activation mail", + "activation-link": "User activation link", + "activation-link-text": "In order to activate user use the following activation link :", + "copy-activation-link": "Copy activation link", + "activation-link-copied-message": "User activation link has been copied to clipboard", + "details": "Details" + }, + "value": { + "type": "Value type", + "string": "String", + "string-value": "String value", + "integer": "Integer", + "integer-value": "Integer value", + "invalid-integer-value": "Invalid integer value", + "double": "Double", + "double-value": "Double value", + "boolean": "Boolean", + "boolean-value": "Boolean value", + "false": "False", + "true": "True" + }, + "widget": { + "widget-library": "위젯 저장소", + "widget-bundle": "위젯 번들", + "select-widgets-bundle": "위젯 번들 선택", + "management": "위젯 관리", + "editor": "위젯 편집기", + "widget-type-not-found": "위젯 구성을 로드하는 중 문제가 발생했습니다.
연결된 위젯 타입이 삭제되었습니다.", + "widget-type-load-error": "다음과 같은 오류로 인해 위젯이로드되지 않았습니다:", + "remove": "위젯 삭제", + "edit": "위젯 수정", + "remove-widget-title": "'{{widgetTitle}}' 위젯을 삭제하시겠습니까?", + "remove-widget-text": "위젯과 관련된 모든 데이터를 복구할 수 없으므로 주의하십시오.", + "timeseries": "Time series", + "latest-values": "Latest values", + "rpc": "Control 위젯", + "static": "Static 위젯", + "select-widget-type": "위젯 타입 선택", + "missing-widget-title-error": "위젯 타이틀을 입력하세요!", + "widget-saved": "위젯이 저장되었습니다.", + "unable-to-save-widget-error": "위젯을 저장할 수 없습니다! 위젯에 오류가 있습니다!", + "save": "위젯 저장", + "saveAs": "다른 이름으로 위젯 저장", + "save-widget-type-as": "다른 이름으로 위젯 타입 저장", + "save-widget-type-as-text": "새로운 위젯 이름과 위젯 번들을 선택하세요.", + "toggle-fullscreen": "전체화면 전환", + "run": "위젯 실행", + "title": "위젯 타이틀", + "title-required": "위젯 타이틀을 입력하세요.", + "type": "위젯 타입", + "resources": "리소스", + "resource-url": "JavaScript/CSS URI", + "remove-resource": "리소스 삭제", + "add-resource": "리소스 추가", + "html": "HTML", + "tidy": "Tidy", + "css": "CSS", + "settings-schema": "스키마 설정", + "datakey-settings-schema": "데이터 키 설정 스키마", + "javascript": "Javascript", + "remove-widget-type-title": "'{{widgetName}}' 위젯 타입을 삭제하시겠습니까?", + "remove-widget-type-text": "위젯 타입과 관련된 모든 데이터를 복구할 수 없으므로 주의하십시오.", + "remove-widget-type": "위젯 타입 삭제", + "add-widget-type": "새로운 위젯 타입 추가", + "widget-type-load-failed-error": "위젯 타입을 로드하지 못했습니다!", + "widget-template-load-failed-error": "위젯 템플릿을 로드하지 못했습니다!", + "add": "위젯 추가", + "undo": "위젯 변경사항 취소", + "export": "위젯 내보내기" + }, + "widget-action": { + "header-button": "Widget header button", + "open-dashboard-state": "Navigate to new dashboard state", + "update-dashboard-state": "Update current dashboard state", + "open-dashboard": "Navigate to other dashboard", + "custom": "Custom action", + "target-dashboard-state": "Target dashboard state", + "target-dashboard-state-required": "Target dashboard state is required", + "set-entity-from-widget": "Set entity from widget", + "target-dashboard": "Target dashboard", + "open-right-layout": "Open right dashboard layout (mobile view)" + }, + "widgets-bundle": { + "current": "현재 번들", + "widgets-bundles": "위젯 번들", + "add": "위젯 번들 추가", + "delete": "위젯 번들 삭제", + "title": "타이틀", + "title-required": "타이틀을 입력하세요.", + "add-widgets-bundle-text": "위젯 번들 추가", + "no-widgets-bundles-text": "위젯 번들이 없습니다.", + "empty": "위젯 번들이 비어있습니다.", + "details": "상세", + "widgets-bundle-details": "위젯 번들 상세정보", + "delete-widgets-bundle-title": "'{{widgetsBundleTitle}}' 위젯 번들을 삭제하시겠습니까?", + "delete-widgets-bundle-text": "위젯 번들과 관련된 모든 데이터를 복구할 수 없으므로 주의하십시오.", + "delete-widgets-bundles-title": "{ count, plural, 1 {위젯 번들 1개} other {위젯 번들 #개} }를 삭제하시겠습니까?", + "delete-widgets-bundles-action-title": "{ count, plural, 1 {위젯 번들 1개} other {위젯 번들 #개} } 삭제", + "delete-widgets-bundles-text": "선택된 위젯 번들이 삭제되고 관련된 모든 데이터를 복구할 수 없으므로 주의하십시오.", + "no-widgets-bundles-matching": "'{{widgetsBundle}}' 와(과) 일치하는 위젯 번들을 찾을 수 없습니다.", + "widgets-bundle-required": "위젯 번들을 입력하세요.", + "system": "시스템", + "import": "위젯 번들 가져오기", + "export": "위젯 번들 내보내기", + "export-failed-error": "위젯 번들을 내보내기 할 수 없습니다.: {{error}}", + "create-new-widgets-bundle": "새로운 위젯 번들 생성", + "widgets-bundle-file": "위젯 번들 파일", + "invalid-widgets-bundle-file-error": "위젯 번들을 가져오기 할 수 없습니다.: 잘못된 위젯 번들 데이터 구조입니다." + }, + "widget-config": { + "data": "데이터", + "settings": "설정", + "advanced": "고급", + "title": "타이틀", + "general-settings": "일반 설정", + "display-title": "타이틀 표시", + "drop-shadow": "그림자", + "enable-fullscreen": "전체화면 사용 ", + "background-color": "배경 색", + "text-color": "글자 색", + "padding": "패딩", + "title-style": "타이틀 스타일", + "mobile-mode-settings": "모바일 모드 설정", + "order": "순서", + "height": "높이", + "units": "값 옆에 표시할 특수 기호", + "decimals": "소수점 이하 자릿수", + "timewindow": "타임윈도우", + "use-dashboard-timewindow": "대시보드 타임윈도우", + "display-legend": "범례 표시", + "datasources": "데이터소스", + "datasource-type": "유형", + "datasource-parameters": "파라미터", + "remove-datasource": "데이터소스 삭제", + "add-datasource": "데이터소스 추가", + "target-device": "대상 디바이스" + }, + "widget-type": { + "import": "위젯 타입 가져오기", + "export": "위젯 타입 내보내기", + "export-failed-error": "위젯 타입을 내보내기 할 수 없습니다.: {{error}}", + "create-new-widget-type": "새로운 위젯 타입 생성", + "widget-type-file": "위젯 타입 파일", + "invalid-widget-type-file-error": "위젯 타입을 가져오기 할 수 없습니다.: 잘못된 위젯 타입 데이터 구조입니다." + }, + "icon": { + "icon": "Icon", + "select-icon": "Select icon", + "material-icons": "Material icons", + "show-all": "Show all icons" + }, + "custom": { + "widget-action": { + "action-cell-button": "Action cell button", + "row-click": "On row click", + "marker-click": "On marker click", + "tooltip-tag-action": "Tooltip tag action" + } + }, + "language": { + "language": "언어", + "locales": { + "en_US": "영어", + "ko_KR": "한글", + "zh_CN": "중국어", + "ru_RU": "러시아어", + "es_ES": "스페인어", + "it_IT": "이탈리아 사람" + } + } +} \ No newline at end of file diff --git a/ui/src/app/locale/locale.constant-ru.js b/ui/src/app/locale/locale.constant-ru.js deleted file mode 100644 index cff98809c0..0000000000 --- a/ui/src/app/locale/locale.constant-ru.js +++ /dev/null @@ -1,1381 +0,0 @@ -/* - * Copyright © 2016-2018 The Thingsboard Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -export default function addLocaleRussian(locales) { - var ru_RU = { - "access": { - "unauthorized": "Неавторизированный", - "unauthorized-access": "Несанкционированный доступ", - "unauthorized-access-text": "Вы должны войти в систему для получения доступа к этому ресурсу!", - "access-forbidden": "Доступ запрещен", - "access-forbidden-text": "У вас нет прав доступа к этому ресурсу!
Для получения доступа попробуйте войти под другим пользователем.", - "refresh-token-expired": "Сессия истекла", - "refresh-token-failed": "Не удалось обновить сессию" - }, - "action": { - "activate": "Активировать", - "suspend": "Приостановить", - "save": "Сохранить", - "saveAs": "Сохранить как", - "cancel": "Отмена", - "ok": "ОК", - "delete": "Удалить", - "add": "Добавить", - "yes": "Да", - "no": "Нет", - "update": "Обновить", - "remove": "Удалить", - "search": "Поиск", - "assign": "Присвоить", - "unassign": "Отменить присвоение", - "share": "Поделиться", - "make-private": "Закрыть для общего доступа", - "apply": "Применить", - "apply-changes": "Применить изменения", - "edit-mode": "Режим редактирования", - "enter-edit-mode": "Режим редактирования", - "decline-changes": "Отменить изменения", - "close": "Закрыть", - "back": "Назад", - "run": "Запуск", - "sign-in": "Войти", - "edit": "Редактировать", - "view": "Просмотреть", - "create": "Создать", - "drag": "Переместить", - "refresh": "Обновить", - "undo": "Откатить", - "copy": "Копировать", - "paste": "Вставить", - "import": "Импортировать", - "export": "Экспортировать", - "share-via": "Поделиться в {{provider}}" - }, - "aggregation": { - "aggregation": "Агрегация", - "function": "Тип агрегации данных", - "limit": "Максимальное значение", - "group-interval": "Интервал группировки", - "min": "Мин", - "max": "Maкс", - "avg": "Среднее", - "sum": "Сумма", - "count": "Количество", - "none": "Без агрегации" - }, - "admin": { - "general": "Общие", - "general-settings": "Общие настройки", - "outgoing-mail": "Исходящая почта", - "outgoing-mail-settings": "Настройки исходящей почты", - "system-settings": "Системные настройки", - "test-mail-sent": "Пробное письмо успешно отправлено!", - "base-url": "Базовая URL", - "base-url-required": "Базовая URL обязательна.", - "mail-from": "Отправитель", - "mail-from-required": "Отправитель обязателен.", - "smtp-protocol": "SMTP протокол", - "smtp-host": "SMTP хост", - "smtp-host-required": "SMTP хост обязателен.", - "smtp-port": "SMTP порт", - "smtp-port-required": "SMTP порт обязателен.", - "smtp-port-invalid": "Недействительный SMTP порт.", - "timeout-msec": "Таймаут (мс)", - "timeout-required": "Таймаут обязателен.", - "timeout-invalid": "Недействительный таймаут.", - "enable-tls": "Включить TLS", - "send-test-mail": "Отправить пробное письмо" - }, - "alarm": { // TODO - "alarm": "Alarm", - "alarms": "Alarms", - "select-alarm": "Select alarm", - "no-alarms-matching": "No alarms matching '{{entity}}' were found.", - "alarm-required": "Alarm is required", - "alarm-status": "Alarm status", - "search-status": { - "ANY": "Any", - "ACTIVE": "Active", - "CLEARED": "Cleared", - "ACK": "Acknowledged", - "UNACK": "Unacknowledged" - }, - "display-status": { - "ACTIVE_UNACK": "Active Unacknowledged", - "ACTIVE_ACK": "Active Acknowledged", - "CLEARED_UNACK": "Cleared Unacknowledged", - "CLEARED_ACK": "Cleared Acknowledged" - }, - "no-alarms-prompt": "No alarms found", - "created-time": "Created time", - "type": "Type", - "severity": "Severity", - "originator": "Originator", - "originator-type": "Originator type", - "details": "Details", - "status": "Status", - "alarm-details": "Alarm details", - "start-time": "Start time", - "end-time": "End time", - "ack-time": "Acknowledged time", - "clear-time": "Cleared time", - "severity-critical": "Critical", - "severity-major": "Major", - "severity-minor": "Minor", - "severity-warning": "Warning", - "severity-indeterminate": "Indeterminate", - "acknowledge": "Acknowledge", - "clear": "Clear", - "search": "Search alarms", - "selected-alarms": "{ count, select, 1 {1 alarm} other {# alarms} } selected", - "no-data": "No data to display", - "polling-interval": "Alarms polling interval (sec)", - "polling-interval-required": "Alarms polling interval is required.", - "min-polling-interval-message": "At least 1 sec polling interval is allowed.", - "aknowledge-alarms-title": "Acknowledge { count, select, 1 {1 alarm} other {# alarms} }", - "aknowledge-alarms-text": "Are you sure you want to acknowledge { count, select, 1 {1 alarm} other {# alarms} }?", - "clear-alarms-title": "Clear { count, select, 1 {1 alarm} other {# alarms} }", - "clear-alarms-text": "Are you sure you want to clear { count, select, 1 {1 alarm} other {# alarms} }?" - }, - "alias": { // TODO - "add": "Add alias", - "edit": "Edit alias", - "name": "Alias name", - "name-required": "Alias name is required", - "duplicate-alias": "Alias with same name is already exists.", - "filter-type-single-entity": "Single entity", - "filter-type-entity-list": "Entity list", - "filter-type-entity-name": "Entity name", - "filter-type-state-entity": "Entity from dashboard state", - "filter-type-state-entity-description": "Entity taken from dashboard state parameters", - "filter-type-asset-type": "Asset type", - "filter-type-asset-type-description": "Assets of type '{{assetType}}'", - "filter-type-asset-type-and-name-description": "Assets of type '{{assetType}}' and with name starting with '{{prefix}}'", - "filter-type-device-type": "Device type", - "filter-type-device-type-description": "Devices of type '{{deviceType}}'", - "filter-type-device-type-and-name-description": "Devices of type '{{deviceType}}' and with name starting with '{{prefix}}'", - "filter-type-relations-query": "Relations query", - "filter-type-relations-query-description": "{{entities}} that have {{relationType}} relation {{direction}} {{rootEntity}}", - "filter-type-asset-search-query": "Asset search query", - "filter-type-asset-search-query-description": "Assets with types {{assetTypes}} that have {{relationType}} relation {{direction}} {{rootEntity}}", - "filter-type-device-search-query": "Device search query", - "filter-type-device-search-query-description": "Devices with types {{deviceTypes}} that have {{relationType}} relation {{direction}} {{rootEntity}}", - "entity-filter": "Entity filter", - "resolve-multiple": "Resolve as multiple entities", - "filter-type": "Filter type", - "filter-type-required": "Filter type is required.", - "entity-filter-no-entity-matched": "No entities matching specified filter were found.", - "no-entity-filter-specified": "No entity filter specified", - "root-state-entity": "Use dashboard state entity as root", - "root-entity": "Root entity", - "state-entity-parameter-name": "State entity parameter name", - "default-state-entity": "Default state entity", - "default-entity-parameter-name": "By default", - "max-relation-level": "Max relation level", - "unlimited-level": "Unlimited level", - "state-entity": "Dashboard state entity", - "all-entities": "All entities", - "any-relation": "any" - }, - "asset": { // TODO - "asset": "Asset", - "assets": "Assets", - "management": "Asset management", - "view-assets": "View Assets", - "add": "Add Asset", - "assign-to-customer": "Assign to customer", - "assign-asset-to-customer": "Assign Asset(s) To Customer", - "assign-asset-to-customer-text": "Please select the assets to assign to the customer", - "no-assets-text": "No assets found", - "assign-to-customer-text": "Please select the customer to assign the asset(s)", - "public": "Public", - "assignedToCustomer": "Assigned to customer", - "make-public": "Make asset public", - "make-private": "Make asset private", - "unassign-from-customer": "Unassign from customer", - "delete": "Delete asset", - "asset-public": "Asset is public", - "asset-type": "Asset type", - "asset-type-required": "Asset type is required.", - "select-asset-type": "Select asset type", - "enter-asset-type": "Enter asset type", - "any-asset": "Any asset", - "no-asset-types-matching": "No asset types matching '{{entitySubtype}}' were found.", - "asset-type-list-empty": "No asset types selected.", - "asset-types": "Asset types", - "name": "Name", - "name-required": "Name is required.", - "description": "Description", - "type": "Type", - "type-required": "Type is required.", - "details": "Details", - "events": "Events", - "add-asset-text": "Add new asset", - "asset-details": "Asset details", - "assign-assets": "Assign assets", - "assign-assets-text": "Assign { count, select, 1 {1 asset} other {# assets} } to customer", - "delete-assets": "Delete assets", - "unassign-assets": "Unassign assets", - "unassign-assets-action-title": "Unassign { count, select, 1 {1 asset} other {# assets} } from customer", - "assign-new-asset": "Assign new asset", - "delete-asset-title": "Are you sure you want to delete the asset '{{assetName}}'?", - "delete-asset-text": "Be careful, after the confirmation the asset and all related data will become unrecoverable.", - "delete-assets-title": "Are you sure you want to delete { count, select, 1 {1 asset} other {# assets} }?", - "delete-assets-action-title": "Delete { count, select, 1 {1 asset} other {# assets} }", - "delete-assets-text": "Be careful, after the confirmation all selected assets will be removed and all related data will become unrecoverable.", - "make-public-asset-title": "Are you sure you want to make the asset '{{assetName}}' public?", - "make-public-asset-text": "After the confirmation the asset and all its data will be made public and accessible by others.", - "make-private-asset-title": "Are you sure you want to make the asset '{{assetName}}' private?", - "make-private-asset-text": "After the confirmation the asset and all its data will be made private and won't be accessible by others.", - "unassign-asset-title": "Are you sure you want to unassign the asset '{{assetName}}'?", - "unassign-asset-text": "After the confirmation the asset will be unassigned and won't be accessible by the customer.", - "unassign-asset": "Unassign asset", - "unassign-assets-title": "Are you sure you want to unassign { count, select, 1 {1 asset} other {# assets} }?", - "unassign-assets-text": "After the confirmation all selected assets will be unassigned and won't be accessible by the customer.", - "copyId": "Copy asset Id", - "idCopiedMessage": "Asset Id has been copied to clipboard", - "select-asset": "Select asset", - "no-assets-matching": "No assets matching '{{entity}}' were found.", - "asset-required": "Asset is required", - "name-starts-with": "Asset name starts with" - }, - "attribute": { - "attributes": "Атрибуты", - "latest-telemetry": "Последняя телеметрия", - "attributes-scope": "Контекст атрибутов устройства", - "scope-latest-telemetry": "Последняя телеметрия", - "scope-client": "Клиентские атрибуты", - "scope-server": "Серверные атрибуты", - "scope-shared": "Общие атрибуты", - "add": "Добавить атрибут", - "key": "Ключ", - "key-required": "Ключ атрибута обязателен.", - "value": "Значение", - "value-required": "Значение атрибута обязательно.", - "delete-attributes-title": "Вы уверенны, что хотите удалить { count, plural, one {1 атрибут} few {# атрибута} other {# атрибутов} }? ", - "delete-attributes-text": "Внимание, после подтверждения выбранные атрибуты будут удалены.", - "delete-attributes": "Удалить атрибуты", - "enter-attribute-value": "Введите значение атрибута", - "show-on-widget": "Показать на виджете", - "widget-mode": "Виджет-режим", - "next-widget": "Следующий виджет", - "prev-widget": "Предыдущий виджет", - "add-to-dashboard": "Добавить на дашборд", - "add-widget-to-dashboard": "Добавить виджет на дашборд", - "selected-attributes": "{ count, plural, 1 {Выбран} other {Выбраны} } { count, plural, one {1 атрибут} few {# атрибута} other {# атрибутов} }", - "selected-telemetry": "{ count, plural, 1 {Выбран} other {Выбраны} } { count, plural, 1 {1 параметр} few {# параметра} other {# параметров} } телеметрии" - }, - "audit-log": { // TODO - "audit": "Audit", - "audit-logs": "Audit Logs", - "timestamp": "Timestamp", - "entity-type": "Entity Type", - "entity-name": "Entity Name", - "user": "User", - "type": "Type", - "status": "Status", - "details": "Details", - "type-added": "Added", - "type-deleted": "Deleted", - "type-updated": "Updated", - "type-attributes-updated": "Attributes updated", - "type-attributes-deleted": "Attributes deleted", - "type-rpc-call": "RPC call", - "type-credentials-updated": "Credentials updated", - "type-assigned-to-customer": "Assigned to Customer", - "type-unassigned-from-customer": "Unassigned from Customer", - "type-activated": "Activated", - "type-suspended": "Suspended", - "type-credentials-read": "Credentials read", - "type-attributes-read": "Attributes read", - "status-success": "Success", - "status-failure": "Failure", - "audit-log-details": "Audit log details", - "no-audit-logs-prompt": "No logs found", - "action-data": "Action data", - "failure-details": "Failure details", - "search": "Search audit logs", - "clear-search": "Clear search" - }, - "confirm-on-exit": { - "message": "У вас есть несохраненные изменения. Вы точно хотите покинуть эту страницу?", - "html-message": "У вас есть несохраненные изменения.
Вы точно хотите покинуть эту страницу?", - "title": "Несохраненные изменения" - }, - "contact": { - "country": "Страна", - "city": "Город", - "state": "Штат", - "postal-code": "Почтовый код", - "postal-code-invalid": "Допустимы только цифры", - "address": "Адрес", - "address2": "Адрес 2", - "phone": "Телефон", - "email": "Эл. адрес", - "no-address": "Адрес не указан" - }, - "common": { - "username": "Имя пользователя", - "password": "Пароль", - "enter-username": "Введите имя пользователя", - "enter-password": "Введите пароль", - "enter-search": "Введите условие поиска" - }, - "content-type": { // TODO - "json": "Json", - "text": "Text", - "binary": "Binary (Base64)" - }, - "customer": { - "customers": "Клиенты", - "management": "Управление клиентами", - "dashboard": "Дашборд клиентов", - "dashboards": "Дашборды клиентов", - "devices": "Устройства клиента", - "public-dashboards": "Общедоступные дашборды", - "public-devices": "Общедоступные устройства", - "add": "Добавить клиента", - "delete": "Удалить клиента", - "manage-customer-users": "Управление пользователями клиента", - "manage-customer-devices": "Управление устройствами клиента", - "manage-customer-dashboards": "Управление дашбордами клиента", - "manage-public-devices": "Управление общедоступными устройствами", - "manage-public-dashboards": "Управление общедоступными дашбордами", - "add-customer-text": "Добавить нового клиента", - "no-customers-text": "Клиенты не найдены", - "customer-details": "Подробности о клиенте", - "delete-customer-title": "Вы точно хотите удалить клиента '{{customerTitle}}'?", - "delete-customer-text": "Внимание, после подтверждения клиент и вся связанная с ним информация будут безвозвратно утеряны.", - "delete-customers-title": "Вы точно хотите удалить { count, plural, one {1 клиента} other {# клиентов} }?", - "delete-customers-action-title": "Удалить { count, plural, one {1 клиента} other {# клиентов} } }", - "delete-customers-text": "Внимание, после подтверждения клиенты и вся связанная с ними информация будут безвозвратно утеряны.", - "manage-users": "Управление пользователями", - "manage-assets": "Manage assets", // TODO - "manage-devices": "Управление устройствами", - "manage-dashboards": "Управление дашбордами", - "title": "Имя", - "title-required": "Название обязательно.", - "description": "Описание", - "details": "Details", // TODO - "events": "Events", // TODO - "copyId": "Copy customer Id", // TODO - "idCopiedMessage": "Customer Id has been copied to clipboard", // TODO - "select-customer": "Select customer", // TODO - "no-customers-matching": "No customers matching '{{entity}}' were found.", // TODO - "customer-required": "Customer is required", // TODO - "select-default-customer": "Select default customer", // TODO - "default-customer": "Default customer", // TODO - "default-customer-required": "Default customer is required in order to debug dashboard on Tenant level" // TODO - }, - "datetime": { - "date-from": "Дата с", - "time-from": "Время с", - "date-to": "Дата до", - "time-to": "Время до" - }, - "dashboard": { - "dashboard": "Дашборд", - "dashboards": "Дашборды", - "management": "Управление дашбордами", - "view-dashboards": "Просмотреть дашборды", - "add": "Добавить дашборд", - "assign-dashboard-to-customer": "Прикрепить дашборд(ы) к клиенту", - "assign-dashboard-to-customer-text": "Пожалуйста, выберите дашборды, которые нужно прикрепить к клиенту", - "assign-to-customer-text": "Пожалуйста, выберите клиента, к которому нужно прикрепить дашборд(ы)", - "assign-to-customer": "Прикрепить к клиенту", - "unassign-from-customer": "Открепить от клиента", - "make-public": "Открыть дашборд для общего доступа", - "make-private": "Закрыть дашборд для общего доступа", - "no-dashboards-text": "Дашборды не найдены", - "no-widgets": "Виджеты не сконфигурированы", - "add-widget": "Добавить новый виджет", - "title": "Название", - "select-widget-title": "Выберите виджет", - "select-widget-subtitle": "Список доступных виджетов", - "delete": "Удалить дашборд", - "title-required": "Название обязательно.", - "description": "Описание", - "details": "Подробности", - "dashboard-details": "Подробности о дашборде", - "add-dashboard-text": "Добавить новый дашборд", - "assign-dashboards": "Прикрепить дашборды", - "assign-new-dashboard": "Прикрепить новый дашборд", - "assign-dashboards-text": "Прикрепить { count, plural, 1 {1 дашборд} other {# дашборда} } к клиенту", - "delete-dashboards": "Удалить дашборды", - "unassign-dashboards": "Открепить дашборды", - "unassign-dashboards-action-title": "Открепить { count, plural, one {1 дашборд} few {# дашборда} other {# дашбордов} } от клиента", - "delete-dashboard-title": "Вы точно хотите удалить дашборд '{{dashboardTitle}}'?", - "delete-dashboard-text": "Внимание, после подтверждения дашборд и все связанные с ним данные будут безвозвратно утеряны.", - "delete-dashboards-title": "Вы точно хотите удалить { count, plural, one {1 дашборд} few {# дашборда} other {# дашбордов} }?", - "delete-dashboards-action-title": "Удалить { count, plural, one {1 дашборд} few {# дашборда} other {# дашбордов} }", - "delete-dashboards-text": "Внимание, после подтверждения дашборды и все связанные с ними данные будут безвозвратно утеряны.", - "unassign-dashboard-title": "Вы точно хотите открепить дашборд '{{dashboardTitle}}'?", - "unassign-dashboard-text": "После подтверждения дашборд не будет доступен клиенту.", - "unassign-dashboard": "Открепить дашборд", - "unassign-dashboards-title": "Вы точно хотите открепить { count, plural, one {1 дашборд} few {# дашборда} other {# дашбордов} }?", - "unassign-dashboards-text": "После подтверждения выбранные дашборды не будут доступны клиенту.", - "public-dashboard-title": "Теперь дашборд общедоступный", - "public-dashboard-text": "Теперь ваш дашборд {{dashboardTitle}} доступен всем по ссылке:", - "public-dashboard-notice": "Примечание: Для получения доступа к данным устройства нужно открыть общий доступ к этому устройству.", - "make-private-dashboard-title": "Вы точно хотите закрыть общий доступ к дашборду '{{dashboardTitle}}'?", - "make-private-dashboard-text": "После подтверждения дашборд будет закрыт для общего доступа.", - "make-private-dashboard": "Закрыть дашборд для общего доступа", - "socialshare-text": "'{{dashboardTitle}}' сделано ThingsBoard", - "socialshare-title": "'{{dashboardTitle}}' сделано ThingsBoard", - "select-dashboard": "Выберите дашборд", - "no-dashboards-matching": "Дашборд '{{entity}}' не найден.", - "dashboard-required": "Дашборд обязателен.", - "select-existing": "Выберите существующий дашборд", - "create-new": "Создать новый дашборд", - "new-dashboard-title": "Новое название дашборда", - "open-dashboard": "Открыть дашборд", - "set-background": "Установить фон", - "background-color": "Фоновый цвет", - "background-image": "Фоновая картинка", - "background-size-mode": "Размер фона", - "no-image": "Картинка не выбрана", - "drop-image": "Перетащите картинку или кликните для выбора файла.", - "settings": "Настройки", - "columns-count": "Количество колонок", - "columns-count-required": "Количество колонок обязательно.", - "min-columns-count-message": "Минимальное число колонок - 10.", - "max-columns-count-message": "Максимальное число колонок - 1000.", - "widgets-margins": "Величина отступа между виджетами", - "horizontal-margin": "Величина горизонтального отступа", - "horizontal-margin-required": "Величина горизонтального отступа обязательна.", - "min-horizontal-margin-message": "Минимальная величина горизонтального отступа - 0.", - "max-horizontal-margin-message": "Максимальная величина горизонтального отступа - 50.", - "vertical-margin": "Величина вертикального отступа", - "vertical-margin-required": "Величина вертикального отступа обязательна.", - "min-vertical-margin-message": "Минимальная величина вертикального отступа - 0.", - "max-vertical-margin-message": "Максимальная величина вертикального отступа - 50.", - "display-title": "Показать название дашборда", - "title-color": "Цвет названия", - "display-device-selection": "Показать выборку устройств", - "display-dashboard-timewindow": "Показать временное окно", - "display-dashboard-export": "Показать экспорт", - "import": "Импортировать дашборд", - "export": "Экспортировать дашборд", - "export-failed-error": "Не удалось экспортировать дашборд: {{error}}", - "create-new-dashboard": "Создать новый дашборд", - "dashboard-file": "Файл дашборда", - "invalid-dashboard-file-error": "Не удалось импортировать дашборд: неизвестная схема данных дашборда.", - "dashboard-import-missing-aliases-title": "Конфигурировать псевдонимы импортированного дашборда", - "create-new-widget": "Создать новый виджет", - "import-widget": "Импортировать новый виджет", - "widget-file": "Файл виджета", - "invalid-widget-file-error": "Не удалось импортировать виджет: неизвестная схема данных виджета.", - "widget-import-missing-aliases-title": "Конфигурировать псевдонимы импортированного виджета", - "open-toolbar": "Открыть панель инструментов", - "close-toolbar": "Закрыть панель инструментов", - "configuration-error": "Ошибка конфигурирования", - "alias-resolution-error-title": "Ошибка конфигурирования псевдонимов дашборда", - "invalid-aliases-config": "Не удалось найти устройства, соответствующие фильтру псевдонимов.
" + - "Пожалуйста, свяжитесь с администратором для устранения этой проблемы.", - "select-devices": "Выберите устройства", - "assignedToCustomer": "Прикреплен к клиенту", - "public": "Общедоступный", - "public-link": "Общедоступная ссылка", - "copy-public-link": "Скопировать общедоступную ссылку", - "public-link-copied-message": "Общедоступная ссылка на дашборд скопирована в буфер обмена", - "manage-states": "Manage dashboard states", // TODO - "states": "Dashboard states", // TODO - "search-states": "Search dashboard states", // TODO - "selected-states": "{ count, select, 1 {1 dashboard state} other {# dashboard states} } selected", // TODO - "edit-state": "Edit dashboard state", // TODO - "delete-state": "Delete dashboard state", // TODO - "add-state": "Add dashboard state", // TODO - "state": "Dashboard state", // TODO - "state-name": "Name", // TODO - "state-name-required": "Dashboard state name is required.", // TODO - "state-id": "State Id", // TODO - "state-id-required": "Dashboard state id is required.", // TODO - "state-id-exists": "Dashboard state with the same id is already exists.", // TODO - "is-root-state": "Root state", // TODO - "delete-state-title": "Delete dashboard state", // TODO - "delete-state-text": "Are you sure you want delete dashboard state with name '{{stateName}}'?", // TODO - "show-details": "Show details", // TODO - "hide-details": "Hide details", // TODO - "select-state": "Select target state", // TODO - "state-controller": "State controller" // TODO - }, - "datakey": { - "settings": "Настройки", - "advanced": "Дополнительно", - "label": "Метка", - "color": "Цвет", - "units": "Special symbol to show next to value", // TODO - "decimals": "Number of digits after floating point", // TODO - "data-generation-func": "Функция генерации данных", - "use-data-post-processing-func": "Использовать функцию пост-обработки данных", - "configuration": "Конфигурация ключа данных", - "timeseries": "Выборка по времени", - "attributes": "Атрибуты", - "timeseries-required": "Выборка по времени обязательна.", - "timeseries-or-attributes-required": "Выборка по времени/атрибуты обязательны.", - "maximum-timeseries-or-attributes": "Maximum { count, select, 1 {1 timeseries/attribute is allowed.} other {# timeseries/attributes are allowed} }", // TODO - "alarm-fields-required": "Alarm fields are required.", // TODO - "function-types": "Тип функции", - "function-types-required": "Тип функции обязателен.", - "maximum-function-types": "Maximum { count, select, 1 {1 function type is allowed.} other {# function types are allowed} }" // TODO - }, - "datasource": { - "type": "Тип источника данных", - "add-datasource-prompt": "Пожалуйста, добавьте источник данных" - }, - "details": { - "edit-mode": "Режим редактирования", - "toggle-edit-mode": "Режим редактирования" - }, - "device": { - "device": "Устройство", - "device-required": "Устройство обязательно.", - "devices": "Устройства", - "management": "Управление устройствами", - "view-devices": "Просмотреть устройства", - "device-alias": "Псевдоним устройства", - "aliases": "Псевдонимы устройства", - "no-alias-matching": "'{{alias}}' не найден.", - "no-aliases-found": "Псевдонимы не найдены.", - "no-key-matching": "'{{key}}' не найден.", - "no-keys-found": "Ключи не найдены.", - "create-new-alias": "Создать новый!", - "create-new-key": "Создать новый!", - "duplicate-alias-error": "Найден дублирующийся псевдоним '{{alias}}'.
В рамках дашборда псевдонимы устройств должны быть уникальными.", - "configure-alias": "Конфигурировать '{{alias}}' псевдоним", - "no-devices-matching": "Устройство '{{entity}}' не найдено.", - "alias": "Псевдоним", - "alias-required": "Псевдоним устройства обязателен.", - "remove-alias": "Удалить псевдоним устройства", - "add-alias": "Добавить псевдоним устройства", - "name-starts-with": "Название начинается с", - "device-list": "Список устройств", - "use-device-name-filter": "Использовать фильтр", - "device-list-empty": "Устройства не выбраны.", - "device-name-filter-required": "Фильтр названия устройства обязателен.", - "device-name-filter-no-device-matched": "Устройства, названия которых начинаются с '{{device}}', не найдены.", - "add": "Добавить устройство", - "assign-to-customer": "Присвоить клиенту", - "assign-device-to-customer": "Присвоить устройство(а) клиенту", - "assign-device-to-customer-text": "Пожалуйста, выберите устройства, которые нужно присвоить клиенту", - "make-public": "Открыть общий доступ к устройству", - "make-private": "Закрыть общий доступ к устройству", - "no-devices-text": "Устройства не найдены", - "assign-to-customer-text": "Пожалуйста, выберите клиента, которому нужно присвоить устройство(а)", - "device-details": "Подробности об устройстве", - "add-device-text": "Добавить новое устройство", - "credentials": "Учетные данные", - "manage-credentials": "Управление учетными данными", - "delete": "Удалить устройство", - "assign-devices": "Присвоить устройство", - "assign-devices-text": "Присвоить { count, plural, one {1 устройство} few {# устройства} other {# устройств} } клиенту", - "delete-devices": "Удалить устройства", - "unassign-from-customer": "Отменить присвоение клиенту", - "unassign-devices": "Отменить присвоение устройств", - "unassign-devices-action-title": "Отменить присвоение { count, plural, one {1 устройства} few {# устройств} other {# устройств} } клиенту", - "assign-new-device": "Присвоить новое устройство", - "make-public-device-title": "Вы точно хотите открыть общий доступ к устройству '{{deviceName}}'?", - "make-public-device-text": "После подтверждения устройство и все связанные с ним данные будут общедоступными.", - "make-private-device-title": "Вы точно хотите закрыть общий доступ к устройству '{{deviceName}}'", - "make-private-device-text": "После подтверждения устройство и все связанные с ним данные будут закрыты для общего доступа.", - "view-credentials": "Просмотреть учетные данные", - "delete-device-title": "Вы точно хотите удалить устройство '{{deviceName}}'?", - "delete-device-text": "Внимание, после подтверждения устройство и все связанные с ним данные будут безвозвратно утеряны.", - "delete-devices-title": "Вы точно хотите удалить { count, plural, one {1 устройство} few {# устройства} other {# устройств} }?", - "delete-devices-action-title": "Удалить { count, plural, one {1 устройство} few {# устройства} other {# устройств} } }", - "delete-devices-text": "Внимание, после подтверждения выбранные устройства и все связанные с ними данные будут безвозвратно утеряны..", - "unassign-device-title": "Вы точно хотите отменить присвоение устройства '{{deviceName}}'?", - "unassign-device-text": "После подтверждения устройство будет недоступно клиенту.", - "unassign-device": "Отменить присвоение устройства", - "unassign-devices-title": "Вы точно хотите отменить присвоение { count, plural, one {1 устройство} few {# устройства} other {# устройств} } }?", - "unassign-devices-text": "После подтверждения выбранные устройства будут недоступны клиенту.", - "device-credentials": "Учетные данные устройства", - "credentials-type": "Тип учетных данных", - "access-token": "Токен", - "access-token-required": "Токен обязателен.", - "access-token-invalid": "Длина токена должна быть от 1 до 20 символов.", - "rsa-key": "Открытый ключ RSA", - "rsa-key-required": "Открытый ключ RSA обязателен.", - "secret": "Секрет", - "secret-required": "Секрет обязателен.", - "name": "Название", - "name-required": "Название обязательно.", - "description": "Описание", - "events": "События", - "details": "Подробности", - "copyId": "Копировать идентификатор устройства", - "copyAccessToken": "Копировать токен", - "idCopiedMessage": "Идентификатор устройства скопирован в буфер обмена", - "accessTokenCopiedMessage": "Токен устройства скопирован в буфер обмена", - "assignedToCustomer": "Присвоен клиенту", - "unable-delete-device-alias-title": "Не удалось удалить псевдоним устройства", - "unable-delete-device-alias-text": "Не удалось удалить псевдоним '{{deviceAlias}}' устройства, т.к. он используется следующими виджетами:
{{widgetsList}}", - "is-gateway": "Гейтвей", - "public": "Общедоступный", - "device-public": "Устройство общедоступно" - }, - "dialog": { - "close": "Закрыть диалог" - }, - "error": { - "unable-to-connect": "Не удалось подключиться к серверу! Пожалуйста, проверьте интернет-соединение.", - "unhandled-error-code": "Код необработанной ошибки: {{errorCode}}", - "unknown-error": "Неизвестная ошибка" - }, - "entity": { // TODO - "entity": "Entity", - "entities": "Entities", - "aliases": "Entity aliases", - "entity-alias": "Entity alias", - "unable-delete-entity-alias-title": "Unable to delete entity alias", - "unable-delete-entity-alias-text": "Entity alias '{{entityAlias}}' can't be deleted as it used by the following widget(s):
{{widgetsList}}", - "duplicate-alias-error": "Duplicate alias found '{{alias}}'.
Entity aliases must be unique whithin the dashboard.", - "missing-entity-filter-error": "Filter is missing for alias '{{alias}}'.", - "configure-alias": "Configure '{{alias}}' alias", - "alias": "Alias", - "alias-required": "Entity alias is required.", - "remove-alias": "Remove entity alias", - "add-alias": "Add entity alias", - "entity-list": "Entity list", - "entity-type": "Entity type", - "entity-types": "Entity types", - "entity-type-list": "Entity type list", - "any-entity": "Any entity", - "enter-entity-type": "Enter entity type", - "no-entities-matching": "No entities matching '{{entity}}' were found.", - "no-entity-types-matching": "No entity types matching '{{entityType}}' were found.", - "name-starts-with": "Name starts with", - "use-entity-name-filter": "Use filter", - "entity-list-empty": "No entities selected.", - "entity-type-list-empty": "No entity types selected.", - "entity-name-filter-required": "Entity name filter is required.", - "entity-name-filter-no-entity-matched": "No entities starting with '{{entity}}' were found.", - "all-subtypes": "All", - "select-entities": "Select entities", - "no-aliases-found": "No aliases found.", - "no-alias-matching": "'{{alias}}' not found.", - "create-new-alias": "Create a new one!", - "key": "Key", - "key-name": "Key name", - "no-keys-found": "No keys found.", - "no-key-matching": "'{{key}}' not found.", - "create-new-key": "Create a new one!", - "type": "Type", - "type-required": "Entity type is required.", - "type-device": "Device", - "type-devices": "Devices", - "list-of-devices": "{ count, select, 1 {One device} other {List of # devices} }", - "device-name-starts-with": "Devices whose names start with '{{prefix}}'", - "type-asset": "Asset", - "type-assets": "Assets", - "list-of-assets": "{ count, select, 1 {One asset} other {List of # assets} }", - "asset-name-starts-with": "Assets whose names start with '{{prefix}}'", - "type-rule": "Rule", - "type-rules": "Rules", - "list-of-rules": "{ count, select, 1 {One rule} other {List of # rules} }", - "rule-name-starts-with": "Rules whose names start with '{{prefix}}'", - "type-plugin": "Plugin", - "type-plugins": "Plugins", - "list-of-plugins": "{ count, select, 1 {One plugin} other {List of # plugins} }", - "plugin-name-starts-with": "Plugins whose names start with '{{prefix}}'", - "type-tenant": "Tenant", - "type-tenants": "Tenants", - "list-of-tenants": "{ count, select, 1 {One tenant} other {List of # tenants} }", - "tenant-name-starts-with": "Tenants whose names start with '{{prefix}}'", - "type-customer": "Customer", - "type-customers": "Customers", - "list-of-customers": "{ count, select, 1 {One customer} other {List of # customers} }", - "customer-name-starts-with": "Customers whose names start with '{{prefix}}'", - "type-user": "User", - "type-users": "Users", - "list-of-users": "{ count, select, 1 {One user} other {List of # users} }", - "user-name-starts-with": "Users whose names start with '{{prefix}}'", - "type-dashboard": "Dashboard", - "type-dashboards": "Dashboards", - "list-of-dashboards": "{ count, select, 1 {One dashboard} other {List of # dashboards} }", - "dashboard-name-starts-with": "Dashboards whose names start with '{{prefix}}'", - "type-alarm": "Alarm", - "type-alarms": "Alarms", - "list-of-alarms": "{ count, select, 1 {One alarms} other {List of # alarms} }", - "alarm-name-starts-with": "Alarms whose names start with '{{prefix}}'", - "type-rulechain": "Rule chain", - "type-rulechains": "Rule chains", - "list-of-rulechains": "{ count, select, 1 {One rule chain} other {List of # rule chains} }", - "rulechain-name-starts-with": "Rule chains whose names start with '{{prefix}}'", - "type-current-customer": "Current Customer", - "search": "Search entities", - "selected-entities": "{ count, select, 1 {1 entity} other {# entities} } selected", - "entity-name": "Entity name", - "details": "Entity details", - "no-entities-prompt": "No entities found", - "no-data": "No data to display" - }, - "event": { - "event-type": "Тип события", - "type-error": "Ошибка", - "type-lc-event": "Событие жизненного цикла", - "type-stats": "Статистика", - "type-debug-rule-node": "Debug", // TODO - "type-debug-rule-chain": "Debug", // TODO - "no-events-prompt": "События не найдены", - "error": "Ошибка", - "alarm": "Аварийное оповещение", - "event-time": "Время возникновения события", - "server": "Сервер", - "body": "Тело", - "method": "Метод", - "type": "Type", // TODO - "entity": "Entity", // TODO - "message-id": "Message Id", // TODO - "message-type": "Message Type", // TODO - "data-type": "Data Type", // TODO - "relation-type": "Relation Type", // TODO - "metadata": "Metadata", // TODO - "data": "Data", // TODO - "event": "Событие", - "status": "Статус", - "success": "Успех", - "failed": "Неудача", - "messages-processed": "Сообщения обработаны", - "errors-occurred": "Возникли ошибки" - }, - "extension": { // TODO - "extensions": "Extensions", - "selected-extensions": "{ count, select, 1 {1 extension} other {# extensions} } selected", - "type": "Type", - "key": "Key", - "value": "Value", - "id": "Id", - "extension-id": "Extension id", - "extension-type": "Extension type", - "transformer-json": "JSON *", - "unique-id-required": "Current extension id already exists.", - "delete": "Delete extension", - "add": "Add extension", - "edit": "Edit extension", - "delete-extension-title": "Are you sure you want to delete the extension '{{extensionId}}'?", - "delete-extension-text": "Be careful, after the confirmation the extension and all related data will become unrecoverable.", - "delete-extensions-title": "Are you sure you want to delete { count, select, 1 {1 extension} other {# extensions} }?", - "delete-extensions-text": "Be careful, after the confirmation all selected extensions will be removed.", - "converters": "Converters", - "converter-id": "Converter id", - "configuration": "Configuration", - "converter-configurations": "Converter configurations", - "token": "Security token", - "add-converter": "Add converter", - "add-config": "Add converter configuration", - "device-name-expression": "Device name expression", - "device-type-expression": "Device type expression", - "custom": "Custom", - "to-double": "To Double", - "transformer": "Transformer", - "json-required": "Transformer json is required.", - "json-parse": "Unable to parse transformer json.", - "attributes": "Attributes", - "add-attribute": "Add attribute", - "add-map": "Add mapping element", - "timeseries": "Timeseries", - "add-timeseries": "Add timeseries", - "field-required": "Field is required", - "brokers": "Brokers", - "add-broker": "Add broker", - "host": "Host", - "port": "Port", - "port-range": "Port should be in a range from 1 to 65535.", - "ssl": "Ssl", - "credentials": "Credentials", - "username": "Username", - "password": "Password", - "retry-interval": "Retry interval in milliseconds", - "anonymous": "Anonymous", - "basic": "Basic", - "pem": "PEM", - "ca-cert": "CA certificate file *", - "private-key": "Private key file *", - "cert": "Certificate file *", - "no-file": "No file selected.", - "drop-file": "Drop a file or click to select a file to upload.", - "mapping": "Mapping", - "topic-filter": "Topic filter", - "converter-type": "Converter type", - "converter-json": "Json", - "json-name-expression": "Device name json expression", - "topic-name-expression": "Device name topic expression", - "json-type-expression": "Device type json expression", - "topic-type-expression": "Device type topic expression", - "attribute-key-expression": "Attribute key expression", - "attr-json-key-expression": "Attribute key json expression", - "attr-topic-key-expression": "Attribute key topic expression", - "request-id-expression": "Request id expression", - "request-id-json-expression": "Request id json expression", - "request-id-topic-expression": "Request id topic expression", - "response-topic-expression": "Response topic expression", - "value-expression": "Value expression", - "topic": "Topic", - "timeout": "Timeout in milliseconds", - "converter-json-required": "Converter json is required.", - "converter-json-parse": "Unable to parse converter json.", - "filter-expression": "Filter expression", - "connect-requests": "Connect requests", - "add-connect-request": "Add connect request", - "disconnect-requests": "Disconnect requests", - "add-disconnect-request": "Add disconnect request", - "attribute-requests": "Attribute requests", - "add-attribute-request": "Add attribute request", - "attribute-updates": "Attribute updates", - "add-attribute-update": "Add attribute update", - "server-side-rpc": "Server side RPC", - "add-server-side-rpc-request": "Add server-side RPC request", - "device-name-filter": "Device name filter", - "attribute-filter": "Attribute filter", - "method-filter": "Method filter", - "request-topic-expression": "Request topic expression", - "response-timeout": "Response timeout in milliseconds", - "topic-expression": "Topic expression", - "client-scope": "Client scope", - "add-device": "Add device", - "opc-server": "Servers", - "opc-add-server": "Add server", - "opc-add-server-prompt": "Please add server", - "opc-application-name": "Application name", - "opc-application-uri": "Application uri", - "opc-scan-period-in-seconds": "Scan period in seconds", - "opc-security": "Security", - "opc-identity": "Identity", - "opc-keystore": "Keystore", - "opc-type": "Type", - "opc-keystore-type": "Type", - "opc-keystore-location": "Location *", - "opc-keystore-password": "Password", - "opc-keystore-alias": "Alias", - "opc-keystore-key-password": "Key password", - "opc-device-node-pattern": "Device node pattern", - "opc-device-name-pattern": "Device name pattern", - "modbus-server": "Servers/slaves", - "modbus-add-server": "Add server/slave", - "modbus-add-server-prompt": "Please add server/slave", - "modbus-transport": "Transport", - "modbus-port-name": "Serial port name", - "modbus-encoding": "Encoding", - "modbus-parity": "Parity", - "modbus-baudrate": "Baud rate", - "modbus-databits": "Data bits", - "modbus-stopbits": "Stop bits", - "modbus-databits-range": "Data bits should be in a range from 7 to 8.", - "modbus-stopbits-range": "Stop bits should be in a range from 1 to 2.", - "modbus-unit-id": "Unit ID", - "modbus-unit-id-range": "Unit ID should be in a range from 1 to 247.", - "modbus-device-name": "Device name", - "modbus-poll-period": "Poll period (ms)", - "modbus-attributes-poll-period": "Attributes poll period (ms)", - "modbus-timeseries-poll-period": "Timeseries poll period (ms)", - "modbus-poll-period-range": "Poll period should be positive value.", - "modbus-tag": "Tag", - "modbus-function": "Function", - "modbus-register-address": "Register address", - "modbus-register-address-range": "Register address should be in a range from 0 to 65535.", - "modbus-register-bit-index": "Bit index", - "modbus-register-bit-index-range": "Bit index should be in a range from 0 to 15.", - "modbus-register-count": "Register count", - "modbus-register-count-range": "Register count should be a positive value.", - "modbus-byte-order": "Byte order", - - "sync": { - "status": "Status", - "sync": "Sync", - "not-sync": "Not sync", - "last-sync-time": "Last sync time", - "not-available": "Not available" - }, - - "export-extensions-configuration": "Export extensions configuration", - "import-extensions-configuration": "Import extensions configuration", - "import-extensions": "Import extensions", - "import-extension": "Import extension", - "export-extension": "Export extension", - "file": "Extensions file", - "invalid-file-error": "Invalid extension file" - }, - "fullscreen": { - "expand": "Во весь экран", - "exit": "Выйти из полноэкранного режима", - "toggle": "Во весь экран", - "fullscreen": "Полноэкранный режим" - }, - "function": { - "function": "Функция" - }, - "grid": { - "delete-item-title": "Вы точно хотите удалить этот объект?", - "delete-item-text": "Внимание, после подтверждения объект и все связанные с ним данные будут безвозвратно утеряны.", - "delete-items-title": "Вы точно хотите удалить { count, plural, one {1 объект} few {# объекта} other {# объектов} }?", - "delete-items-action-title": "Удалить { count, plural, one {1 объект} few {# объекта} other {# объектов}", - "delete-items-text": "Внимание, после подтверждения выбранные объекты и все связанные с ними данные будут безвозвратно утеряны.", - "add-item-text": "Добавить новый объект", - "no-items-text": "Объекты не найдены", - "item-details": "Подробности об объекте", - "delete-item": "Удалить объект", - "delete-items": "Удалить объекты", - "scroll-to-top": "Прокрутка к началу" - }, - "help": { - "goto-help-page": "Перейти к справке" - }, - "home": { - "home": "Главная", - "profile": "Профиль", - "logout": "Выйти из системы", - "menu": "Меню", - "avatar": "Аватар", - "open-user-menu": "Открыть меню пользователя" - }, - "import": { - "no-file": "Файл не выбран", - "drop-file": "Перетащите JSON файл или кликните для выбора файла." - }, - "item": { - "selected": "Выбранные" - }, - "js-func": { - "no-return-error": "Функция должна возвращать значение!", - "return-type-mismatch": "Функция должна возвращать значение типа '{{type}}'!", - "tidy": "Tidy" // TODO - }, - "key-val": { // TODO - "key": "Key", - "value": "Value", - "remove-entry": "Remove entry", - "add-entry": "Add entry", - "no-data": "No entries" - }, - "layout": { // TODO - "layout": "Layout", - "manage": "Manage layouts", - "settings": "Layout settings", - "color": "Color", - "main": "Main", - "right": "Right", - "select": "Select target layout" - }, - "legend": { - "position": "Расположение легенды", - "show-max": "Показать максимальное значение", - "show-min": "Показать минимальное значение", - "show-avg": "Показать среднее значение", - "show-total": "Показать сумму", - "settings": "Настройки легенды", - "min": "Мин", - "max": "Макс", - "avg": "Среднее", - "total": "Сумма" - }, - "login": { - "login": "Войти", - "request-password-reset": "Запрос на сброс пароля", - "reset-password": "Сбросить пароль", - "create-password": "Создать пароль", - "passwords-mismatch-error": "Введенные пароли должны быть одинаковыми!", - "password-again": "Введите пароль еще раз", - "sign-in": "Пожалуйста, войдите в систему", - "username": "Имя пользователя (эл. адрес)", - "remember-me": "Запомнить меня", - "forgot-password": "Забыли пароль?", - "password-reset": "Пароль сброшен", - "new-password": "Новый пароль", - "new-password-again": "Повторите новый пароль", - "password-link-sent-message": "Ссылка для сброса пароля была успешно отправлена!", - "email": "Эл. адрес" - }, - "position": { - "top": "Верх", - "bottom": "Низ", - "left": "Левый край", - "right": "Правый край" - }, - "profile": { - "profile": "Профиль", - "change-password": "Изменить пароль", - "current-password": "Текущий пароль" - }, - "relation": { // TODO - "relations": "Relations", - "direction": "Direction", - "search-direction": { - "FROM": "From", - "TO": "To" - }, - "direction-type": { - "FROM": "from", - "TO": "to" - }, - "from-relations": "Outbound relations", - "to-relations": "Inbound relations", - "selected-relations": "{ count, select, 1 {1 relation} other {# relations} } selected", - "type": "Type", - "to-entity-type": "To entity type", - "to-entity-name": "To entity name", - "from-entity-type": "From entity type", - "from-entity-name": "From entity name", - "to-entity": "To entity", - "from-entity": "From entity", - "delete": "Delete relation", - "relation-type": "Relation type", - "relation-type-required": "Relation type is required.", - "any-relation-type": "Any type", - "add": "Add relation", - "edit": "Edit relation", - "delete-to-relation-title": "Are you sure you want to delete relation to the entity '{{entityName}}'?", - "delete-to-relation-text": "Be careful, after the confirmation the entity '{{entityName}}' will be unrelated from the current entity.", - "delete-to-relations-title": "Are you sure you want to delete { count, select, 1 {1 relation} other {# relations} }?", - "delete-to-relations-text": "Be careful, after the confirmation all selected relations will be removed and corresponding entities will be unrelated from the current entity.", - "delete-from-relation-title": "Are you sure you want to delete relation from the entity '{{entityName}}'?", - "delete-from-relation-text": "Be careful, after the confirmation current entity will be unrelated from the entity '{{entityName}}'.", - "delete-from-relations-title": "Are you sure you want to delete { count, select, 1 {1 relation} other {# relations} }?", - "delete-from-relations-text": "Be careful, after the confirmation all selected relations will be removed and current entity will be unrelated from the corresponding entities.", - "remove-relation-filter": "Remove relation filter", - "add-relation-filter": "Add relation filter", - "any-relation": "Any relation", - "relation-filters": "Relation filters", - "additional-info": "Additional info (JSON)", - "invalid-additional-info": "Unable to parse additional info json." - }, - "rulechain": { // TODO - "rulechain": "Rule chain", - "rulechains": "Rule chains", - "root": "Root", - "delete": "Delete rule chain", - "name": "Name", - "name-required": "Name is required.", - "description": "Description", - "add": "Add Rule Chain", - "set-root": "Make rule chain root", - "set-root-rulechain-title": "Are you sure you want to make the rule chain '{{ruleChainName}}' root?", - "set-root-rulechain-text": "After the confirmation the rule chain will become root and will handle all incoming transport messages.", - "delete-rulechain-title": "Are you sure you want to delete the rule chain '{{ruleChainName}}'?", - "delete-rulechain-text": "Be careful, after the confirmation the rule chain and all related data will become unrecoverable.", - "delete-rulechains-title": "Are you sure you want to delete { count, select, 1 {1 rule chain} other {# rule chains} }?", - "delete-rulechains-action-title": "Delete { count, select, 1 {1 rule chain} other {# rule chains} }", - "delete-rulechains-text": "Be careful, after the confirmation all selected rule chains will be removed and all related data will become unrecoverable.", - "add-rulechain-text": "Add new rule chain", - "no-rulechains-text": "No rule chains found", - "rulechain-details": "Rule chain details", - "details": "Details", - "events": "Events", - "system": "System", - "import": "Import rule chain", - "export": "Export rule chain", - "export-failed-error": "Unable to export rule chain: {{error}}", - "create-new-rulechain": "Create new rule chain", - "rulechain-file": "Rule chain file", - "invalid-rulechain-file-error": "Unable to import rule chain: Invalid rule chain data structure.", - "copyId": "Copy rule chain Id", - "idCopiedMessage": "Rule chain Id has been copied to clipboard", - "select-rulechain": "Select rule chain", - "no-rulechains-matching": "No rule chains matching '{{entity}}' were found.", - "rulechain-required": "Rule chain is required", - "management": "Rules management", - "debug-mode": "Debug mode" - }, - "rulenode": { // TODO - "details": "Details", - "events": "Events", - "search": "Search nodes", - "open-node-library": "Open node library", - "add": "Add rule node", - "name": "Name", - "name-required": "Name is required.", - "type": "Type", - "description": "Description", - "delete": "Delete rule node", - "select-all-objects": "Select all nodes and connections", - "deselect-all-objects": "Deselect all nodes and connections", - "delete-selected-objects": "Delete selected nodes and connections", - "delete-selected": "Delete selected", - "select-all": "Select all", - "copy-selected": "Copy selected", - "deselect-all": "Deselect all", - "rulenode-details": "Rule node details", - "debug-mode": "Debug mode", - "configuration": "Configuration", - "link": "Link", - "link-details": "Rule node link details", - "add-link": "Add link", - "link-label": "Link label", - "link-label-required": "Link label is required.", - "custom-link-label": "Custom link label", - "custom-link-label-required": "Custom link label is required.", - "type-filter": "Filter", - "type-filter-details": "Filter incoming messages with configured conditions", - "type-enrichment": "Enrichment", - "type-enrichment-details": "Add additional information into Message Metadata", - "type-transformation": "Transformation", - "type-transformation-details": "Change Message payload and Metadata", - "type-action": "Action", - "type-action-details": "Perform special action", - "type-external": "External", - "type-external-details": "Interacts with external system", - "type-rule-chain": "Rule Chain", - "type-rule-chain-details": "Forwards incoming messages to specified Rule Chain", - "type-input": "Input", - "type-input-details": "Logical input of Rule Chain, forwards incoming messages to next related Rule Node", - "directive-is-not-loaded": "Defined configuration directive '{{directiveName}}' is not available.", - "ui-resources-load-error": "Failed to load configuration ui resources.", - "invalid-target-rulechain": "Unable to resolve target rule chain!", - "test-script-function": "Test script function", - "message": "Message", - "message-type": "Message type", - "message-type-required": "Message type is required", - "metadata": "Metadata", - "metadata-required": "Metadata entries can't be empty.", - "output": "Output", - "test": "Test", - "help": "Help" - }, - "tenant": { - "tenants": "Владельцы", - "management": "Управление владельцами", - "add": "Добавить владельца", - "admins": "Администраторы", - "manage-tenant-admins": "Управление администраторами владельца", - "delete": "Удалить владельца", - "add-tenant-text": "Добавить нового владельца", - "no-tenants-text": "Владельцы не найдены", - "tenant-details": "Подробности об владельце", - "delete-tenant-title": "Вы точно хотите удалить владельца '{{tenantTitle}}'?", - "delete-tenant-text": "Внимание, после подтверждения владелец и все связанные с ним данные будут безвозвратно утеряны.", - "delete-tenants-title": "Вы точно хотите удалить { count, plural, one {1 владельца} other {# владельцев} }?", - "delete-tenants-action-title": "Удалить { count, plural, one {1 владельца} other {# владельцев} }", - "delete-tenants-text": "Внимание, после подтверждения выбранные Владельцы и все связанные с ними данные будут безвозвратно утеряны.", - "title": "Имя", - "title-required": "Имя обязательно.", - "description": "Описание" - }, - "timeinterval": { - "seconds-interval": "{ seconds, plural, one {1 секунда} few {# секунды} other {# секунд} }", - "minutes-interval": "{ minutes, plural, one {1 минута} few {# минуты} other {# минут} }", - "hours-interval": "{ hours, plural, one {1 час} few {# часа} other {# часов} }", - "days-interval": "{ days, plural, one {1 день} few {# дня} other {# дней} }", - "days": "Дни", - "hours": "Часы", - "minutes": "Минуты", - "seconds": "Секунды", - "advanced": "Дополнительно" - }, - "timewindow": { - "days": "{ days, plural, one {1 день} few {# дня} other {# дней} }", - "hours": "{ hours, plural, one {1 час} few {# часа} other {# часов} }", - "minutes": "{ minutes, plural, one {1 минута} few {# минуты} other {# минут} }", - "seconds": "{ seconds, plural, one {1 секунда} few {# секунды} other {# секунд} }", - "realtime": "Режим реального времени", - "history": "История", - "last-prefix": "Последние", - "period": "с {{ startTime }} до {{ endTime }}", - "edit": "Изменить временное окно", - "date-range": "Диапазон дат", - "last": "Последние", - "time-period": "Период времени" - }, - "user": { - "users": "Пользователи", - "customer-users": "Пользователи клиента", - "tenant-admins": "Администраторы владельца", - "sys-admin": "Системный администратор", - "tenant-admin": "Администратор владельца", - "customer": "Клиент", - "anonymous": "Аноним", - "add": "Добавить пользователя", - "delete": "Удалить пользователя", - "add-user-text": "Добавить нового пользователя", - "no-users-text": "Пользователи не найдены", - "user-details": "Подробности о пользователе", - "delete-user-title": "Вы точно хотите удалить пользователя '{{userEmail}}'?", - "delete-user-text": "Внимание, после подтверждения пользователь и все связанные с ним данные будут безвозвратно утеряны.", - "delete-users-title": "Вы точно хотите удалить { count, plural, one {1 пользователя} other {# пользователей} }?", - "delete-users-action-title": "Удалить { count, plural, one {1 пользователя} other {# пользователей} }", - "delete-users-text": "Внимание, после подтверждения выбранные пользователи и все связанные с ними данные будут безвозвратно утеряны.", - "activation-email-sent-message": "Активационное письмо успешно отправлено!", - "resend-activation": "Повторить отправку активационного письма", - "email": "Эл. адрес", - "email-required": "Эл. адрес обязателен.", - "first-name": "Имя", - "last-name": "Фамилия", - "description": "Описание", - "default-dashboard": "Дашборд по умолчанию", - "always-fullscreen": "Всегда во весь экран" - }, - "value": { - "type": "Тип значения", - "string": "Строка", - "string-value": "Строковое значение", - "integer": "Целое число", - "integer-value": "Целочисленное значение", - "invalid-integer-value": "Неправильный формат целого числа", - "double": "Число двойной точности", - "double-value": "Значение двойной точности", - "boolean": "Логический тип", - "boolean-value": "Логическое значение", - "false": "Ложь", - "true": "Правда" - }, - "widget": { - "widget-library": "Галерея виджетов", - "widget-bundle": "Набор виджетов", - "select-widgets-bundle": "Выберите набор виджетов", - "management": "Управление виджетами", - "editor": "Редактор виджетов", - "widget-type-not-found": "Ошибка при загрузке конфигурации виджета.
Возможно, связанный с ней\n тип виджета уже удален.", - "widget-type-load-error": "Не удалось загрузить виджет по следующим причинам:", - "remove": "Удалить виджет", - "edit": "Редактировать виджет", - "remove-widget-title": "Вы точно хотите удалить виджет '{{widgetTitle}}'?", - "remove-widget-text": "Внимание, после подтверждения виджет и все связанные с ним данные будут безвозвратно утеряны.", - "timeseries": "Выборка по времени", - "latest-values": "Последние значения", - "rpc": "Управляющий виджет", - "static": "Статический виджет", - "select-widget-type": "Выберите тип виджета", - "missing-widget-title-error": "Укажите название виджета!", - "widget-saved": "Виджет сохранен", - "unable-to-save-widget-error": "Не удалось сохранить виджет! Виджет содержит ошибки!", - "save": "Сохранить виджет", - "saveAs": "Сохранить виджет как", - "save-widget-type-as": "Сохранить тип виджета как", - "save-widget-type-as-text": "Пожалуйста, введите название виджета и/или укажите целевой набор виджетов", - "toggle-fullscreen": "Во весь экран", - "run": "Запустить виджет", - "title": "Название виджета", - "title-required": "Название виджета обязательно.", - "type": "Тип виджета", - "resources": "Ресурсы", - "resource-url": "JavaScript/CSS URL", - "remove-resource": "Удалить ресурс", - "add-resource": "Добавить ресурс", - "html": "HTML", - "tidy": "Форматировать", - "css": "CSS", - "settings-schema": "Схема конфигурации", - "datakey-settings-schema": "Схема конфигурации ключа данных", - "javascript": "Javascript", - "remove-widget-type-title": "Вы точно хотите удалить виджет '{{widgetName}}'?", - "remove-widget-type-text": "Внимание, после подтверждения тип виджета и все связанные с ним данные будут безвозвратно утеряны.", - "remove-widget-type": "Удалить тип виджета", - "add-widget-type": "Добавить новый тип виджета", - "widget-type-load-failed-error": "Не удалось загрузить тип виджета!", - "widget-template-load-failed-error": "Не удалось загрузить шаблон виджета!", - "add": "Добавить виджет", - "undo": "Откатить изменения в виджете", - "export": "Экспортировать виджет" - }, - "widget-action": { // TODO - "header-button": "Widget header button", - "open-dashboard-state": "Navigate to new dashboard state", - "update-dashboard-state": "Update current dashboard state", - "open-dashboard": "Navigate to other dashboard", - "custom": "Custom action", - "target-dashboard-state": "Target dashboard state", - "target-dashboard-state-required": "Target dashboard state is required", - "set-entity-from-widget": "Set entity from widget", - "target-dashboard": "Target dashboard", - "open-right-layout": "Open right dashboard layout (mobile view)" - }, - "widgets-bundle": { - "current": "Текущий набор", - "widgets-bundles": "Наборы виджетов", - "add": "Добавить набор виджетов", - "delete": "Удалить набор виджетов", - "title": "Название", - "title-required": "Название обязательно.", - "add-widgets-bundle-text": "Добавить новый набор виджетов", - "no-widgets-bundles-text": "Наборы виджетов не найдены", - "empty": "Пустой набор виджетов", - "details": "Подробности", - "widgets-bundle-details": "Подробности о наборе виджетов", - "delete-widgets-bundle-title": "Вы точно хотите удалить набор виджетов '{{widgetsBundleTitle}}'?", - "delete-widgets-bundle-text": "Внимание, после подтверждения набор виджетов и все связанные с ним данные будут безвозвратно утеряны.", - "delete-widgets-bundles-title": "Вы точно хотите удалить { count, plural, one {1 набор виджетов} few {# набора виджетов} other {# наборов виджетов} }?", - "delete-widgets-bundles-action-title": "Удалить { count, plural, one {1 набор виджетов} few {# набора виджетов} other {# наборов виджетов} }", - "delete-widgets-bundles-text": "Внимание, после подтверждения выбранные наборы виджетов и все связанные с ними данные будут безвозвратно утеряны..", - "no-widgets-bundles-matching": "Набор виджетов '{{widgetsBundle}}' не найден.", - "widgets-bundle-required": "Набор виджетов обязателен.", - "system": "Системный", - "import": "Импортировать набор виджетов", - "export": "Экспортировать набор виджетов", - "export-failed-error": "Не удалось экспортировать набор виджетов: {{error}}", - "create-new-widgets-bundle": "Создать новый набор виджетов", - "widgets-bundle-file": "Файл набора виджетов", - "invalid-widgets-bundle-file-error": "Не удалось импортировать набор виджетов: неизвестная схема данных набора виджетов." - }, - "widget-config": { - "data": "Данные", - "settings": "Настройки", - "advanced": "Дополнительно", - "title": "Название", - "general-settings": "Общие настройки", - "display-title": "Показать название", - "drop-shadow": "Тень", - "enable-fullscreen": "Во весь экран", - "background-color": "Цвет фона", - "text-color": "Цвет текста", - "padding": "Отступ", - "title-style": "Стиль названия", - "mobile-mode-settings": "Настройки мобильного режима", - "order": "Порядок", - "height": "Высота", - "units": "Специальный символ после значения", - "decimals": "Количество цифр после запятой", - "timewindow": "Временное окно", - "use-dashboard-timewindow": "Использовать временное окно дашборда", - "display-legend": "Показать легенду", - "datasources": "Источники данных", - "datasource-type": "Тип", - "datasource-parameters": "Параметры", - "remove-datasource": "Удалить источник данных", - "add-datasource": "Добавить источник данных", - "target-device": "Целевое устройство" - }, - "widget-type": { - "import": "Импортировать тип виджета", - "export": "Экспортировать тип виджета", - "export-failed-error": "Не удалось экспортировать тип виджета: {{error}}", - "create-new-widget-type": "Создать новый тип виджета", - "widget-type-file": "Файл типа виджета", - "invalid-widget-type-file-error": "Не удалось импортировать виджет: неизвестная схема данных типа виджета." - }, - "icon": { // TODO - "icon": "Icon", - "select-icon": "Select icon", - "material-icons": "Material icons", - "show-all": "Show all icons" - }, - "custom": { // TODO - "widget-action": { - "action-cell-button": "Action cell button", - "row-click": "On row click", - "marker-click": "On marker click", - "tooltip-tag-action": "Tooltip tag action" - } - }, - "language": { - "language": "Язык", - "en_US": "Английский", - "ko_KR": "Корейский", - "zh_CN": "Китайский", - "ru_RU": "Русский", - "es_ES": "испанский" - - } - }; - angular.extend(locales, { 'ru_RU': ru_RU }); -} \ No newline at end of file diff --git a/ui/src/app/locale/locale.constant-ru_RU.json b/ui/src/app/locale/locale.constant-ru_RU.json new file mode 100644 index 0000000000..2e384e95dc --- /dev/null +++ b/ui/src/app/locale/locale.constant-ru_RU.json @@ -0,0 +1,1365 @@ +{ + "access": { + "unauthorized": "Неавторизированный", + "unauthorized-access": "Несанкционированный доступ", + "unauthorized-access-text": "Вы должны войти в систему для получения доступа к этому ресурсу!", + "access-forbidden": "Доступ запрещен", + "access-forbidden-text": "У вас нет прав доступа к этому ресурсу!
Для получения доступа попробуйте войти под другим пользователем.", + "refresh-token-expired": "Сессия истекла", + "refresh-token-failed": "Не удалось обновить сессию" + }, + "action": { + "activate": "Активировать", + "suspend": "Приостановить", + "save": "Сохранить", + "saveAs": "Сохранить как", + "cancel": "Отмена", + "ok": "ОК", + "delete": "Удалить", + "add": "Добавить", + "yes": "Да", + "no": "Нет", + "update": "Обновить", + "remove": "Удалить", + "search": "Поиск", + "assign": "Присвоить", + "unassign": "Отменить присвоение", + "share": "Поделиться", + "make-private": "Закрыть для общего доступа", + "apply": "Применить", + "apply-changes": "Применить изменения", + "edit-mode": "Режим редактирования", + "enter-edit-mode": "Режим редактирования", + "decline-changes": "Отменить изменения", + "close": "Закрыть", + "back": "Назад", + "run": "Запуск", + "sign-in": "Войти", + "edit": "Редактировать", + "view": "Просмотреть", + "create": "Создать", + "drag": "Переместить", + "refresh": "Обновить", + "undo": "Откатить", + "copy": "Копировать", + "paste": "Вставить", + "import": "Импортировать", + "export": "Экспортировать", + "share-via": "Поделиться в {{provider}}" + }, + "aggregation": { + "aggregation": "Агрегация", + "function": "Тип агрегации данных", + "limit": "Максимальное значение", + "group-interval": "Интервал группировки", + "min": "Мин", + "max": "Maкс", + "avg": "Среднее", + "sum": "Сумма", + "count": "Количество", + "none": "Без агрегации" + }, + "admin": { + "general": "Общие", + "general-settings": "Общие настройки", + "outgoing-mail": "Исходящая почта", + "outgoing-mail-settings": "Настройки исходящей почты", + "system-settings": "Системные настройки", + "test-mail-sent": "Пробное письмо успешно отправлено!", + "base-url": "Базовая URL", + "base-url-required": "Базовая URL обязательна.", + "mail-from": "Отправитель", + "mail-from-required": "Отправитель обязателен.", + "smtp-protocol": "SMTP протокол", + "smtp-host": "SMTP хост", + "smtp-host-required": "SMTP хост обязателен.", + "smtp-port": "SMTP порт", + "smtp-port-required": "SMTP порт обязателен.", + "smtp-port-invalid": "Недействительный SMTP порт.", + "timeout-msec": "Таймаут (мс)", + "timeout-required": "Таймаут обязателен.", + "timeout-invalid": "Недействительный таймаут.", + "enable-tls": "Включить TLS", + "send-test-mail": "Отправить пробное письмо" + }, + "alarm": { + "alarm": "Alarm", + "alarms": "Alarms", + "select-alarm": "Select alarm", + "no-alarms-matching": "No alarms matching '{{entity}}' were found.", + "alarm-required": "Alarm is required", + "alarm-status": "Alarm status", + "search-status": { + "ANY": "Any", + "ACTIVE": "Active", + "CLEARED": "Cleared", + "ACK": "Acknowledged", + "UNACK": "Unacknowledged" + }, + "display-status": { + "ACTIVE_UNACK": "Active Unacknowledged", + "ACTIVE_ACK": "Active Acknowledged", + "CLEARED_UNACK": "Cleared Unacknowledged", + "CLEARED_ACK": "Cleared Acknowledged" + }, + "no-alarms-prompt": "No alarms found", + "created-time": "Created time", + "type": "Type", + "severity": "Severity", + "originator": "Originator", + "originator-type": "Originator type", + "details": "Details", + "status": "Status", + "alarm-details": "Alarm details", + "start-time": "Start time", + "end-time": "End time", + "ack-time": "Acknowledged time", + "clear-time": "Cleared time", + "severity-critical": "Critical", + "severity-major": "Major", + "severity-minor": "Minor", + "severity-warning": "Warning", + "severity-indeterminate": "Indeterminate", + "acknowledge": "Acknowledge", + "clear": "Clear", + "search": "Search alarms", + "selected-alarms": "{ count, plural, 1 {1 alarm} other {# alarms} } selected", + "no-data": "No data to display", + "polling-interval": "Alarms polling interval (sec)", + "polling-interval-required": "Alarms polling interval is required.", + "min-polling-interval-message": "At least 1 sec polling interval is allowed.", + "aknowledge-alarms-title": "Acknowledge { count, plural, 1 {1 alarm} other {# alarms} }", + "aknowledge-alarms-text": "Are you sure you want to acknowledge { count, plural, 1 {1 alarm} other {# alarms} }?", + "clear-alarms-title": "Clear { count, plural, 1 {1 alarm} other {# alarms} }", + "clear-alarms-text": "Are you sure you want to clear { count, plural, 1 {1 alarm} other {# alarms} }?" + }, + "alias": { + "add": "Add alias", + "edit": "Edit alias", + "name": "Alias name", + "name-required": "Alias name is required", + "duplicate-alias": "Alias with same name is already exists.", + "filter-type-single-entity": "Single entity", + "filter-type-entity-list": "Entity list", + "filter-type-entity-name": "Entity name", + "filter-type-state-entity": "Entity from dashboard state", + "filter-type-state-entity-description": "Entity taken from dashboard state parameters", + "filter-type-asset-type": "Asset type", + "filter-type-asset-type-description": "Assets of type '{{assetType}}'", + "filter-type-asset-type-and-name-description": "Assets of type '{{assetType}}' and with name starting with '{{prefix}}'", + "filter-type-device-type": "Device type", + "filter-type-device-type-description": "Devices of type '{{deviceType}}'", + "filter-type-device-type-and-name-description": "Devices of type '{{deviceType}}' and with name starting with '{{prefix}}'", + "filter-type-relations-query": "Relations query", + "filter-type-relations-query-description": "{{entities}} that have {{relationType}} relation {{direction}} {{rootEntity}}", + "filter-type-asset-search-query": "Asset search query", + "filter-type-asset-search-query-description": "Assets with types {{assetTypes}} that have {{relationType}} relation {{direction}} {{rootEntity}}", + "filter-type-device-search-query": "Device search query", + "filter-type-device-search-query-description": "Devices with types {{deviceTypes}} that have {{relationType}} relation {{direction}} {{rootEntity}}", + "entity-filter": "Entity filter", + "resolve-multiple": "Resolve as multiple entities", + "filter-type": "Filter type", + "filter-type-required": "Filter type is required.", + "entity-filter-no-entity-matched": "No entities matching specified filter were found.", + "no-entity-filter-specified": "No entity filter specified", + "root-state-entity": "Use dashboard state entity as root", + "root-entity": "Root entity", + "state-entity-parameter-name": "State entity parameter name", + "default-state-entity": "Default state entity", + "default-entity-parameter-name": "By default", + "max-relation-level": "Max relation level", + "unlimited-level": "Unlimited level", + "state-entity": "Dashboard state entity", + "all-entities": "All entities", + "any-relation": "any" + }, + "asset": { + "asset": "Asset", + "assets": "Assets", + "management": "Asset management", + "view-assets": "View Assets", + "add": "Add Asset", + "assign-to-customer": "Assign to customer", + "assign-asset-to-customer": "Assign Asset(s) To Customer", + "assign-asset-to-customer-text": "Please select the assets to assign to the customer", + "no-assets-text": "No assets found", + "assign-to-customer-text": "Please select the customer to assign the asset(s)", + "public": "Public", + "assignedToCustomer": "Assigned to customer", + "make-public": "Make asset public", + "make-private": "Make asset private", + "unassign-from-customer": "Unassign from customer", + "delete": "Delete asset", + "asset-public": "Asset is public", + "asset-type": "Asset type", + "asset-type-required": "Asset type is required.", + "select-asset-type": "Select asset type", + "enter-asset-type": "Enter asset type", + "any-asset": "Any asset", + "no-asset-types-matching": "No asset types matching '{{entitySubtype}}' were found.", + "asset-type-list-empty": "No asset types selected.", + "asset-types": "Asset types", + "name": "Name", + "name-required": "Name is required.", + "description": "Description", + "type": "Type", + "type-required": "Type is required.", + "details": "Details", + "events": "Events", + "add-asset-text": "Add new asset", + "asset-details": "Asset details", + "assign-assets": "Assign assets", + "assign-assets-text": "Assign { count, plural, 1 {1 asset} other {# assets} } to customer", + "delete-assets": "Delete assets", + "unassign-assets": "Unassign assets", + "unassign-assets-action-title": "Unassign { count, plural, 1 {1 asset} other {# assets} } from customer", + "assign-new-asset": "Assign new asset", + "delete-asset-title": "Are you sure you want to delete the asset '{{assetName}}'?", + "delete-asset-text": "Be careful, after the confirmation the asset and all related data will become unrecoverable.", + "delete-assets-title": "Are you sure you want to delete { count, plural, 1 {1 asset} other {# assets} }?", + "delete-assets-action-title": "Delete { count, plural, 1 {1 asset} other {# assets} }", + "delete-assets-text": "Be careful, after the confirmation all selected assets will be removed and all related data will become unrecoverable.", + "make-public-asset-title": "Are you sure you want to make the asset '{{assetName}}' public?", + "make-public-asset-text": "After the confirmation the asset and all its data will be made public and accessible by others.", + "make-private-asset-title": "Are you sure you want to make the asset '{{assetName}}' private?", + "make-private-asset-text": "After the confirmation the asset and all its data will be made private and won't be accessible by others.", + "unassign-asset-title": "Are you sure you want to unassign the asset '{{assetName}}'?", + "unassign-asset-text": "After the confirmation the asset will be unassigned and won't be accessible by the customer.", + "unassign-asset": "Unassign asset", + "unassign-assets-title": "Are you sure you want to unassign { count, plural, 1 {1 asset} other {# assets} }?", + "unassign-assets-text": "After the confirmation all selected assets will be unassigned and won't be accessible by the customer.", + "copyId": "Copy asset Id", + "idCopiedMessage": "Asset Id has been copied to clipboard", + "select-asset": "Select asset", + "no-assets-matching": "No assets matching '{{entity}}' were found.", + "asset-required": "Asset is required", + "name-starts-with": "Asset name starts with" + }, + "attribute": { + "attributes": "Атрибуты", + "latest-telemetry": "Последняя телеметрия", + "attributes-scope": "Контекст атрибутов устройства", + "scope-latest-telemetry": "Последняя телеметрия", + "scope-client": "Клиентские атрибуты", + "scope-server": "Серверные атрибуты", + "scope-shared": "Общие атрибуты", + "add": "Добавить атрибут", + "key": "Ключ", + "key-required": "Ключ атрибута обязателен.", + "value": "Значение", + "value-required": "Значение атрибута обязательно.", + "delete-attributes-title": "Вы уверенны, что хотите удалить { count, plural, one {1 атрибут} few {# атрибута} other {# атрибутов} }? ", + "delete-attributes-text": "Внимание, после подтверждения выбранные атрибуты будут удалены.", + "delete-attributes": "Удалить атрибуты", + "enter-attribute-value": "Введите значение атрибута", + "show-on-widget": "Показать на виджете", + "widget-mode": "Виджет-режим", + "next-widget": "Следующий виджет", + "prev-widget": "Предыдущий виджет", + "add-to-dashboard": "Добавить на дашборд", + "add-widget-to-dashboard": "Добавить виджет на дашборд", + "selected-attributes": "{ count, plural, 1 {Выбран} other {Выбраны} } { count, plural, one {1 атрибут} few {# атрибута} other {# атрибутов} }", + "selected-telemetry": "{ count, plural, 1 {Выбран} other {Выбраны} } { count, plural, 1 {1 параметр} few {# параметра} other {# параметров} } телеметрии" + }, + "audit-log": { + "audit": "Audit", + "audit-logs": "Audit Logs", + "timestamp": "Timestamp", + "entity-type": "Entity Type", + "entity-name": "Entity Name", + "user": "User", + "type": "Type", + "status": "Status", + "details": "Details", + "type-added": "Added", + "type-deleted": "Deleted", + "type-updated": "Updated", + "type-attributes-updated": "Attributes updated", + "type-attributes-deleted": "Attributes deleted", + "type-rpc-call": "RPC call", + "type-credentials-updated": "Credentials updated", + "type-assigned-to-customer": "Assigned to Customer", + "type-unassigned-from-customer": "Unassigned from Customer", + "type-activated": "Activated", + "type-suspended": "Suspended", + "type-credentials-read": "Credentials read", + "type-attributes-read": "Attributes read", + "status-success": "Success", + "status-failure": "Failure", + "audit-log-details": "Audit log details", + "no-audit-logs-prompt": "No logs found", + "action-data": "Action data", + "failure-details": "Failure details", + "search": "Search audit logs", + "clear-search": "Clear search" + }, + "confirm-on-exit": { + "message": "У вас есть несохраненные изменения. Вы точно хотите покинуть эту страницу?", + "html-message": "У вас есть несохраненные изменения.
Вы точно хотите покинуть эту страницу?", + "title": "Несохраненные изменения" + }, + "contact": { + "country": "Страна", + "city": "Город", + "state": "Штат", + "postal-code": "Почтовый код", + "postal-code-invalid": "Допустимы только цифры", + "address": "Адрес", + "address2": "Адрес 2", + "phone": "Телефон", + "email": "Эл. адрес", + "no-address": "Адрес не указан" + }, + "common": { + "username": "Имя пользователя", + "password": "Пароль", + "enter-username": "Введите имя пользователя", + "enter-password": "Введите пароль", + "enter-search": "Введите условие поиска" + }, + "content-type": { + "json": "Json", + "text": "Text", + "binary": "Binary (Base64)" + }, + "customer": { + "customers": "Клиенты", + "management": "Управление клиентами", + "dashboard": "Дашборд клиентов", + "dashboards": "Дашборды клиентов", + "devices": "Устройства клиента", + "public-dashboards": "Общедоступные дашборды", + "public-devices": "Общедоступные устройства", + "add": "Добавить клиента", + "delete": "Удалить клиента", + "manage-customer-users": "Управление пользователями клиента", + "manage-customer-devices": "Управление устройствами клиента", + "manage-customer-dashboards": "Управление дашбордами клиента", + "manage-public-devices": "Управление общедоступными устройствами", + "manage-public-dashboards": "Управление общедоступными дашбордами", + "add-customer-text": "Добавить нового клиента", + "no-customers-text": "Клиенты не найдены", + "customer-details": "Подробности о клиенте", + "delete-customer-title": "Вы точно хотите удалить клиента '{{customerTitle}}'?", + "delete-customer-text": "Внимание, после подтверждения клиент и вся связанная с ним информация будут безвозвратно утеряны.", + "delete-customers-title": "Вы точно хотите удалить { count, plural, one {1 клиента} other {# клиентов} }?", + "delete-customers-action-title": "Удалить { count, plural, one {1 клиента} other {# клиентов} } }", + "delete-customers-text": "Внимание, после подтверждения клиенты и вся связанная с ними информация будут безвозвратно утеряны.", + "manage-users": "Управление пользователями", + "manage-assets": "Manage assets", + "manage-devices": "Управление устройствами", + "manage-dashboards": "Управление дашбордами", + "title": "Имя", + "title-required": "Название обязательно.", + "description": "Описание", + "details": "Details", + "events": "Events", + "copyId": "Copy customer Id", + "idCopiedMessage": "Customer Id has been copied to clipboard", + "select-customer": "Select customer", + "no-customers-matching": "No customers matching '{{entity}}' were found.", + "customer-required": "Customer is required", + "select-default-customer": "Select default customer", + "default-customer": "Default customer", + "default-customer-required": "Default customer is required in order to debug dashboard on Tenant level" + }, + "datetime": { + "date-from": "Дата с", + "time-from": "Время с", + "date-to": "Дата до", + "time-to": "Время до" + }, + "dashboard": { + "dashboard": "Дашборд", + "dashboards": "Дашборды", + "management": "Управление дашбордами", + "view-dashboards": "Просмотреть дашборды", + "add": "Добавить дашборд", + "assign-dashboard-to-customer": "Прикрепить дашборд(ы) к клиенту", + "assign-dashboard-to-customer-text": "Пожалуйста, выберите дашборды, которые нужно прикрепить к клиенту", + "assign-to-customer-text": "Пожалуйста, выберите клиента, к которому нужно прикрепить дашборд(ы)", + "assign-to-customer": "Прикрепить к клиенту", + "unassign-from-customer": "Открепить от клиента", + "make-public": "Открыть дашборд для общего доступа", + "make-private": "Закрыть дашборд для общего доступа", + "no-dashboards-text": "Дашборды не найдены", + "no-widgets": "Виджеты не сконфигурированы", + "add-widget": "Добавить новый виджет", + "title": "Название", + "select-widget-title": "Выберите виджет", + "select-widget-subtitle": "Список доступных виджетов", + "delete": "Удалить дашборд", + "title-required": "Название обязательно.", + "description": "Описание", + "details": "Подробности", + "dashboard-details": "Подробности о дашборде", + "add-dashboard-text": "Добавить новый дашборд", + "assign-dashboards": "Прикрепить дашборды", + "assign-new-dashboard": "Прикрепить новый дашборд", + "assign-dashboards-text": "Прикрепить { count, plural, 1 {1 дашборд} other {# дашборда} } к клиенту", + "delete-dashboards": "Удалить дашборды", + "unassign-dashboards": "Открепить дашборды", + "unassign-dashboards-action-title": "Открепить { count, plural, one {1 дашборд} few {# дашборда} other {# дашбордов} } от клиента", + "delete-dashboard-title": "Вы точно хотите удалить дашборд '{{dashboardTitle}}'?", + "delete-dashboard-text": "Внимание, после подтверждения дашборд и все связанные с ним данные будут безвозвратно утеряны.", + "delete-dashboards-title": "Вы точно хотите удалить { count, plural, one {1 дашборд} few {# дашборда} other {# дашбордов} }?", + "delete-dashboards-action-title": "Удалить { count, plural, one {1 дашборд} few {# дашборда} other {# дашбордов} }", + "delete-dashboards-text": "Внимание, после подтверждения дашборды и все связанные с ними данные будут безвозвратно утеряны.", + "unassign-dashboard-title": "Вы точно хотите открепить дашборд '{{dashboardTitle}}'?", + "unassign-dashboard-text": "После подтверждения дашборд не будет доступен клиенту.", + "unassign-dashboard": "Открепить дашборд", + "unassign-dashboards-title": "Вы точно хотите открепить { count, plural, one {1 дашборд} few {# дашборда} other {# дашбордов} }?", + "unassign-dashboards-text": "После подтверждения выбранные дашборды не будут доступны клиенту.", + "public-dashboard-title": "Теперь дашборд общедоступный", + "public-dashboard-text": "Теперь ваш дашборд {{dashboardTitle}} доступен всем по ссылке:", + "public-dashboard-notice": "Примечание: Для получения доступа к данным устройства нужно открыть общий доступ к этому устройству.", + "make-private-dashboard-title": "Вы точно хотите закрыть общий доступ к дашборду '{{dashboardTitle}}'?", + "make-private-dashboard-text": "После подтверждения дашборд будет закрыт для общего доступа.", + "make-private-dashboard": "Закрыть дашборд для общего доступа", + "socialshare-text": "'{{dashboardTitle}}' сделано ThingsBoard", + "socialshare-title": "'{{dashboardTitle}}' сделано ThingsBoard", + "select-dashboard": "Выберите дашборд", + "no-dashboards-matching": "Дашборд '{{entity}}' не найден.", + "dashboard-required": "Дашборд обязателен.", + "select-existing": "Выберите существующий дашборд", + "create-new": "Создать новый дашборд", + "new-dashboard-title": "Новое название дашборда", + "open-dashboard": "Открыть дашборд", + "set-background": "Установить фон", + "background-color": "Фоновый цвет", + "background-image": "Фоновая картинка", + "background-size-mode": "Размер фона", + "no-image": "Картинка не выбрана", + "drop-image": "Перетащите картинку или кликните для выбора файла.", + "settings": "Настройки", + "columns-count": "Количество колонок", + "columns-count-required": "Количество колонок обязательно.", + "min-columns-count-message": "Минимальное число колонок - 10.", + "max-columns-count-message": "Максимальное число колонок - 1000.", + "widgets-margins": "Величина отступа между виджетами", + "horizontal-margin": "Величина горизонтального отступа", + "horizontal-margin-required": "Величина горизонтального отступа обязательна.", + "min-horizontal-margin-message": "Минимальная величина горизонтального отступа - 0.", + "max-horizontal-margin-message": "Максимальная величина горизонтального отступа - 50.", + "vertical-margin": "Величина вертикального отступа", + "vertical-margin-required": "Величина вертикального отступа обязательна.", + "min-vertical-margin-message": "Минимальная величина вертикального отступа - 0.", + "max-vertical-margin-message": "Максимальная величина вертикального отступа - 50.", + "display-title": "Показать название дашборда", + "title-color": "Цвет названия", + "display-device-selection": "Показать выборку устройств", + "display-dashboard-timewindow": "Показать временное окно", + "display-dashboard-export": "Показать экспорт", + "import": "Импортировать дашборд", + "export": "Экспортировать дашборд", + "export-failed-error": "Не удалось экспортировать дашборд: {{error}}", + "create-new-dashboard": "Создать новый дашборд", + "dashboard-file": "Файл дашборда", + "invalid-dashboard-file-error": "Не удалось импортировать дашборд: неизвестная схема данных дашборда.", + "dashboard-import-missing-aliases-title": "Конфигурировать псевдонимы импортированного дашборда", + "create-new-widget": "Создать новый виджет", + "import-widget": "Импортировать новый виджет", + "widget-file": "Файл виджета", + "invalid-widget-file-error": "Не удалось импортировать виджет: неизвестная схема данных виджета.", + "widget-import-missing-aliases-title": "Конфигурировать псевдонимы импортированного виджета", + "open-toolbar": "Открыть панель инструментов", + "close-toolbar": "Закрыть панель инструментов", + "configuration-error": "Ошибка конфигурирования", + "alias-resolution-error-title": "Ошибка конфигурирования псевдонимов дашборда", + "invalid-aliases-config": "Не удалось найти устройства, соответствующие фильтру псевдонимов.
Пожалуйста, свяжитесь с администратором для устранения этой проблемы.", + "select-devices": "Выберите устройства", + "assignedToCustomer": "Прикреплен к клиенту", + "public": "Общедоступный", + "public-link": "Общедоступная ссылка", + "copy-public-link": "Скопировать общедоступную ссылку", + "public-link-copied-message": "Общедоступная ссылка на дашборд скопирована в буфер обмена", + "manage-states": "Manage dashboard states", + "states": "Dashboard states", + "search-states": "Search dashboard states", + "selected-states": "{ count, plural, 1 {1 dashboard state} other {# dashboard states} } selected", + "edit-state": "Edit dashboard state", + "delete-state": "Delete dashboard state", + "add-state": "Add dashboard state", + "state": "Dashboard state", + "state-name": "Name", + "state-name-required": "Dashboard state name is required.", + "state-id": "State Id", + "state-id-required": "Dashboard state id is required.", + "state-id-exists": "Dashboard state with the same id is already exists.", + "is-root-state": "Root state", + "delete-state-title": "Delete dashboard state", + "delete-state-text": "Are you sure you want delete dashboard state with name '{{stateName}}'?", + "show-details": "Show details", + "hide-details": "Hide details", + "select-state": "Select target state", + "state-controller": "State controller" + }, + "datakey": { + "settings": "Настройки", + "advanced": "Дополнительно", + "label": "Метка", + "color": "Цвет", + "units": "Special symbol to show next to value", + "decimals": "Number of digits after floating point", + "data-generation-func": "Функция генерации данных", + "use-data-post-processing-func": "Использовать функцию пост-обработки данных", + "configuration": "Конфигурация ключа данных", + "timeseries": "Выборка по времени", + "attributes": "Атрибуты", + "timeseries-required": "Выборка по времени обязательна.", + "timeseries-or-attributes-required": "Выборка по времени/атрибуты обязательны.", + "maximum-timeseries-or-attributes": "Maximum { count, plural, 1 {1 timeseries/attribute is allowed.} other {# timeseries/attributes are allowed} }", + "alarm-fields-required": "Alarm fields are required.", + "function-types": "Тип функции", + "function-types-required": "Тип функции обязателен.", + "maximum-function-types": "Maximum { count, plural, 1 {1 function type is allowed.} other {# function types are allowed} }" + }, + "datasource": { + "type": "Тип источника данных", + "add-datasource-prompt": "Пожалуйста, добавьте источник данных" + }, + "details": { + "edit-mode": "Режим редактирования", + "toggle-edit-mode": "Режим редактирования" + }, + "device": { + "device": "Устройство", + "device-required": "Устройство обязательно.", + "devices": "Устройства", + "management": "Управление устройствами", + "view-devices": "Просмотреть устройства", + "device-alias": "Псевдоним устройства", + "aliases": "Псевдонимы устройства", + "no-alias-matching": "'{{alias}}' не найден.", + "no-aliases-found": "Псевдонимы не найдены.", + "no-key-matching": "'{{key}}' не найден.", + "no-keys-found": "Ключи не найдены.", + "create-new-alias": "Создать новый!", + "create-new-key": "Создать новый!", + "duplicate-alias-error": "Найден дублирующийся псевдоним '{{alias}}'.
В рамках дашборда псевдонимы устройств должны быть уникальными.", + "configure-alias": "Конфигурировать '{{alias}}' псевдоним", + "no-devices-matching": "Устройство '{{entity}}' не найдено.", + "alias": "Псевдоним", + "alias-required": "Псевдоним устройства обязателен.", + "remove-alias": "Удалить псевдоним устройства", + "add-alias": "Добавить псевдоним устройства", + "name-starts-with": "Название начинается с", + "device-list": "Список устройств", + "use-device-name-filter": "Использовать фильтр", + "device-list-empty": "Устройства не выбраны.", + "device-name-filter-required": "Фильтр названия устройства обязателен.", + "device-name-filter-no-device-matched": "Устройства, названия которых начинаются с '{{device}}', не найдены.", + "add": "Добавить устройство", + "assign-to-customer": "Присвоить клиенту", + "assign-device-to-customer": "Присвоить устройство(а) клиенту", + "assign-device-to-customer-text": "Пожалуйста, выберите устройства, которые нужно присвоить клиенту", + "make-public": "Открыть общий доступ к устройству", + "make-private": "Закрыть общий доступ к устройству", + "no-devices-text": "Устройства не найдены", + "assign-to-customer-text": "Пожалуйста, выберите клиента, которому нужно присвоить устройство(а)", + "device-details": "Подробности об устройстве", + "add-device-text": "Добавить новое устройство", + "credentials": "Учетные данные", + "manage-credentials": "Управление учетными данными", + "delete": "Удалить устройство", + "assign-devices": "Присвоить устройство", + "assign-devices-text": "Присвоить { count, plural, one {1 устройство} few {# устройства} other {# устройств} } клиенту", + "delete-devices": "Удалить устройства", + "unassign-from-customer": "Отменить присвоение клиенту", + "unassign-devices": "Отменить присвоение устройств", + "unassign-devices-action-title": "Отменить присвоение { count, plural, one {1 устройства} few {# устройств} other {# устройств} } клиенту", + "assign-new-device": "Присвоить новое устройство", + "make-public-device-title": "Вы точно хотите открыть общий доступ к устройству '{{deviceName}}'?", + "make-public-device-text": "После подтверждения устройство и все связанные с ним данные будут общедоступными.", + "make-private-device-title": "Вы точно хотите закрыть общий доступ к устройству '{{deviceName}}'", + "make-private-device-text": "После подтверждения устройство и все связанные с ним данные будут закрыты для общего доступа.", + "view-credentials": "Просмотреть учетные данные", + "delete-device-title": "Вы точно хотите удалить устройство '{{deviceName}}'?", + "delete-device-text": "Внимание, после подтверждения устройство и все связанные с ним данные будут безвозвратно утеряны.", + "delete-devices-title": "Вы точно хотите удалить { count, plural, one {1 устройство} few {# устройства} other {# устройств} }?", + "delete-devices-action-title": "Удалить { count, plural, one {1 устройство} few {# устройства} other {# устройств} } }", + "delete-devices-text": "Внимание, после подтверждения выбранные устройства и все связанные с ними данные будут безвозвратно утеряны..", + "unassign-device-title": "Вы точно хотите отменить присвоение устройства '{{deviceName}}'?", + "unassign-device-text": "После подтверждения устройство будет недоступно клиенту.", + "unassign-device": "Отменить присвоение устройства", + "unassign-devices-title": "Вы точно хотите отменить присвоение { count, plural, one {1 устройство} few {# устройства} other {# устройств} } }?", + "unassign-devices-text": "После подтверждения выбранные устройства будут недоступны клиенту.", + "device-credentials": "Учетные данные устройства", + "credentials-type": "Тип учетных данных", + "access-token": "Токен", + "access-token-required": "Токен обязателен.", + "access-token-invalid": "Длина токена должна быть от 1 до 20 символов.", + "rsa-key": "Открытый ключ RSA", + "rsa-key-required": "Открытый ключ RSA обязателен.", + "secret": "Секрет", + "secret-required": "Секрет обязателен.", + "name": "Название", + "name-required": "Название обязательно.", + "description": "Описание", + "events": "События", + "details": "Подробности", + "copyId": "Копировать идентификатор устройства", + "copyAccessToken": "Копировать токен", + "idCopiedMessage": "Идентификатор устройства скопирован в буфер обмена", + "accessTokenCopiedMessage": "Токен устройства скопирован в буфер обмена", + "assignedToCustomer": "Присвоен клиенту", + "unable-delete-device-alias-title": "Не удалось удалить псевдоним устройства", + "unable-delete-device-alias-text": "Не удалось удалить псевдоним '{{deviceAlias}}' устройства, т.к. он используется следующими виджетами:
{{widgetsList}}", + "is-gateway": "Гейтвей", + "public": "Общедоступный", + "device-public": "Устройство общедоступно" + }, + "dialog": { + "close": "Закрыть диалог" + }, + "error": { + "unable-to-connect": "Не удалось подключиться к серверу! Пожалуйста, проверьте интернет-соединение.", + "unhandled-error-code": "Код необработанной ошибки: {{errorCode}}", + "unknown-error": "Неизвестная ошибка" + }, + "entity": { + "entity": "Entity", + "entities": "Entities", + "aliases": "Entity aliases", + "entity-alias": "Entity alias", + "unable-delete-entity-alias-title": "Unable to delete entity alias", + "unable-delete-entity-alias-text": "Entity alias '{{entityAlias}}' can't be deleted as it used by the following widget(s):
{{widgetsList}}", + "duplicate-alias-error": "Duplicate alias found '{{alias}}'.
Entity aliases must be unique whithin the dashboard.", + "missing-entity-filter-error": "Filter is missing for alias '{{alias}}'.", + "configure-alias": "Configure '{{alias}}' alias", + "alias": "Alias", + "alias-required": "Entity alias is required.", + "remove-alias": "Remove entity alias", + "add-alias": "Add entity alias", + "entity-list": "Entity list", + "entity-type": "Entity type", + "entity-types": "Entity types", + "entity-type-list": "Entity type list", + "any-entity": "Any entity", + "enter-entity-type": "Enter entity type", + "no-entities-matching": "No entities matching '{{entity}}' were found.", + "no-entity-types-matching": "No entity types matching '{{entityType}}' were found.", + "name-starts-with": "Name starts with", + "use-entity-name-filter": "Use filter", + "entity-list-empty": "No entities selected.", + "entity-type-list-empty": "No entity types selected.", + "entity-name-filter-required": "Entity name filter is required.", + "entity-name-filter-no-entity-matched": "No entities starting with '{{entity}}' were found.", + "all-subtypes": "All", + "select-entities": "Select entities", + "no-aliases-found": "No aliases found.", + "no-alias-matching": "'{{alias}}' not found.", + "create-new-alias": "Create a new one!", + "key": "Key", + "key-name": "Key name", + "no-keys-found": "No keys found.", + "no-key-matching": "'{{key}}' not found.", + "create-new-key": "Create a new one!", + "type": "Type", + "type-required": "Entity type is required.", + "type-device": "Device", + "type-devices": "Devices", + "list-of-devices": "{ count, plural, 1 {One device} other {List of # devices} }", + "device-name-starts-with": "Devices whose names start with '{{prefix}}'", + "type-asset": "Asset", + "type-assets": "Assets", + "list-of-assets": "{ count, plural, 1 {One asset} other {List of # assets} }", + "asset-name-starts-with": "Assets whose names start with '{{prefix}}'", + "type-rule": "Rule", + "type-rules": "Rules", + "list-of-rules": "{ count, plural, 1 {One rule} other {List of # rules} }", + "rule-name-starts-with": "Rules whose names start with '{{prefix}}'", + "type-plugin": "Plugin", + "type-plugins": "Plugins", + "list-of-plugins": "{ count, plural, 1 {One plugin} other {List of # plugins} }", + "plugin-name-starts-with": "Plugins whose names start with '{{prefix}}'", + "type-tenant": "Tenant", + "type-tenants": "Tenants", + "list-of-tenants": "{ count, plural, 1 {One tenant} other {List of # tenants} }", + "tenant-name-starts-with": "Tenants whose names start with '{{prefix}}'", + "type-customer": "Customer", + "type-customers": "Customers", + "list-of-customers": "{ count, plural, 1 {One customer} other {List of # customers} }", + "customer-name-starts-with": "Customers whose names start with '{{prefix}}'", + "type-user": "User", + "type-users": "Users", + "list-of-users": "{ count, plural, 1 {One user} other {List of # users} }", + "user-name-starts-with": "Users whose names start with '{{prefix}}'", + "type-dashboard": "Dashboard", + "type-dashboards": "Dashboards", + "list-of-dashboards": "{ count, plural, 1 {One dashboard} other {List of # dashboards} }", + "dashboard-name-starts-with": "Dashboards whose names start with '{{prefix}}'", + "type-alarm": "Alarm", + "type-alarms": "Alarms", + "list-of-alarms": "{ count, plural, 1 {One alarms} other {List of # alarms} }", + "alarm-name-starts-with": "Alarms whose names start with '{{prefix}}'", + "type-rulechain": "Rule chain", + "type-rulechains": "Rule chains", + "list-of-rulechains": "{ count, plural, 1 {One rule chain} other {List of # rule chains} }", + "rulechain-name-starts-with": "Rule chains whose names start with '{{prefix}}'", + "type-current-customer": "Current Customer", + "search": "Search entities", + "selected-entities": "{ count, plural, 1 {1 entity} other {# entities} } selected", + "entity-name": "Entity name", + "details": "Entity details", + "no-entities-prompt": "No entities found", + "no-data": "No data to display" + }, + "event": { + "event-type": "Тип события", + "type-error": "Ошибка", + "type-lc-event": "Событие жизненного цикла", + "type-stats": "Статистика", + "type-debug-rule-node": "Debug", + "type-debug-rule-chain": "Debug", + "no-events-prompt": "События не найдены", + "error": "Ошибка", + "alarm": "Аварийное оповещение", + "event-time": "Время возникновения события", + "server": "Сервер", + "body": "Тело", + "method": "Метод", + "type": "Type", + "entity": "Entity", + "message-id": "Message Id", + "message-type": "Message Type", + "data-type": "Data Type", + "relation-type": "Relation Type", + "metadata": "Metadata", + "data": "Data", + "event": "Событие", + "status": "Статус", + "success": "Успех", + "failed": "Неудача", + "messages-processed": "Сообщения обработаны", + "errors-occurred": "Возникли ошибки" + }, + "extension": { + "extensions": "Extensions", + "selected-extensions": "{ count, plural, 1 {1 extension} other {# extensions} } selected", + "type": "Type", + "key": "Key", + "value": "Value", + "id": "Id", + "extension-id": "Extension id", + "extension-type": "Extension type", + "transformer-json": "JSON *", + "unique-id-required": "Current extension id already exists.", + "delete": "Delete extension", + "add": "Add extension", + "edit": "Edit extension", + "delete-extension-title": "Are you sure you want to delete the extension '{{extensionId}}'?", + "delete-extension-text": "Be careful, after the confirmation the extension and all related data will become unrecoverable.", + "delete-extensions-title": "Are you sure you want to delete { count, plural, 1 {1 extension} other {# extensions} }?", + "delete-extensions-text": "Be careful, after the confirmation all selected extensions will be removed.", + "converters": "Converters", + "converter-id": "Converter id", + "configuration": "Configuration", + "converter-configurations": "Converter configurations", + "token": "Security token", + "add-converter": "Add converter", + "add-config": "Add converter configuration", + "device-name-expression": "Device name expression", + "device-type-expression": "Device type expression", + "custom": "Custom", + "to-double": "To Double", + "transformer": "Transformer", + "json-required": "Transformer json is required.", + "json-parse": "Unable to parse transformer json.", + "attributes": "Attributes", + "add-attribute": "Add attribute", + "add-map": "Add mapping element", + "timeseries": "Timeseries", + "add-timeseries": "Add timeseries", + "field-required": "Field is required", + "brokers": "Brokers", + "add-broker": "Add broker", + "host": "Host", + "port": "Port", + "port-range": "Port should be in a range from 1 to 65535.", + "ssl": "Ssl", + "credentials": "Credentials", + "username": "Username", + "password": "Password", + "retry-interval": "Retry interval in milliseconds", + "anonymous": "Anonymous", + "basic": "Basic", + "pem": "PEM", + "ca-cert": "CA certificate file *", + "private-key": "Private key file *", + "cert": "Certificate file *", + "no-file": "No file selected.", + "drop-file": "Drop a file or click to select a file to upload.", + "mapping": "Mapping", + "topic-filter": "Topic filter", + "converter-type": "Converter type", + "converter-json": "Json", + "json-name-expression": "Device name json expression", + "topic-name-expression": "Device name topic expression", + "json-type-expression": "Device type json expression", + "topic-type-expression": "Device type topic expression", + "attribute-key-expression": "Attribute key expression", + "attr-json-key-expression": "Attribute key json expression", + "attr-topic-key-expression": "Attribute key topic expression", + "request-id-expression": "Request id expression", + "request-id-json-expression": "Request id json expression", + "request-id-topic-expression": "Request id topic expression", + "response-topic-expression": "Response topic expression", + "value-expression": "Value expression", + "topic": "Topic", + "timeout": "Timeout in milliseconds", + "converter-json-required": "Converter json is required.", + "converter-json-parse": "Unable to parse converter json.", + "filter-expression": "Filter expression", + "connect-requests": "Connect requests", + "add-connect-request": "Add connect request", + "disconnect-requests": "Disconnect requests", + "add-disconnect-request": "Add disconnect request", + "attribute-requests": "Attribute requests", + "add-attribute-request": "Add attribute request", + "attribute-updates": "Attribute updates", + "add-attribute-update": "Add attribute update", + "server-side-rpc": "Server side RPC", + "add-server-side-rpc-request": "Add server-side RPC request", + "device-name-filter": "Device name filter", + "attribute-filter": "Attribute filter", + "method-filter": "Method filter", + "request-topic-expression": "Request topic expression", + "response-timeout": "Response timeout in milliseconds", + "topic-expression": "Topic expression", + "client-scope": "Client scope", + "add-device": "Add device", + "opc-server": "Servers", + "opc-add-server": "Add server", + "opc-add-server-prompt": "Please add server", + "opc-application-name": "Application name", + "opc-application-uri": "Application uri", + "opc-scan-period-in-seconds": "Scan period in seconds", + "opc-security": "Security", + "opc-identity": "Identity", + "opc-keystore": "Keystore", + "opc-type": "Type", + "opc-keystore-type": "Type", + "opc-keystore-location": "Location *", + "opc-keystore-password": "Password", + "opc-keystore-alias": "Alias", + "opc-keystore-key-password": "Key password", + "opc-device-node-pattern": "Device node pattern", + "opc-device-name-pattern": "Device name pattern", + "modbus-server": "Servers/slaves", + "modbus-add-server": "Add server/slave", + "modbus-add-server-prompt": "Please add server/slave", + "modbus-transport": "Transport", + "modbus-port-name": "Serial port name", + "modbus-encoding": "Encoding", + "modbus-parity": "Parity", + "modbus-baudrate": "Baud rate", + "modbus-databits": "Data bits", + "modbus-stopbits": "Stop bits", + "modbus-databits-range": "Data bits should be in a range from 7 to 8.", + "modbus-stopbits-range": "Stop bits should be in a range from 1 to 2.", + "modbus-unit-id": "Unit ID", + "modbus-unit-id-range": "Unit ID should be in a range from 1 to 247.", + "modbus-device-name": "Device name", + "modbus-poll-period": "Poll period (ms)", + "modbus-attributes-poll-period": "Attributes poll period (ms)", + "modbus-timeseries-poll-period": "Timeseries poll period (ms)", + "modbus-poll-period-range": "Poll period should be positive value.", + "modbus-tag": "Tag", + "modbus-function": "Function", + "modbus-register-address": "Register address", + "modbus-register-address-range": "Register address should be in a range from 0 to 65535.", + "modbus-register-bit-index": "Bit index", + "modbus-register-bit-index-range": "Bit index should be in a range from 0 to 15.", + "modbus-register-count": "Register count", + "modbus-register-count-range": "Register count should be a positive value.", + "modbus-byte-order": "Byte order", + + "sync": { + "status": "Status", + "sync": "Sync", + "not-sync": "Not sync", + "last-sync-time": "Last sync time", + "not-available": "Not available" + }, + + "export-extensions-configuration": "Export extensions configuration", + "import-extensions-configuration": "Import extensions configuration", + "import-extensions": "Import extensions", + "import-extension": "Import extension", + "export-extension": "Export extension", + "file": "Extensions file", + "invalid-file-error": "Invalid extension file" + }, + "fullscreen": { + "expand": "Во весь экран", + "exit": "Выйти из полноэкранного режима", + "toggle": "Во весь экран", + "fullscreen": "Полноэкранный режим" + }, + "function": { + "function": "Функция" + }, + "grid": { + "delete-item-title": "Вы точно хотите удалить этот объект?", + "delete-item-text": "Внимание, после подтверждения объект и все связанные с ним данные будут безвозвратно утеряны.", + "delete-items-title": "Вы точно хотите удалить { count, plural, one {1 объект} few {# объекта} other {# объектов} }?", + "delete-items-action-title": "Удалить { count, plural, one {1 объект} few {# объекта} other {# объектов}", + "delete-items-text": "Внимание, после подтверждения выбранные объекты и все связанные с ними данные будут безвозвратно утеряны.", + "add-item-text": "Добавить новый объект", + "no-items-text": "Объекты не найдены", + "item-details": "Подробности об объекте", + "delete-item": "Удалить объект", + "delete-items": "Удалить объекты", + "scroll-to-top": "Прокрутка к началу" + }, + "help": { + "goto-help-page": "Перейти к справке" + }, + "home": { + "home": "Главная", + "profile": "Профиль", + "logout": "Выйти из системы", + "menu": "Меню", + "avatar": "Аватар", + "open-user-menu": "Открыть меню пользователя" + }, + "import": { + "no-file": "Файл не выбран", + "drop-file": "Перетащите JSON файл или кликните для выбора файла." + }, + "item": { + "selected": "Выбранные" + }, + "js-func": { + "no-return-error": "Функция должна возвращать значение!", + "return-type-mismatch": "Функция должна возвращать значение типа '{{type}}'!", + "tidy": "Tidy" + }, + "key-val": { + "key": "Key", + "value": "Value", + "remove-entry": "Remove entry", + "add-entry": "Add entry", + "no-data": "No entries" + }, + "layout": { + "layout": "Layout", + "manage": "Manage layouts", + "settings": "Layout settings", + "color": "Color", + "main": "Main", + "right": "Right", + "select": "Select target layout" + }, + "legend": { + "position": "Расположение легенды", + "show-max": "Показать максимальное значение", + "show-min": "Показать минимальное значение", + "show-avg": "Показать среднее значение", + "show-total": "Показать сумму", + "settings": "Настройки легенды", + "min": "Мин", + "max": "Макс", + "avg": "Среднее", + "total": "Сумма" + }, + "login": { + "login": "Войти", + "request-password-reset": "Запрос на сброс пароля", + "reset-password": "Сбросить пароль", + "create-password": "Создать пароль", + "passwords-mismatch-error": "Введенные пароли должны быть одинаковыми!", + "password-again": "Введите пароль еще раз", + "sign-in": "Пожалуйста, войдите в систему", + "username": "Имя пользователя (эл. адрес)", + "remember-me": "Запомнить меня", + "forgot-password": "Забыли пароль?", + "password-reset": "Пароль сброшен", + "new-password": "Новый пароль", + "new-password-again": "Повторите новый пароль", + "password-link-sent-message": "Ссылка для сброса пароля была успешно отправлена!", + "email": "Эл. адрес" + }, + "position": { + "top": "Верх", + "bottom": "Низ", + "left": "Левый край", + "right": "Правый край" + }, + "profile": { + "profile": "Профиль", + "change-password": "Изменить пароль", + "current-password": "Текущий пароль" + }, + "relation": { + "relations": "Relations", + "direction": "Direction", + "search-direction": { + "FROM": "From", + "TO": "To" + }, + "direction-type": { + "FROM": "from", + "TO": "to" + }, + "from-relations": "Outbound relations", + "to-relations": "Inbound relations", + "selected-relations": "{ count, plural, 1 {1 relation} other {# relations} } selected", + "type": "Type", + "to-entity-type": "To entity type", + "to-entity-name": "To entity name", + "from-entity-type": "From entity type", + "from-entity-name": "From entity name", + "to-entity": "To entity", + "from-entity": "From entity", + "delete": "Delete relation", + "relation-type": "Relation type", + "relation-type-required": "Relation type is required.", + "any-relation-type": "Any type", + "add": "Add relation", + "edit": "Edit relation", + "delete-to-relation-title": "Are you sure you want to delete relation to the entity '{{entityName}}'?", + "delete-to-relation-text": "Be careful, after the confirmation the entity '{{entityName}}' will be unrelated from the current entity.", + "delete-to-relations-title": "Are you sure you want to delete { count, plural, 1 {1 relation} other {# relations} }?", + "delete-to-relations-text": "Be careful, after the confirmation all selected relations will be removed and corresponding entities will be unrelated from the current entity.", + "delete-from-relation-title": "Are you sure you want to delete relation from the entity '{{entityName}}'?", + "delete-from-relation-text": "Be careful, after the confirmation current entity will be unrelated from the entity '{{entityName}}'.", + "delete-from-relations-title": "Are you sure you want to delete { count, plural, 1 {1 relation} other {# relations} }?", + "delete-from-relations-text": "Be careful, after the confirmation all selected relations will be removed and current entity will be unrelated from the corresponding entities.", + "remove-relation-filter": "Remove relation filter", + "add-relation-filter": "Add relation filter", + "any-relation": "Any relation", + "relation-filters": "Relation filters", + "additional-info": "Additional info (JSON)", + "invalid-additional-info": "Unable to parse additional info json." + }, + "rulechain": { + "rulechain": "Rule chain", + "rulechains": "Rule chains", + "root": "Root", + "delete": "Delete rule chain", + "name": "Name", + "name-required": "Name is required.", + "description": "Description", + "add": "Add Rule Chain", + "set-root": "Make rule chain root", + "set-root-rulechain-title": "Are you sure you want to make the rule chain '{{ruleChainName}}' root?", + "set-root-rulechain-text": "After the confirmation the rule chain will become root and will handle all incoming transport messages.", + "delete-rulechain-title": "Are you sure you want to delete the rule chain '{{ruleChainName}}'?", + "delete-rulechain-text": "Be careful, after the confirmation the rule chain and all related data will become unrecoverable.", + "delete-rulechains-title": "Are you sure you want to delete { count, plural, 1 {1 rule chain} other {# rule chains} }?", + "delete-rulechains-action-title": "Delete { count, plural, 1 {1 rule chain} other {# rule chains} }", + "delete-rulechains-text": "Be careful, after the confirmation all selected rule chains will be removed and all related data will become unrecoverable.", + "add-rulechain-text": "Add new rule chain", + "no-rulechains-text": "No rule chains found", + "rulechain-details": "Rule chain details", + "details": "Details", + "events": "Events", + "system": "System", + "import": "Import rule chain", + "export": "Export rule chain", + "export-failed-error": "Unable to export rule chain: {{error}}", + "create-new-rulechain": "Create new rule chain", + "rulechain-file": "Rule chain file", + "invalid-rulechain-file-error": "Unable to import rule chain: Invalid rule chain data structure.", + "copyId": "Copy rule chain Id", + "idCopiedMessage": "Rule chain Id has been copied to clipboard", + "select-rulechain": "Select rule chain", + "no-rulechains-matching": "No rule chains matching '{{entity}}' were found.", + "rulechain-required": "Rule chain is required", + "management": "Rules management", + "debug-mode": "Debug mode" + }, + "rulenode": { + "details": "Details", + "events": "Events", + "search": "Search nodes", + "open-node-library": "Open node library", + "add": "Add rule node", + "name": "Name", + "name-required": "Name is required.", + "type": "Type", + "description": "Description", + "delete": "Delete rule node", + "select-all-objects": "Select all nodes and connections", + "deselect-all-objects": "Deselect all nodes and connections", + "delete-selected-objects": "Delete selected nodes and connections", + "delete-selected": "Delete selected", + "select-all": "Select all", + "copy-selected": "Copy selected", + "deselect-all": "Deselect all", + "rulenode-details": "Rule node details", + "debug-mode": "Debug mode", + "configuration": "Configuration", + "link": "Link", + "link-details": "Rule node link details", + "add-link": "Add link", + "link-label": "Link label", + "link-label-required": "Link label is required.", + "custom-link-label": "Custom link label", + "custom-link-label-required": "Custom link label is required.", + "type-filter": "Filter", + "type-filter-details": "Filter incoming messages with configured conditions", + "type-enrichment": "Enrichment", + "type-enrichment-details": "Add additional information into Message Metadata", + "type-transformation": "Transformation", + "type-transformation-details": "Change Message payload and Metadata", + "type-action": "Action", + "type-action-details": "Perform special action", + "type-external": "External", + "type-external-details": "Interacts with external system", + "type-rule-chain": "Rule Chain", + "type-rule-chain-details": "Forwards incoming messages to specified Rule Chain", + "type-input": "Input", + "type-input-details": "Logical input of Rule Chain, forwards incoming messages to next related Rule Node", + "directive-is-not-loaded": "Defined configuration directive '{{directiveName}}' is not available.", + "ui-resources-load-error": "Failed to load configuration ui resources.", + "invalid-target-rulechain": "Unable to resolve target rule chain!", + "test-script-function": "Test script function", + "message": "Message", + "message-type": "Message type", + "message-type-required": "Message type is required", + "metadata": "Metadata", + "metadata-required": "Metadata entries can't be empty.", + "output": "Output", + "test": "Test", + "help": "Help" + }, + "tenant": { + "tenants": "Владельцы", + "management": "Управление владельцами", + "add": "Добавить владельца", + "admins": "Администраторы", + "manage-tenant-admins": "Управление администраторами владельца", + "delete": "Удалить владельца", + "add-tenant-text": "Добавить нового владельца", + "no-tenants-text": "Владельцы не найдены", + "tenant-details": "Подробности об владельце", + "delete-tenant-title": "Вы точно хотите удалить владельца '{{tenantTitle}}'?", + "delete-tenant-text": "Внимание, после подтверждения владелец и все связанные с ним данные будут безвозвратно утеряны.", + "delete-tenants-title": "Вы точно хотите удалить { count, plural, one {1 владельца} other {# владельцев} }?", + "delete-tenants-action-title": "Удалить { count, plural, one {1 владельца} other {# владельцев} }", + "delete-tenants-text": "Внимание, после подтверждения выбранные Владельцы и все связанные с ними данные будут безвозвратно утеряны.", + "title": "Имя", + "title-required": "Имя обязательно.", + "description": "Описание" + }, + "timeinterval": { + "seconds-interval": "{ seconds, plural, one {1 секунда} few {# секунды} other {# секунд} }", + "minutes-interval": "{ minutes, plural, one {1 минута} few {# минуты} other {# минут} }", + "hours-interval": "{ hours, plural, one {1 час} few {# часа} other {# часов} }", + "days-interval": "{ days, plural, one {1 день} few {# дня} other {# дней} }", + "days": "Дни", + "hours": "Часы", + "minutes": "Минуты", + "seconds": "Секунды", + "advanced": "Дополнительно" + }, + "timewindow": { + "days": "{ days, plural, one {1 день} few {# дня} other {# дней} }", + "hours": "{ hours, plural, one {1 час} few {# часа} other {# часов} }", + "minutes": "{ minutes, plural, one {1 минута} few {# минуты} other {# минут} }", + "seconds": "{ seconds, plural, one {1 секунда} few {# секунды} other {# секунд} }", + "realtime": "Режим реального времени", + "history": "История", + "last-prefix": "Последние", + "period": "с {{ startTime }} до {{ endTime }}", + "edit": "Изменить временное окно", + "date-range": "Диапазон дат", + "last": "Последние", + "time-period": "Период времени" + }, + "user": { + "users": "Пользователи", + "customer-users": "Пользователи клиента", + "tenant-admins": "Администраторы владельца", + "sys-admin": "Системный администратор", + "tenant-admin": "Администратор владельца", + "customer": "Клиент", + "anonymous": "Аноним", + "add": "Добавить пользователя", + "delete": "Удалить пользователя", + "add-user-text": "Добавить нового пользователя", + "no-users-text": "Пользователи не найдены", + "user-details": "Подробности о пользователе", + "delete-user-title": "Вы точно хотите удалить пользователя '{{userEmail}}'?", + "delete-user-text": "Внимание, после подтверждения пользователь и все связанные с ним данные будут безвозвратно утеряны.", + "delete-users-title": "Вы точно хотите удалить { count, plural, one {1 пользователя} other {# пользователей} }?", + "delete-users-action-title": "Удалить { count, plural, one {1 пользователя} other {# пользователей} }", + "delete-users-text": "Внимание, после подтверждения выбранные пользователи и все связанные с ними данные будут безвозвратно утеряны.", + "activation-email-sent-message": "Активационное письмо успешно отправлено!", + "resend-activation": "Повторить отправку активационного письма", + "email": "Эл. адрес", + "email-required": "Эл. адрес обязателен.", + "first-name": "Имя", + "last-name": "Фамилия", + "description": "Описание", + "default-dashboard": "Дашборд по умолчанию", + "always-fullscreen": "Всегда во весь экран" + }, + "value": { + "type": "Тип значения", + "string": "Строка", + "string-value": "Строковое значение", + "integer": "Целое число", + "integer-value": "Целочисленное значение", + "invalid-integer-value": "Неправильный формат целого числа", + "double": "Число двойной точности", + "double-value": "Значение двойной точности", + "boolean": "Логический тип", + "boolean-value": "Логическое значение", + "false": "Ложь", + "true": "Правда" + }, + "widget": { + "widget-library": "Галерея виджетов", + "widget-bundle": "Набор виджетов", + "select-widgets-bundle": "Выберите набор виджетов", + "management": "Управление виджетами", + "editor": "Редактор виджетов", + "widget-type-not-found": "Ошибка при загрузке конфигурации виджета.
Возможно, связанный с ней\n тип виджета уже удален.", + "widget-type-load-error": "Не удалось загрузить виджет по следующим причинам:", + "remove": "Удалить виджет", + "edit": "Редактировать виджет", + "remove-widget-title": "Вы точно хотите удалить виджет '{{widgetTitle}}'?", + "remove-widget-text": "Внимание, после подтверждения виджет и все связанные с ним данные будут безвозвратно утеряны.", + "timeseries": "Выборка по времени", + "latest-values": "Последние значения", + "rpc": "Управляющий виджет", + "static": "Статический виджет", + "select-widget-type": "Выберите тип виджета", + "missing-widget-title-error": "Укажите название виджета!", + "widget-saved": "Виджет сохранен", + "unable-to-save-widget-error": "Не удалось сохранить виджет! Виджет содержит ошибки!", + "save": "Сохранить виджет", + "saveAs": "Сохранить виджет как", + "save-widget-type-as": "Сохранить тип виджета как", + "save-widget-type-as-text": "Пожалуйста, введите название виджета и/или укажите целевой набор виджетов", + "toggle-fullscreen": "Во весь экран", + "run": "Запустить виджет", + "title": "Название виджета", + "title-required": "Название виджета обязательно.", + "type": "Тип виджета", + "resources": "Ресурсы", + "resource-url": "JavaScript/CSS URL", + "remove-resource": "Удалить ресурс", + "add-resource": "Добавить ресурс", + "html": "HTML", + "tidy": "Форматировать", + "css": "CSS", + "settings-schema": "Схема конфигурации", + "datakey-settings-schema": "Схема конфигурации ключа данных", + "javascript": "Javascript", + "remove-widget-type-title": "Вы точно хотите удалить виджет '{{widgetName}}'?", + "remove-widget-type-text": "Внимание, после подтверждения тип виджета и все связанные с ним данные будут безвозвратно утеряны.", + "remove-widget-type": "Удалить тип виджета", + "add-widget-type": "Добавить новый тип виджета", + "widget-type-load-failed-error": "Не удалось загрузить тип виджета!", + "widget-template-load-failed-error": "Не удалось загрузить шаблон виджета!", + "add": "Добавить виджет", + "undo": "Откатить изменения в виджете", + "export": "Экспортировать виджет" + }, + "widget-action": { + "header-button": "Widget header button", + "open-dashboard-state": "Navigate to new dashboard state", + "update-dashboard-state": "Update current dashboard state", + "open-dashboard": "Navigate to other dashboard", + "custom": "Custom action", + "target-dashboard-state": "Target dashboard state", + "target-dashboard-state-required": "Target dashboard state is required", + "set-entity-from-widget": "Set entity from widget", + "target-dashboard": "Target dashboard", + "open-right-layout": "Open right dashboard layout (mobile view)" + }, + "widgets-bundle": { + "current": "Текущий набор", + "widgets-bundles": "Наборы виджетов", + "add": "Добавить набор виджетов", + "delete": "Удалить набор виджетов", + "title": "Название", + "title-required": "Название обязательно.", + "add-widgets-bundle-text": "Добавить новый набор виджетов", + "no-widgets-bundles-text": "Наборы виджетов не найдены", + "empty": "Пустой набор виджетов", + "details": "Подробности", + "widgets-bundle-details": "Подробности о наборе виджетов", + "delete-widgets-bundle-title": "Вы точно хотите удалить набор виджетов '{{widgetsBundleTitle}}'?", + "delete-widgets-bundle-text": "Внимание, после подтверждения набор виджетов и все связанные с ним данные будут безвозвратно утеряны.", + "delete-widgets-bundles-title": "Вы точно хотите удалить { count, plural, one {1 набор виджетов} few {# набора виджетов} other {# наборов виджетов} }?", + "delete-widgets-bundles-action-title": "Удалить { count, plural, one {1 набор виджетов} few {# набора виджетов} other {# наборов виджетов} }", + "delete-widgets-bundles-text": "Внимание, после подтверждения выбранные наборы виджетов и все связанные с ними данные будут безвозвратно утеряны..", + "no-widgets-bundles-matching": "Набор виджетов '{{widgetsBundle}}' не найден.", + "widgets-bundle-required": "Набор виджетов обязателен.", + "system": "Системный", + "import": "Импортировать набор виджетов", + "export": "Экспортировать набор виджетов", + "export-failed-error": "Не удалось экспортировать набор виджетов: {{error}}", + "create-new-widgets-bundle": "Создать новый набор виджетов", + "widgets-bundle-file": "Файл набора виджетов", + "invalid-widgets-bundle-file-error": "Не удалось импортировать набор виджетов: неизвестная схема данных набора виджетов." + }, + "widget-config": { + "data": "Данные", + "settings": "Настройки", + "advanced": "Дополнительно", + "title": "Название", + "general-settings": "Общие настройки", + "display-title": "Показать название", + "drop-shadow": "Тень", + "enable-fullscreen": "Во весь экран", + "background-color": "Цвет фона", + "text-color": "Цвет текста", + "padding": "Отступ", + "title-style": "Стиль названия", + "mobile-mode-settings": "Настройки мобильного режима", + "order": "Порядок", + "height": "Высота", + "units": "Специальный символ после значения", + "decimals": "Количество цифр после запятой", + "timewindow": "Временное окно", + "use-dashboard-timewindow": "Использовать временное окно дашборда", + "display-legend": "Показать легенду", + "datasources": "Источники данных", + "datasource-type": "Тип", + "datasource-parameters": "Параметры", + "remove-datasource": "Удалить источник данных", + "add-datasource": "Добавить источник данных", + "target-device": "Целевое устройство" + }, + "widget-type": { + "import": "Импортировать тип виджета", + "export": "Экспортировать тип виджета", + "export-failed-error": "Не удалось экспортировать тип виджета: {{error}}", + "create-new-widget-type": "Создать новый тип виджета", + "widget-type-file": "Файл типа виджета", + "invalid-widget-type-file-error": "Не удалось импортировать виджет: неизвестная схема данных типа виджета." + }, + "icon": { + "icon": "Icon", + "select-icon": "Select icon", + "material-icons": "Material icons", + "show-all": "Show all icons" + }, + "custom": { + "widget-action": { + "action-cell-button": "Action cell button", + "row-click": "On row click", + "marker-click": "On marker click", + "tooltip-tag-action": "Tooltip tag action" + } + }, + "language": { + "language": "Язык", + "locales": { + "en_US": "Английский", + "zh_CN": "Китайский", + "ko_KR": "Корейский", + "es_ES": "Испанский", + "it_IT": "Итальянский", + "ru_RU": "Русский" + } + + } +} \ No newline at end of file diff --git a/ui/src/app/locale/locale.constant-zh.js b/ui/src/app/locale/locale.constant-zh.js deleted file mode 100644 index 9a08ca146c..0000000000 --- a/ui/src/app/locale/locale.constant-zh.js +++ /dev/null @@ -1,1431 +0,0 @@ -/* - * Copyright © 2016-2018 The Thingsboard Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -export default function addLocaleChinese(locales) { - var zh_CN = { - "access": { - "unauthorized": "未授权", - "unauthorized-access": "未授权访问", - "unauthorized-access-text": "您需要登陆才能访问这个资源!", - "access-forbidden": "禁止访问", - "access-forbidden-text": "您没有访问此位置的权限
如果您仍希望访问此位置,请尝试使用其他用户登录。", - "refresh-token-expired": "会话已过期", - "refresh-token-failed": "无法刷新会话" - }, - "action": { - "activate": "激活", - "suspend": "暂停", - "save": "保存", - "saveAs": "另存为", - "cancel": "取消", - "ok": "确定", - "delete": "删除", - "add": "添加", - "yes": "是", - "no": "否", - "update": "更新", - "remove": "移除", - "search": "查询", - "assign": "分配", - "unassign": "取消分配", - "share": "分享", - "make-private": "私有", - "apply": "应用", - "apply-changes": "应用更改", - "edit-mode": "编辑模式", - "enter-edit-mode": "进入编辑模式", - "decline-changes": "撤销更改", - "close": "关闭", - "back": "后退", - "run": "运行", - "sign-in": "登录!", - "edit": "编辑", - "view": "查看", - "create": "创建", - "drag": "拖拽", - "refresh": "刷新", - "undo": "撤销", - "copy": "复制", - "paste": "粘贴", - "copy-reference": "复制引用", - "paste-reference": "粘贴引用", - "import": "导入", - "export": "导出", - "share-via": "通过 {{provider}}分享" - }, - "aggregation": { - "aggregation": "聚合", - "function": "数据聚合功能", - "limit": "最大值", - "group-interval": "分组间隔", - "min": "最少值", - "max": "最大值", - "avg": "平均值", - "sum": "求和", - "count": "计数", - "none": "空" - }, - "admin": { - "general": "常规", - "general-settings": "常规设置", - "outgoing-mail": "发送邮件", - "outgoing-mail-settings": "发送邮件设置", - "system-settings": "系统设置", - "test-mail-sent": "测试邮件发送成功!", - "base-url": "基本URL", - "base-url-required": "基本URL必填。", - "mail-from": "邮件来自", - "mail-from-required": "邮件发件人必填。", - "smtp-protocol": "SMTP协议", - "smtp-host": "SMTP主机", - "smtp-host-required": "SMTP主机必填。", - "smtp-port": "SMTP端口", - "smtp-port-required": "您必须提供一个smtp端口。", - "smtp-port-invalid": "这看起来不是有效的smtp端口。", - "timeout-msec": "超时(ms)", - "timeout-required": "超时必填。", - "timeout-invalid": "这看起来不像有效的超时值。", - "enable-tls": "启用TLS", - "send-test-mail": "发送测试邮件" - }, - "alarm": { - "alarm": "警告", - "alarms": "警告", - "select-alarm": "选择警告", - "no-alarms-matching": "没有找到匹配 '{{entity}}' 的警告", - "alarm-required": "警告必填", - "alarm-status": "警告状态", - "search-status": { - "ANY": "所有", - "ACTIVE": "已激活", - "CLEARED": "已清除", - "ACK": "已应答", - "UNACK": "未应答" - }, - "display-status": { - "ACTIVE_UNACK": "激活未应答", - "ACTIVE_ACK": "激活已应答", - "CLEARED_UNACK": "清除未应答", - "CLEARED_ACK": "清除已应答" - }, - "no-alarms-prompt": "未发现警告", - "created-time": "创建时间", - "type": "类型", - "severity": "严重程度", - "originator": "起因", - "originator-type": "起因类型", - "details": "详情", - "status": "状态", - "alarm-details": "警告详情", - "start-time": "开始时间", - "end-time": "结束时间", - "ack-time": "应答时间", - "clear-time": "创建时间", - "severity-critical": "危险", - "severity-major": "重要", - "severity-minor": "次要", - "severity-warning": "警告", - "severity-indeterminate": "不确定", - "acknowledge": "应答", - "clear": "清除", - "search": "搜索警告", - "selected-alarms": "已选择 { count, select, 1 {1 警告} other {# 警告} } ", - "no-data": "无数据显示", - "polling-interval": "警告轮询间隔(秒)", - "polling-interval-required": "警告轮询间隔必填。", - "min-polling-interval-message": "轮询间隔至少是1秒。", - "aknowledge-alarms-title": "应答 { count, select, 1 {1 警告} other {# 警告} }", - "aknowledge-alarms-text": "确定要应答 { count, select, 1 {1 警告} other {# 警告} }?", - "clear-alarms-title": "清除 { count, select, 1 {1 警告} other {# 警告} }", - "clear-alarms-text": "确定要清除 { count, select, 1 {1 警告} other {# 警告} }?" - }, - "alias": { - "add": "添加别名", - "edit": "编辑别名", - "name": "别名", - "name-required": "别名必填", - "duplicate-alias": "别名已经存在。", - "filter-type-single-entity": "单个实体", - "filter-type-entity-list": "实体列表", - "filter-type-entity-name": "实体名称", - "filter-type-state-entity": "实体(仪表板状态)", - "filter-type-state-entity-description": "实体令牌(仪表板状态参数)", - "filter-type-asset-type": "资产类型", - "filter-type-asset-type-description": "类型为 '{{assetType}}' 的资产", - "filter-type-asset-type-and-name-description": "类型为 '{{assetType}}' 且以 '{{prefix}}' 开头的资产", - "filter-type-device-type": "设备类型", - "filter-type-device-type-description": "类型为 '{{deviceType}}' 的设备", - "filter-type-device-type-and-name-description": "类型为 '{{deviceType}}' 且以 '{{prefix}}' 开头的设备", - "filter-type-relations-query": "关系查询", - "filter-type-relations-query-description": "具有 {{relationType}} 关联 {{direction}} {{rootEntity}} 的 {{entities}} ", - "filter-type-asset-search-query": "资产搜索查询", - "filter-type-asset-search-query-description": "类型为 {{assetTypes}} 且具有 {{relationType}} 关联 {{direction}} {{rootEntity}} 的资产", - "filter-type-device-search-query": "设备搜索查询", - "filter-type-device-search-query-description": "类型为 {{deviceTypes}} 且具有 {{relationType}} 关联 {{direction}} {{rootEntity}} 的设备", - "entity-filter": "实体过滤", - "resolve-multiple": "解决为多实体", - "filter-type": "过滤类型", - "filter-type-required": "过滤类型必填。", - "entity-filter-no-entity-matched": "未找到符合指定过滤条件的实体。", - "no-entity-filter-specified": "没有指定实体过滤条件", - "root-state-entity": "使用仪表板状态实体作为根实体", - "root-entity": "根实体", - "state-entity-parameter-name": "状态实体参数名称", - "default-state-entity": "默认状态实体", - "default-entity-parameter-name": "默认", - "max-relation-level": "最大关系层级", - "unlimited-level": "不限层级", - "state-entity": "仪表板状态实体", - "all-entities": "所有实体", - "any-relation": "不限" - }, - "asset": { - "asset": "资产", - "assets": "资产", - "management": "资产管理", - "view-assets": "查看资产", - "add": "添加资产", - "assign-to-customer": "分配给客户", - "assign-asset-to-customer": "将资产分配给客户", - "assign-asset-to-customer-text": "请选择要分配给客户的资产", - "no-assets-text": "未找到资产", - "assign-to-customer-text": "请选择客户以分配资产", - "public": "公开", - "assignedToCustomer": "分配客户", - "make-public": "资产设为公开", - "make-private": "资产设为私有", - "unassign-from-customer": "取消分配客户", - "delete": "删除资产", - "asset-public": "资产公开", - "asset-type": "资产类型", - "asset-type-required": "资产类型必填。", - "select-asset-type": "选择资产类型", - "enter-asset-type": "输入资产类型", - "any-asset": "Any asset", - "no-asset-types-matching": "没有找到匹配 '{{entitySubtype}}' 的资产类型。", - "asset-type-list-empty": "资产类型未选择。", - "asset-types": "资产类型", - "name": "名称", - "name-required": "名称必填。", - "description": "描述", - "type": "类型", - "type-required": "类型必填。", - "details": "详情", - "events": "事件", - "add-asset-text": "添加新资产", - "asset-details": "资产详情", - "assign-assets": "分配资产", - "assign-assets-text": "分配 { count, select, 1 {1 资产} other {# 资产} } 给客户", - "delete-assets": "删除资产", - "unassign-assets": "取消分配资产", - "unassign-assets-action-title": "从客户处取消分配 { count, select, 1 {1 资产} other {# 资产} } ", - "assign-new-asset": "分配新资产", - "delete-asset-title": "确定要删除资产 '{{assetName}}'?", - "delete-asset-text": "小心!确认后资产及其所有相关数据将不可恢复。", - "delete-assets-title": "确定要删除 { count, select, 1 {1 资产} other {# 资产} }?", - "delete-assets-action-title": "删除 { count, select, 1 {1 资产} other {# 资产} }", - "delete-assets-text": "小心!确认后,所有选定的客户将被删除,所有相关数据将不可恢复。", - "make-public-asset-title": "确定要将资产 '{{assetName}}' 设为公开?", - "make-public-asset-text": "确认后资产及所有相关数据会被设为公开并对其他人所见。", - "make-private-asset-title": "确定要将资产 '{{assetName}}' 设为私有?", - "make-private-asset-text": "确认后资产及所有相关数据会被设为私有并对其他人不可见。", - "unassign-asset-title": "确定要取消分配资产 '{{assetName}}'?", - "unassign-asset-text": "确定后资产将被取消分配并对客户不可见。", - "unassign-asset": "取消分配资产", - "unassign-assets-title": "确定要取消分配 { count, select, 1 {1 资产} other {# 资产} }?", - "unassign-assets-text": "确定后资产将被取消分配并对客户不可见。", - "copyId": "复制资产ID", - "idCopiedMessage": "资产ID已经复制到粘贴板", - "select-asset": "选择资产", - "no-assets-matching": "没有找到匹配 '{{entity}}' 的资产。", - "asset-required": "资产必填", - "name-starts-with": "资产名称以此开头" - }, - "attribute": { - "attributes": "属性", - "latest-telemetry": "最新遥测", - "attributes-scope": "设备属性范围", - "scope-latest-telemetry": "最新遥测", - "scope-client": "客户端属性", - "scope-server": "服务端属性", - "scope-shared": "共享属性", - "add": "添加属性", - "key": "键", - "last-update-time": "最后更新时间", - "key-required": "属性键必填。", - "value": "值", - "value-required": "属性值必填。", - "delete-attributes-title": "您确定要删除 { count, select, 1 {1 属性} other {# 属性} }吗?", - "delete-attributes-text": "注意,确认后所有选中的属性都会被删除。", - "delete-attributes": "删除属性", - "enter-attribute-value": "输入属性值", - "show-on-widget": "在部件上显示", - "widget-mode": "部件模式", - "next-widget": "下一个部件", - "prev-widget": "上一个部件", - "add-to-dashboard": "添加到仪表板", - "add-widget-to-dashboard": "将部件添加到仪表板", - "selected-attributes": "{ count, select, 1 {1 属性} other {# 属性} } 被选中", - "selected-telemetry": "{ count, select, 1 {1 遥测} other {# 遥测} } 被选中" - }, - "audit-log": { - "audit": "审计", - "audit-logs": "审计日志", - "timestamp": "时间戳", - "entity-type": "实体类型", - "entity-name": "实体名称", - "user": "用户", - "type": "类型", - "status": "状态", - "details": "详情", - "type-added": "添加", - "type-deleted": "删除", - "type-updated": "更新", - "type-attributes-updated": "更新属性", - "type-attributes-deleted": "删除属性", - "type-rpc-call": "RPC调用", - "type-credentials-updated": "更新凭证", - "type-assigned-to-customer": "分配给客户", - "type-unassigned-from-customer": "未分配给客户", - "type-activated": "激活", - "type-suspended": "暂停", - "type-credentials-read": "读取凭证", - "type-attributes-read": "读取属性", - "status-success": "成功", - "status-failure": "失败", - "audit-log-details": "审计日志详情", - "no-audit-logs-prompt": "找不到日志", - "action-data": "活动数据", - "failure-details": "失败详情", - "search": "查找审计日志", - "clear-search": "清空查找" - }, - "confirm-on-exit": { - "message": "您有未保存的更改。确定要离开此页吗?", - "html-message": "您有未保存的更改。
确定要离开此页面吗?", - "title": "未保存的更改" - }, - "contact": { - "country": "国家", - "city": "城市", - "state": "州", - "postal-code": "邮政编码", - "postal-code-invalid": "只允许数字。", - "address": "地址", - "address2": "地址2", - "phone": "手机", - "email": "邮箱", - "no-address": "无地址" - }, - "common": { - "username": "用户名", - "password": "密码", - "enter-username": "输入用户名", - "enter-password": "输入密码", - "enter-search": "输入检索条件" - }, - "content-type": { // TODO - "json": "Json", - "text": "Text", - "binary": "Binary (Base64)" - }, - "customer": { - "customer": "客户", - "customers": "客户", - "management": "客户管理", - "dashboard": "客户仪表板", - "dashboards": "客户仪表板", - "devices": "客户设备", - "assets": "客户资产", - "public-dashboards": "公共仪表板", - "public-devices": "公共设备", - "public-assets": "公共资产", - "add": "添加客户", - "delete": "删除客户", - "manage-customer-users": "管理客户用户", - "manage-customer-devices": "管理客户设备", - "manage-customer-dashboards": "管理客户仪表板", - "manage-public-devices": "管理公共设备", - "manage-public-dashboards": "管理公共仪表板", - "manage-customer-assets": "管理客户资产", - "manage-public-assets": "管理公共资产", - "add-customer-text": "添加新客户", - "no-customers-text": "没有找到客户", - "customer-details": "客户详情", - "delete-customer-title": "您确定要删除客户'{{customerTitle}}'吗?", - "delete-customer-text": "小心!确认后,客户及其所有相关数据将不可恢复。", - "delete-customers-title": "您确定要删除 { count, select, 1 {1 客户} other {# 客户} }吗?", - "delete-customers-action-title": "删除 { count, select, 1 {1 客户} other {# 客户} }", - "delete-customers-text": "小心!确认后,所有选定的客户将被删除,所有相关数据将不可恢复。", - "manage-users": "管理用户", - "manage-assets": "管理资产", - "manage-devices": "管理设备", - "manage-dashboards": "管理仪表板", - "title": "标题", - "title-required": "需要标题", - "description": "描述", - "details": "详情", - "events": "事件", - "copyId": "复制客户ID", - "idCopiedMessage": "客户ID已复制到粘贴板", - "select-customer": "选择客户", - "no-customers-matching": "没有找到匹配 '{{entity}}' 的客户。", - "customer-required": "客户是必选项" - }, - "datetime": { - "date-from": "日期从", - "time-from": "时间从", - "date-to": "日期到", - "time-to": "时间到" - }, - "dashboard": { - "dashboard": "仪表板", - "dashboards": "仪表板库", - "management": "仪表板管理", - "view-dashboards": "查看仪表板", - "add": "添加仪表板", - "assign-dashboard-to-customer": "将仪表板分配给客户", - "assign-dashboard-to-customer-text": "请选择要分配给客户的仪表板", - "assign-to-customer-text": "请选择客户分配仪表板", - "assign-to-customer": "分配给客户", - "unassign-from-customer": "取消分配客户", - "make-public": "仪表板设为公开", - "make-private": "仪表板设为私有", - "no-dashboards-text": "没有找到仪表板", - "no-widgets": "没有配置部件", - "add-widget": "添加新的部件", - "title": "标题", - "select-widget-title": "选择部件", - "select-widget-subtitle": "可用的部件类型列表", - "delete": "删除仪表板", - "title-required": "需要标题。", - "description": "描述", - "details": "详情", - "dashboard-details": "仪表板详情", - "add-dashboard-text": "添加新的仪表板", - "assign-dashboards": "分配仪表板", - "assign-new-dashboard": "分配新的仪表板", - "assign-dashboards-text": "分配 { count, select, 1 {1 仪表板} other {# 仪表板} } 给客户", - "delete-dashboards": "删除仪表板", - "unassign-dashboards": "取消分配仪表板", - "unassign-dashboards-action-title": "从客户处取消分配 { count, select, 1 {1 仪表板} other {# 仪表板} } ", - "delete-dashboard-title": "您确定要删除仪表板 '{{dashboardTitle}}'吗?", - "delete-dashboard-text": "小心!确认后仪表板及其所有相关数据将不可恢复。", - "delete-dashboards-title": "你确定你要删除 { count, select, 1 {1 仪表板} other {# 仪表板} }吗?", - "delete-dashboards-action-title": "删除 { count, select, 1 {1 仪表板} other {# 仪表板} }", - "delete-dashboards-text": "小心!确认后所有选定的仪表板将被删除,所有相关数据将不可恢复。", - "unassign-dashboard-title": "您确定要取消分配仪表板 '{{dashboardTitle}}'吗?", - "unassign-dashboard-text": "确认后,面板将被取消分配,客户将无法访问。", - "unassign-dashboard": "取消分配仪表板", - "unassign-dashboards-title": "您确定要取消分配仪表板 { count, select, 1 {1 仪表板} other {# 仪表板} } 吗?", - "unassign-dashboards-text": "确认后,所有选定的仪表板将被取消分配,客户将无法访问。", - "public-dashboard-title": "仪表板现已公布", - "public-dashboard-text": "你的仪表板 {{dashboardTitle}} 已被公开,可通过如下 链接访问:", - "public-dashboard-notice": "提示: 不要忘记将相关设备公开以访问其数据。", - "make-private-dashboard-title": "您确定要将仪表板 '{{dashboardTitle}}' 设为私有吗?", - "make-private-dashboard-text": "确认后,仪表板将被设为私有,不能被其他人访问。", - "make-private-dashboard": "仪表板设为私有", - "socialshare-text": "'{{dashboardTitle}}' 由Thingsboard提供支持", - "socialshare-title": "'{{dashboardTitle}}' 由Thingsboard提供支持", - "select-dashboard": "选择仪表板", - "no-dashboards-matching": "找不到符合 '{{entity}}' 的仪表板。", - "dashboard-required": "仪表板必填。", - "select-existing": "选择现有仪表板", - "create-new": "创建新的仪表板", - "new-dashboard-title": "新仪表板标题", - "open-dashboard": "打开仪表板", - "set-background": "设置背景", - "background-color": "背景颜色", - "background-image": "背景图片", - "background-size-mode": "背景大小模式", - "no-image": "无图像选择", - "drop-image": "拖拽图像或单击以选择要上传的文件。", - "settings": "设置", - "columns-count": "列数", - "columns-count-required": "需要列数。", - "min-columns-count-message": "只允许最少10列", - "max-columns-count-message": "只允许最多1000列", - "widgets-margins": "部件间边距", - "horizontal-margin": "水平边距", - "horizontal-margin-required": "需要水平边距值。", - "min-horizontal-margin-message": "只允许0作为最小水平边距值。", - "max-horizontal-margin-message": "只允许50作为最大水平边距值。", - "vertical-margin": "垂直边距", - "vertical-margin-required": "需要垂直边距值。", - "min-vertical-margin-message": "只允许0作为最小垂直边距值。", - "max-vertical-margin-message": "只允许50作为最大垂直边距值。", - "autofill-height": "自动填充布局高度", - "mobile-layout": "移动端布局设置", - "mobile-row-height": "移动端行高距(px)", - "mobile-row-height-required": "移动端行高距必填。", - "min-mobile-row-height-message": "移动端行高距至少5px。", - "max-mobile-row-height-message": "移动端行高距最多200px。", - "display-title": "显示仪表板标题", - "toolbar-always-open": "工具栏常驻", - "title-color": "标题颜色", - "display-dashboards-selection": "显示仪表板选项", - "display-entities-selection": "显示实体选项", - "display-dashboard-timewindow": "显示时间窗口", - "display-dashboard-export": "显示导出", - "import": "导入仪表板", - "export": "导出仪表板", - "export-failed-error": "无法导出仪表板: {{error}}", - "create-new-dashboard": "创建新的仪表板", - "dashboard-file": "仪表板文件", - "invalid-dashboard-file-error": "无法导入仪表板: 仪表板数据结构无效。", - "dashboard-import-missing-aliases-title": "配置导入仪表板使用的别名", - "create-new-widget": "创建新部件", - "import-widget": "导入部件", - "widget-file": "部件文件", - "invalid-widget-file-error": "无法导入窗口部件: 窗口部件数据结构无效。", - "widget-import-missing-aliases-title": "配置导入的窗口部件使用的别名", - "open-toolbar": "打开仪表板工具栏", - "close-toolbar": "关闭工具栏", - "configuration-error": "配置错误", - "alias-resolution-error-title": "仪表板别名配置错误", - "invalid-aliases-config": "无法找到与某些别名过滤器匹配的任何设备。
请联系您的管理员以解决此问题。", - "select-devices": "选择设备", - "assignedToCustomer": "分配给客户", - "public": "公共", - "public-link": "公共链接", - "copy-public-link": "复制公共链接", - "public-link-copied-message": "仪表板的公共链接已被复制到剪贴板", - "manage-states": "仪表板状态管理", - "states": "仪表板状态", - "search-states": "仪表板状态检索", - "selected-states": "{ count, select, 1 {1 仪表板状态} other {# 仪表板状态} } 选中", - "edit-state": "仪表板状态编辑", - "delete-state": "删除仪表板状态", - "add-state": "添加仪表板状态", - "state": "仪表板状态", - "state-name": "状态名", - "state-name-required": "仪表板状态名必填。", - "state-id": "状态ID", - "state-id-required": "仪表板状态ID必填。", - "state-id-exists": "仪表板状态ID已经存在。", - "is-root-state": "根状态", - "delete-state-title": "删除仪表板状态", - "delete-state-text": "确定要删除仪表板状态 '{{stateName}}' 吗?", - "show-details": "显示详情", - "hide-details": "隐藏详情", - "select-state": "选择目标状态", - "state-controller": "状态控制" - }, - "datakey": { - "settings": "设置", - "advanced": "高级", - "label": "标签", - "color": "颜色", - "units": "单位符号", - "decimals": "小数位数", - "data-generation-func": "数据生成功能", - "use-data-post-processing-func": "使用数据后处理功能", - "configuration": "数据键配置", - "timeseries": "时间序列", - "attributes": "属性", - "alarm": "Alarm fields", - "timeseries-required": "需要设备时间序列。", - "timeseries-or-attributes-required": "设备时间/属性必填。", - "maximum-timeseries-or-attributes": "最大允许 { count, select, 1 {1 时间序列/属性} other {# 时间序列/属性} }", - "alarm-fields-required": "警告字段必填。", - "function-types": "函数类型", - "function-types-required": "需要函数类型。", - "maximum-function-types": "至少需要 { count, select, 1 {1 函数类型} other {# 函数类型} }" - }, - "datasource": { - "type": "数据源类型", - "name": "数据源名称", - "add-datasource-prompt": "请添加数据源" - }, - "details": { - "edit-mode": "编辑模式", - "toggle-edit-mode": "切换编辑模式" - }, - "device": { - "device": "设备", - "device-required": "设备必填", - "devices": "设备", - "management": "设备管理", - "view-devices": "查看设备", - "device-alias": "设备别名", - "aliases": "设备别名", - "no-alias-matching": "'{{alias}}' 没有找到。", - "no-aliases-found": "找不到别名。", - "no-key-matching": "'{{key}}' 没有找到。", - "no-keys-found": "找不到密钥。", - "create-new-alias": "创建一个新的!", - "create-new-key": "创建一个新的!", - "duplicate-alias-error": "找到重复别名 '{{alias}}'。
设备别名必须是唯一的。", - "configure-alias": "配置 '{{alias}}' 别名", - "no-devices-matching": "找不到与 '{{entity}}' 匹配的设备。", - "alias": "别名", - "alias-required": "需要设备别名。", - "remove-alias": "删除设备别名", - "add-alias": "添加设备别名", - "name-starts-with": "名称前缀", - "device-list": "设备列表", - "use-device-name-filter": "使用过滤器", - "device-list-empty": "没有被选中的设备", - "device-name-filter-required": "设备名称过滤器必填。", - "device-name-filter-no-device-matched": "找不到以'{{device}}' 开头的设备。", - "add": "添加设备", - "assign-to-customer": "分配给客户", - "assign-device-to-customer": "将设备分配给客户", - "assign-device-to-customer-text": "请选择要分配给客户的设备", - "make-public": "公开", - "make-private": "私有", - "no-devices-text": "找不到设备", - "assign-to-customer-text": "请选择客户分配设备", - "device-details": "设备详细信息", - "add-device-text": "添加新设备", - "credentials": "凭据", - "manage-credentials": "管理凭据", - "delete": "删除设备", - "assign-devices": "分配设备", - "assign-devices-text": "将{count,select,1 {1 设备} other {# 设备}}分配给客户", - "delete-devices": "删除设备", - "unassign-from-customer": "取消分配客户", - "unassign-devices": "取消分配设备", - "unassign-devices-action-title": "从客户处取消分配{count,select,1 {1 设备} other {# 设备}}", - "assign-new-device": "分配新设备", - "make-public-device-title": "您确定要将设备 '{{deviceName}}' 设为公开吗?", - "make-public-device-text": "确认后,设备及其所有数据将被设为公开并可被其他人访问。", - "make-private-device-title": "您确定要将设备 '{{deviceName}}' 设为私有吗?", - "make-private-device-text": "确认后,设备及其所有数据将被设为私有,不被其他人访问。", - "view-credentials": "查看凭据", - "delete-device-title": "您确定要删除设备的{{deviceName}}吗?", - "delete-device-text": "小心!确认后设备及其所有相关数据将不可恢复。", - "delete-devices-title": "您确定要删除{count,select,1 {1 设备} other {# 设备}} 吗?", - "delete-devices-action-title": "删除 {count,select,1 {1 设备} other {# 设备}}", - "delete-devices-text": "小心!确认后所有选定的设备将被删除,所有相关数据将不可恢复。", - "unassign-device-title": "您确定要取消分配设备 '{{deviceName}}'?", - "unassign-device-text": "确认后,设备将被取消分配,客户将无法访问。", - "unassign-device": "取消分配设备", - "unassign-devices-title": "您确定要取消分配{count,select,1 {1 设备} other {# 设备}} 吗?", - "unassign-devices-text": "确认后,所有选定的设备将被取消分配,并且客户将无法访问。", - "device-credentials": "设备凭据", - "credentials-type": "凭据类型", - "access-token": "访问令牌", - "access-token-required": "需要访问令牌", - "access-token-invalid": "访问令牌长度必须为1到20个字符。", - "rsa-key": "RSA公钥", - "rsa-key-required": "需要RSA公钥", - "secret": "密钥", - "secret-required": "密钥必填", - "device-type": "设备类型", - "device-type-required": "设备类型必填。", - "select-device-type": "选择设备类型", - "enter-device-type": "输入设备类型", - "any-device": "任意设备", - "no-device-types-matching": "没有找到符合 '{{entitySubtype}}' 的设备类型。", - "device-type-list-empty": "未选择设备类型", - "device-types": "设备类型", - "name": "名称", - "name-required": "名称必填。", - "description": "说明", - "events": "事件", - "details": "详细信息", - "copyId": "复制设备ID", - "copyAccessToken": "复制访问令牌", - "idCopiedMessage": "设备ID已复制到剪贴板", - "accessTokenCopiedMessage": "设备访问令牌已复制到剪贴板", - "assignedToCustomer": "分配给客户", - "unable-delete-device-alias-title": "无法删除设备别名", - "unable-delete-device-alias-text": "设备别名 '{{deviceAlias}}' 不能够被删除,因为它被下列部件所使用:
{{widgetsList}}", - "is-gateway": "是网关", - "public": "公开", - "device-public": "设备公开", - "select-device": "选择设备" - }, - "dialog": { - "close": "关闭对话框" - }, - "error": { - "unable-to-connect": "无法连接到服务器!请检查您的互联网连接。", - "unhandled-error-code": "未处理的错误代码: {{errorCode}}", - "unknown-error": "未知错误" - }, - "entity": { - "entity": "实体", - "entities": "实体", - "aliases": "实体别名", - "entity-alias": "实体别名", - "unable-delete-entity-alias-title": "无法删除实体别名", - "unable-delete-entity-alias-text": "实体别名 '{{entityAlias}}' 被以下部件使用不能删除:
{{widgetsList}}", - "duplicate-alias-error": "别名 '{{alias}}' 重复。
同一仪表板别名必须唯一。", - "missing-entity-filter-error": "别名 '{{alias}}' 缺少过滤器", - "configure-alias": "别名 '{{alias}}' 配置", - "alias": "别名", - "alias-required": "实体别名必填。", - "remove-alias": "移除实体别名", - "add-alias": "添加实体别名", - "entity-list": "实体列表", - "entity-type": "实体类型", - "entity-types": "实体类型", - "entity-type-list": "实体类型列表", - "any-entity": "任意实体", - "enter-entity-type": "输入实体类型", - "no-entities-matching": "没有找到符合 '{{entity}}' 的实体。", - "no-entity-types-matching": "没有找到符合 '{{entityType}}' 类型的实体。", - "name-starts-with": "名称开始于", - "use-entity-name-filter": "用户过滤", - "entity-list-empty": "没有选择实体。", - "entity-type-list-empty": "没有选择实体类型。", - "entity-name-filter-required": "实体名过滤器必填。", - "entity-name-filter-no-entity-matched": "没有找到以 '{{entity}}' 开头的实体", - "all-subtypes": "所有", - "select-entities": "选择实体", - "no-aliases-found": "没有找到别名", - "no-alias-matching": "没有找到 '{{alias}}'", - "create-new-alias": "创建新别名", - "key": "键", - "key-name": "键名", - "no-keys-found": "没有找到键", - "no-key-matching": "没有找到键 '{{key}}'", - "create-new-key": "创建新键", - "type": "类型", - "type-required": "实体类型必填。", - "type-device": "设备", - "type-devices": "设备", - "list-of-devices": "{ count, select, 1 {设备} other {# 设备列表} }", - "device-name-starts-with": "以 '{{prefix}}' 开头的设备", - "type-asset": "资产", - "type-assets": "资产", - "list-of-assets": "{ count, select, 1 {资产} other {# 资产列表} }", - "asset-name-starts-with": "以 '{{prefix}}' 开头的资产", - "type-rule": "规则", - "type-rules": "规则", - "list-of-rules": "{ count, select, 1 {规则} other {# 规则列表} }", - "rule-name-starts-with": "以 '{{prefix}}' 开头的规则", - "type-plugin": "插件", - "type-plugins": "插件", - "list-of-plugins": "{ count, select, 1 {插件} other {# 插件列表} }", - "plugin-name-starts-with": "以 '{{prefix}}' 开头的插件", - "type-tenant": "租户", - "type-tenants": "租户", - "list-of-tenants": "{ count, select, 1 {租户} other {# 租户列表} }", - "tenant-name-starts-with": "以 '{{prefix}}' 开头的租户", - "type-customer": "客户", - "type-customers": "客户", - "list-of-customers": "{ count, select, 1 {客户} other {# 客户列表} }", - "customer-name-starts-with": "以 '{{prefix}}' 开头的客户", - "type-user": "用户", - "type-users": "用户", - "list-of-users": "{ count, select, 1 {用户} other {# 用户列表} }", - "user-name-starts-with": "以 '{{prefix}}' 开头的用户", - "type-dashboard": "仪表板", - "type-dashboards": "仪表板", - "list-of-dashboards": "{ count, select, 1 {仪表板} other {# 仪表板列表} }", - "dashboard-name-starts-with": "以 '{{prefix}}' 开头的仪表板", - "type-alarm": "警告", - "type-alarms": "警告", - "list-of-alarms": "{ count, select, 1 {警告} other {# 警告列表} }", - "alarm-name-starts-with": "以 '{{prefix}}' 开头的警告", - "search": "实体检索", - "selected-entities": "{ count, select, 1 {1 实体} other {# 实体} } 被选中", - "entity-name": "实体名", - "details": "实体详情", - "no-entities-prompt": "没有找到实体", - "no-data": "无数据" - }, - "event": { - "event-type": "事件类型", - "type-error": "错误", - "type-lc-event": "生命周期事件", - "type-stats": "类型统计", - "no-events-prompt": "找不到事件", - "error": "错误", - "alarm": "报警", - "event-time": "事件时间", - "server": "服务器", - "body": "整体", - "method": "方法", - "event": "事件", - "status": "状态", - "success": "成功", - "failed": "失败", - "messages-processed": "消息处理", - "errors-occurred": "错误发生" - }, - "extension": { // TODO - "extensions": "Extensions", - "selected-extensions": "{ count, select, 1 {1 extension} other {# extensions} } selected", - "type": "Type", - "key": "Key", - "value": "Value", - "id": "Id", - "extension-id": "Extension id", - "extension-type": "Extension type", - "transformer-json": "JSON *", - "unique-id-required": "Current extension id already exists.", - "delete": "Delete extension", - "add": "Add extension", - "edit": "Edit extension", - "delete-extension-title": "Are you sure you want to delete the extension '{{extensionId}}'?", - "delete-extension-text": "Be careful, after the confirmation the extension and all related data will become unrecoverable.", - "delete-extensions-title": "Are you sure you want to delete { count, select, 1 {1 extension} other {# extensions} }?", - "delete-extensions-text": "Be careful, after the confirmation all selected extensions will be removed.", - "converters": "Converters", - "converter-id": "Converter id", - "configuration": "Configuration", - "converter-configurations": "Converter configurations", - "token": "Security token", - "add-converter": "Add converter", - "add-config": "Add converter configuration", - "device-name-expression": "Device name expression", - "device-type-expression": "Device type expression", - "custom": "Custom", - "to-double": "To Double", - "transformer": "Transformer", - "json-required": "Transformer json is required.", - "json-parse": "Unable to parse transformer json.", - "attributes": "Attributes", - "add-attribute": "Add attribute", - "add-map": "Add mapping element", - "timeseries": "Timeseries", - "add-timeseries": "Add timeseries", - "field-required": "Field is required", - "brokers": "Brokers", - "add-broker": "Add broker", - "host": "Host", - "port": "Port", - "port-range": "Port should be in a range from 1 to 65535.", - "ssl": "Ssl", - "credentials": "Credentials", - "username": "Username", - "password": "Password", - "retry-interval": "Retry interval in milliseconds", - "anonymous": "Anonymous", - "basic": "Basic", - "pem": "PEM", - "ca-cert": "CA certificate file *", - "private-key": "Private key file *", - "cert": "Certificate file *", - "no-file": "No file selected.", - "drop-file": "Drop a file or click to select a file to upload.", - "mapping": "Mapping", - "topic-filter": "Topic filter", - "converter-type": "Converter type", - "converter-json": "Json", - "json-name-expression": "Device name json expression", - "topic-name-expression": "Device name topic expression", - "json-type-expression": "Device type json expression", - "topic-type-expression": "Device type topic expression", - "attribute-key-expression": "Attribute key expression", - "attr-json-key-expression": "Attribute key json expression", - "attr-topic-key-expression": "Attribute key topic expression", - "request-id-expression": "Request id expression", - "request-id-json-expression": "Request id json expression", - "request-id-topic-expression": "Request id topic expression", - "response-topic-expression": "Response topic expression", - "value-expression": "Value expression", - "topic": "Topic", - "timeout": "Timeout in milliseconds", - "converter-json-required": "Converter json is required.", - "converter-json-parse": "Unable to parse converter json.", - "filter-expression": "Filter expression", - "connect-requests": "Connect requests", - "add-connect-request": "Add connect request", - "disconnect-requests": "Disconnect requests", - "add-disconnect-request": "Add disconnect request", - "attribute-requests": "Attribute requests", - "add-attribute-request": "Add attribute request", - "attribute-updates": "Attribute updates", - "add-attribute-update": "Add attribute update", - "server-side-rpc": "Server side RPC", - "add-server-side-rpc-request": "Add server-side RPC request", - "device-name-filter": "Device name filter", - "attribute-filter": "Attribute filter", - "method-filter": "Method filter", - "request-topic-expression": "Request topic expression", - "response-timeout": "Response timeout in milliseconds", - "topic-expression": "Topic expression", - "client-scope": "Client scope", - "add-device": "Add device", - "opc-server": "Servers", - "opc-add-server": "Add server", - "opc-add-server-prompt": "Please add server", - "opc-application-name": "Application name", - "opc-application-uri": "Application uri", - "opc-scan-period-in-seconds": "Scan period in seconds", - "opc-security": "Security", - "opc-identity": "Identity", - "opc-keystore": "Keystore", - "opc-type": "Type", - "opc-keystore-type": "Type", - "opc-keystore-location": "Location *", - "opc-keystore-password": "Password", - "opc-keystore-alias": "Alias", - "opc-keystore-key-password": "Key password", - "opc-device-node-pattern": "Device node pattern", - "opc-device-name-pattern": "Device name pattern", - "modbus-server": "Servers/slaves", - "modbus-add-server": "Add server/slave", - "modbus-add-server-prompt": "Please add server/slave", - "modbus-transport": "Transport", - "modbus-port-name": "Serial port name", - "modbus-encoding": "Encoding", - "modbus-parity": "Parity", - "modbus-baudrate": "Baud rate", - "modbus-databits": "Data bits", - "modbus-stopbits": "Stop bits", - "modbus-databits-range": "Data bits should be in a range from 7 to 8.", - "modbus-stopbits-range": "Stop bits should be in a range from 1 to 2.", - "modbus-unit-id": "Unit ID", - "modbus-unit-id-range": "Unit ID should be in a range from 1 to 247.", - "modbus-device-name": "Device name", - "modbus-poll-period": "Poll period (ms)", - "modbus-attributes-poll-period": "Attributes poll period (ms)", - "modbus-timeseries-poll-period": "Timeseries poll period (ms)", - "modbus-poll-period-range": "Poll period should be positive value.", - "modbus-tag": "Tag", - "modbus-function": "Function", - "modbus-register-address": "Register address", - "modbus-register-address-range": "Register address should be in a range from 0 to 65535.", - "modbus-register-bit-index": "Bit index", - "modbus-register-bit-index-range": "Bit index should be in a range from 0 to 15.", - "modbus-register-count": "Register count", - "modbus-register-count-range": "Register count should be a positive value.", - "modbus-byte-order": "Byte order", - - "sync": { - "status": "Status", - "sync": "Sync", - "not-sync": "Not sync", - "last-sync-time": "Last sync time", - "not-available": "Not available" - }, - - "export-extensions-configuration": "Export extensions configuration", - "import-extensions-configuration": "Import extensions configuration", - "import-extensions": "Import extensions", - "import-extension": "Import extension", - "export-extension": "Export extension", - "file": "Extensions file", - "invalid-file-error": "Invalid extension file" - }, - "fullscreen": { - "expand": "展开到全屏", - "exit": "退出全屏", - "toggle": "切换全屏模式", - "fullscreen": "全屏" - }, - "function": { - "function": "函数" - }, - "grid": { - "delete-item-title": "您确定要删除此项吗?", - "delete-item-text": "注意,确认后此项及其所有相关数据将变得不可恢复。", - "delete-items-title": "你确定你要删除 { count, select, 1 {1 项} other {# 项} }吗?", - "delete-items-action-title": "删除 { count, select, 1 {1 项} other {# 项} }", - "delete-items-text": "注意,确认后所有选择的项目将被删除,所有相关数据将不可恢复。", - "add-item-text": "添加新项目", - "no-items-text": "没有找到项目", - "item-details": "项目详细信息", - "delete-item": "删除项目", - "delete-items": "删除项目", - "scroll-to-top": "滚动到顶部" - }, - "help": { - "goto-help-page": "转到帮助页面" - }, - "home": { - "home": "首页", - "profile": "属性", - "logout": "注销", - "menu": "菜单", - "avatar": "头像", - "open-user-menu": "打开用户菜单" - }, - "import": { - "no-file": "没有选择文件", - "drop-file": "拖动一个JSON文件或者单击以选择要上传的文件。" - }, - "item": { - "selected": "选择" - }, - "js-func": { - "no-return-error": "函数必须返回值!", - "return-type-mismatch": "函数必须返回 '{{type}}' 类型的值!" - }, - "key-val": { // TODO - "key": "Key", - "value": "Value", - "remove-entry": "Remove entry", - "add-entry": "Add entry", - "no-data": "No entries" - }, - "layout": { - "layout": "布局", - "manage": "布局管理", - "settings": "布局设置", - "color": "颜色", - "main": "主体", - "right": "右侧", - "select": "选择目标布局" - }, - "legend": { - "position": "图例位置", - "show-max": "显示最大值", - "show-min": "显示最小值", - "show-avg": "显示平均值", - "show-total": "显示总数", - "settings": "图例设置", - "min": "最小值", - "max": "最大值", - "avg": "平均值", - "total": "总数" - }, - "login": { - "login": "登录", - "request-password-reset": "请求密码重置", - "reset-password": "重置密码", - "create-password": "创建密码", - "passwords-mismatch-error": "输入的密码必须相同!", - "password-again": "再次输入密码", - "sign-in": "登录 ", - "username": "用户名(电子邮件)", - "remember-me": "记住我", - "forgot-password": "忘记密码?", - "password-reset": "密码重置", - "new-password": "新密码", - "new-password-again": "再次输入新密码", - "password-link-sent-message": "密码重置链接已成功发送!", - "email": "电子邮件" - }, - "position": { - "top": "顶部", - "bottom": "底部", - "left": "左侧", - "right": "右侧" - }, - "profile": { - "profile": "属性", - "change-password": "更改密码", - "current-password": "当前密码" - }, - "relation": { - "relations": "关联", - "direction": "方向", - "search-direction": { - "FROM": "从", - "TO": "到" - }, - "direction-type": { - "FROM": "从", - "TO": "到" - }, - "from-relations": "向外的关联", - "to-relations": "向内的关联", - "selected-relations": "{ count, select, 1 {1 关联} other {# 关联} } 被选中", - "type": "类型", - "to-entity-type": "到实体类型", - "to-entity-name": "到实体名称", - "from-entity-type": "从实体类型", - "from-entity-name": "从实体类型", - "to-entity": "到实体", - "from-entity": "从实体", - "delete": "删除关联", - "relation-type": "关联类型", - "relation-type-required": "关联类型必填", - "any-relation-type": "任意类型", - "add": "添加关联", - "edit": "编辑关联", - "delete-to-relation-title": "确定要删除实体 '{{entityName}}' 的关联吗?", - "delete-to-relation-text": "确定删除后实体 '{{entityName}}' 将取消与当前实体的关联关系。", - "delete-to-relations-title": "确定要删除 { count, select, 1 {1 关联} other {# 关联} }?", - "delete-to-relations-text": "确定删除所有选择的关联关系后,与当前实体对应的所有关联关系将被移除。", - "delete-from-relation-title": "确定要从实体 '{{entityName}}' 删除关联吗?", - "delete-from-relation-text": "确定删除后,当前实体将与实体 '{{entityName}}' 取消关联", - "delete-from-relations-title": "确定删除 { count, select, 1 {1 关联} other {# 关联} } 吗?", - "delete-from-relations-text": "确定删除所有选择的关联关系后,当前实体将与对应的实体取消关联", - "remove-relation-filter": "移除关联过滤器", - "add-relation-filter": "添加关联过滤器", - "any-relation": "任意关联", - "relation-filters": "关联过滤器", - "additional-info": "附加信息 (JSON)", - "invalid-additional-info": "无法解析附加信息json。" - }, - "rulechain": { // TODO - "rulechain": "Rule chain", - "rulechains": "Rule chains", - "root": "Root", - "delete": "Delete rule chain", - "name": "Name", - "name-required": "Name is required.", - "description": "Description", - "add": "Add Rule Chain", - "set-root": "Make rule chain root", - "set-root-rulechain-title": "Are you sure you want to make the rule chain '{{ruleChainName}}' root?", - "set-root-rulechain-text": "After the confirmation the rule chain will become root and will handle all incoming transport messages.", - "delete-rulechain-title": "Are you sure you want to delete the rule chain '{{ruleChainName}}'?", - "delete-rulechain-text": "Be careful, after the confirmation the rule chain and all related data will become unrecoverable.", - "delete-rulechains-title": "Are you sure you want to delete { count, select, 1 {1 rule chain} other {# rule chains} }?", - "delete-rulechains-action-title": "Delete { count, select, 1 {1 rule chain} other {# rule chains} }", - "delete-rulechains-text": "Be careful, after the confirmation all selected rule chains will be removed and all related data will become unrecoverable.", - "add-rulechain-text": "Add new rule chain", - "no-rulechains-text": "No rule chains found", - "rulechain-details": "Rule chain details", - "details": "Details", - "events": "Events", - "system": "System", - "import": "Import rule chain", - "export": "Export rule chain", - "export-failed-error": "Unable to export rule chain: {{error}}", - "create-new-rulechain": "Create new rule chain", - "rulechain-file": "Rule chain file", - "invalid-rulechain-file-error": "Unable to import rule chain: Invalid rule chain data structure.", - "copyId": "Copy rule chain Id", - "idCopiedMessage": "Rule chain Id has been copied to clipboard", - "select-rulechain": "Select rule chain", - "no-rulechains-matching": "No rule chains matching '{{entity}}' were found.", - "rulechain-required": "Rule chain is required", - "management": "Rules management", - "debug-mode": "Debug mode" - }, - "rulenode": { // TODO - "details": "Details", - "events": "Events", - "search": "Search nodes", - "open-node-library": "Open node library", - "add": "Add rule node", - "name": "Name", - "name-required": "Name is required.", - "type": "Type", - "description": "Description", - "delete": "Delete rule node", - "select-all-objects": "Select all nodes and connections", - "deselect-all-objects": "Deselect all nodes and connections", - "delete-selected-objects": "Delete selected nodes and connections", - "delete-selected": "Delete selected", - "select-all": "Select all", - "copy-selected": "Copy selected", - "deselect-all": "Deselect all", - "rulenode-details": "Rule node details", - "debug-mode": "Debug mode", - "configuration": "Configuration", - "link": "Link", - "link-details": "Rule node link details", - "add-link": "Add link", - "link-label": "Link label", - "link-label-required": "Link label is required.", - "custom-link-label": "Custom link label", - "custom-link-label-required": "Custom link label is required.", - "type-filter": "Filter", - "type-filter-details": "Filter incoming messages with configured conditions", - "type-enrichment": "Enrichment", - "type-enrichment-details": "Add additional information into Message Metadata", - "type-transformation": "Transformation", - "type-transformation-details": "Change Message payload and Metadata", - "type-action": "Action", - "type-action-details": "Perform special action", - "type-external": "External", - "type-external-details": "Interacts with external system", - "type-rule-chain": "Rule Chain", - "type-rule-chain-details": "Forwards incoming messages to specified Rule Chain", - "type-input": "Input", - "type-input-details": "Logical input of Rule Chain, forwards incoming messages to next related Rule Node", - "directive-is-not-loaded": "Defined configuration directive '{{directiveName}}' is not available.", - "ui-resources-load-error": "Failed to load configuration ui resources.", - "invalid-target-rulechain": "Unable to resolve target rule chain!", - "test-script-function": "Test script function", - "message": "Message", - "message-type": "Message type", - "message-type-required": "Message type is required", - "metadata": "Metadata", - "metadata-required": "Metadata entries can't be empty.", - "output": "Output", - "test": "Test", - "help": "Help" - }, - "tenant": { - "tenant": "租户", - "tenants": "租户", - "management": "租户管理", - "add": "添加租户", - "admins": "管理员", - "manage-tenant-admins": "管理租户管理员", - "delete": "删除租户", - "add-tenant-text": "添加新租户", - "no-tenants-text": "没有找到租户", - "tenant-details": "租客详情", - "delete-tenant-title": "您确定要删除租户'{{tenantTitle}}'吗?", - "delete-tenant-text": "小心!确认后,租户和所有相关数据将不可恢复。", - "delete-tenants-title": "您确定要删除 {count,select,1 {1 租户} other {# 租户}} 吗?", - "delete-tenants-action-title": "删除 { count, select, 1 {1 租户} other {# 租户} }", - "delete-tenants-text": "小心!确认后,所有选定的租户将被删除,所有相关数据将不可恢复。", - "title": "标题", - "title-required": "标题必填。", - "description": "描述", - "details": "详情", - "events": "事件", - "copyId": "复制租户ID", - "idCopiedMessage": "租户ID已经复制到粘贴板", - "select-tenant": "选择租户", - "no-tenants-matching": "没有找到符合 '{{entity}}' 的租户", - "tenant-required": "租户必填" - }, - "timeinterval": { - "seconds-interval": "{ seconds, select, 1 {1 秒} other {# 秒} }", - "minutes-interval": "{ minutes, select, 1 {1 分} other {# 分} }", - "hours-interval": "{ hours, select, 1 {1 小时} other {# 小时} }", - "days-interval": "{ days, select, 1 {1 天} other {# 天} }", - "days": "天", - "hours": "时", - "minutes": "分", - "seconds": "秒", - "advanced": "高级" - }, - "timewindow": { - "days": "{ days, select, 1 { 天 } other {# 天 } }", - "hours": "{ hours, select, 0 { 小时 } 1 {1 小时 } other {# 小时 } }", - "minutes": "{ minutes, select, 0 { 分 } 1 {1 分 } other {# 分 } }", - "seconds": "{ seconds, select, 0 { 秒 } 1 {1 秒 } other {# 秒 } }", - "realtime": "实时", - "history": "历史", - "last-prefix": "最后", - "period": "从 {{ startTime }} 到 {{ endTime }}", - "edit": "编辑时间窗口", - "date-range": "日期范围", - "last": "最后", - "time-period": "时间段" - }, - "user": { - "user": "用户", - "users": "用户", - "customer-users": "客户用户", - "tenant-admins": "租户管理员", - "sys-admin": "系统管理员", - "tenant-admin": "租户管理员", - "customer": "客户", - "anonymous": "匿名", - "add": "添加用户", - "delete": "删除用户", - "add-user-text": "添加新用户", - "no-users-text": "找不到用户", - "user-details": "用户详细信息", - "delete-user-title": "您确定要删除用户 '{{userEmail}}' 吗?", - "delete-user-text": "小心!确认后,用户和所有相关数据将不可恢复。", - "delete-users-title": "你确定你要删除 { count, select, 1 {1 用户} other {# 用户} } 吗?", - "delete-users-action-title": "删除 { count, select, 1 {1 用户} other {# 用户} }", - "delete-users-text": "小心!确认后,所有选定的用户将被删除,所有相关数据将不可恢复。", - "activation-email-sent-message": "激活电子邮件已成功发送!", - "resend-activation": "重新发送激活", - "email": "电子邮件", - "email-required": "电子邮件必填。", - "invalid-email-format": "无效的邮件格式。", - "first-name": "名字", - "last-name": "姓", - "description": "描述", - "default-dashboard": "默认面板", - "always-fullscreen": "始终全屏", - "select-user": "选择用户", - "no-users-matching": "没有找到符合 '{{entity}}' 的用户。", - "user-required": "用户必填", - "activation-method": "激活方式", - "display-activation-link": "显示激活链接", - "send-activation-mail": "发送激活邮件", - "activation-link": "用户激活链接", - "activation-link-text": "使用该链接 激活 激活用户:", - "copy-activation-link": "复制用户激活链接", - "activation-link-copied-message": "用户激活链接已经复制到粘贴板", - "details": "Details" // TODO - }, - "value": { - "type": "值类型", - "string": "字符串", - "string-value": "字符串值", - "integer": "数字", - "integer-value": "数字值", - "invalid-integer-value": "整数值无效", - "double": "双精度小数", - "double-value": "双精度小数值", - "boolean": "布尔", - "boolean-value": "布尔值", - "false": "假", - "true": "真" - }, - "widget": { - "widget-library": "部件库", - "widget-bundle": "部件包", - "select-widgets-bundle": "选择部件包", - "management": "部件管理", - "editor": "部件编辑器", - "widget-type-not-found": "加载部件配置时出现问题。
可能关联的\n 部件类型已删除。", - "widget-type-load-error": "由于以下错误,部件未加载:", - "remove": "删除部件", - "edit": "编辑部件", - "remove-widget-title": "您确定要删除部件 '{{widgetTitle}}' 吗?", - "remove-widget-text": "确认后,窗口部件和所有相关数据将不可恢复。", - "timeseries": "时间序列", - "latest-values": "最新值", - "rpc": "控件部件", - "alarm": "警告部件", - "static": "静态部件", - "select-widget-type": "选择窗口部件类型", - "missing-widget-title-error": "部件标题必须指定!", - "widget-saved": "部件已保存", - "unable-to-save-widget-error": "无法保存窗口部件! 部件有错误!", - "save": "保存部件", - "saveAs": "将部件另存为", - "save-widget-type-as": "将部件类型另存为", - "save-widget-type-as-text": "请输入新的部件标题和/或选择目标部件包", - "toggle-fullscreen": "切换全屏", - "run": "运行部件", - "title": "部件标题", - "title-required": "需要部件标题。", - "type": "部件类型", - "resources": "资源", - "resource-url": "JavaScript/CSS URL", - "remove-resource": "删除资源", - "add-resource": "添加资源", - "html": "HTML", - "tidy": "整理", - "css": "CSS", - "settings-schema": "设置模式", - "datakey-settings-schema": "数据键设置模式", - "javascript": "Javascript", - "remove-widget-type-title": "您确定要删除部件类型 '{{widgetName}}'吗?", - "remove-widget-type-text": "确认后,窗口部件类型和所有相关数据将不可恢复。", - "remove-widget-type": "删除部件类型", - "add-widget-type": "添加新的部件类型", - "widget-type-load-failed-error": "无法加载部件类型!", - "widget-template-load-failed-error": "无法加载部件模板!", - "add": "添加部件", - "undo": "撤消部件更改", - "export": "导出部件" - }, - "widget-action": { - "header-button": "部件顶部按钮", - "open-dashboard-state": "切换到新仪表板状态", - "update-dashboard-state": "更新当前仪表板状态", - "open-dashboard": "切换到另一个仪表板", - "custom": "自定义动作", - "target-dashboard-state": "目标仪表板状态", - "target-dashboard-state-required": "目标仪表板状态必填", - "set-entity-from-widget": "从部件中设置实体", - "target-dashboard": "目标仪表板", - "open-right-layout": "打开右侧布局 (移动端视图)" - }, - "widgets-bundle": { - "current": "当前包", - "widgets-bundles": "部件包", - "add": "添加部件包", - "delete": "删除部件包", - "title": "标题", - "title-required": "标题必填。", - "add-widgets-bundle-text": "添加新的部件包", - "no-widgets-bundles-text": "找不到部件包", - "empty": "部件包是空的", - "details": "详情", - "widgets-bundle-details": "部件包详细信息", - "delete-widgets-bundle-title": "您确定要删除部件包 '{{widgetsBundleTitle}}'吗?", - "delete-widgets-bundle-text": "小心!确认后,部件包和所有相关数据将不可恢复。", - "delete-widgets-bundles-title": "你确定你要删除 { count, select, 1 {1 部件包} other {# 部件包} } 吗?", - "delete-widgets-bundles-action-title": "删除 { count, select, 1 {1 部件包} other {# 部件包} }", - "delete-widgets-bundles-text": "小心!确认后,所有选定的部件包将被删除,所有相关数据将不可恢复。", - "no-widgets-bundles-matching": "没有找到与 '{{widgetsBundle}}' 匹配的部件包。", - "widgets-bundle-required": "需要部件包。", - "system": "系统", - "import": "导入部件包", - "export": "导出部件包", - "export-failed-error": "无法导出部件包: {{error}}", - "create-new-widgets-bundle": "创建新的部件包", - "widgets-bundle-file": "部件包文件", - "invalid-widgets-bundle-file-error": "无法导入部件包:无效的部件包数据结构。" - }, - "widget-config": { - "data": "数据", - "settings": "设置", - "advanced": "高级", - "title": "标题", - "general-settings": "常规设置", - "display-title": "显示标题", - "drop-shadow": "阴影", - "enable-fullscreen": "启用全屏", - "background-color": "背景颜色", - "text-color": "文字颜色", - "padding": "填充", - "margin": "Margin", - "widget-style": "部件风格", - "title-style": "标题风格", - "mobile-mode-settings": "移动端设置", - "order": "顺序", - "height": "高度", - "units": "特殊符号展示值", - "decimals": "浮点数后的位数", - "timewindow": "时间窗口", - "use-dashboard-timewindow": "使用仪表板的时间窗口", - "display-legend": "显示图例", - "datasources": "数据源", - "maximum-datasources": "最大允许 { count, select, 1 {1 数据} other {# 数据} }", - "datasource-type": "类型", - "datasource-parameters": "参数", - "remove-datasource": "移除数据源", - "add-datasource": "添加数据源", - "target-device": "目标设备", - "alarm-source": "警告源", - "actions": "动作", - "action": "动作", - "add-action": "添加动作", - "search-actions": "动作检索", - "action-source": "动作源", - "action-source-required": "动作源必填", - "action-name": "动作名称", - "action-name-required": "动作名称必填。", - "action-name-not-unique": "动作名称已经存在。
统一动作源的动作名称必须唯一。", - "action-icon": "图标", - "action-type": "类型", - "action-type-required": "类型必填", - "edit-action": "编辑动作", - "delete-action": "删除动作", - "delete-action-title": "删除部件动作", - "delete-action-text": "确定要删除部件动作 '{{actionName}}' 吗?" - }, - "widget-type": { - "import": "导入部件类型", - "export": "导出部件类型", - "export-failed-error": "无法导出部件类型: {{error}}", - "create-new-widget-type": "创建新的部件类型", - "widget-type-file": "部件类型文件", - "invalid-widget-type-file-error": "无法导入部件类型:无效的部件类型数据结构。" - }, - "icon": { - "icon": "图标", - "select-icon": "选择图标", - "material-icons": "素材图标", - "show-all": "显示所有图标" - }, - "custom": { // TODO - "widget-action": { - "action-cell-button": "Action cell button", - "row-click": "On row click", - "marker-click": "On marker click", - "tooltip-tag-action": "Tooltip tag action" - } - }, - "language": { - "language": "语言", - "en_US": "英语", - "ko_KR": "韩语", - "zh_CN": "汉语", - "ru_RU": "俄语", - "es_ES": "西班牙语" - } - }; - angular.extend(locales, { - 'zh_CN': zh_CN - }); -} diff --git a/ui/src/app/locale/locale.constant-zh_CN.json b/ui/src/app/locale/locale.constant-zh_CN.json new file mode 100644 index 0000000000..b55305a68e --- /dev/null +++ b/ui/src/app/locale/locale.constant-zh_CN.json @@ -0,0 +1,1448 @@ +{ + "access": { + "unauthorized": "未授权", + "unauthorized-access": "未授权访问", + "unauthorized-access-text": "您需要登陆才能访问这个资源!", + "access-forbidden": "禁止访问", + "access-forbidden-text": "您没有访问此位置的权限
如果您仍希望访问此位置,请尝试使用其他用户登录。", + "refresh-token-expired": "会话已过期", + "refresh-token-failed": "无法刷新会话" + }, + "action": { + "activate": "激活", + "suspend": "暂停", + "save": "保存", + "saveAs": "另存为", + "cancel": "取消", + "ok": "确定", + "delete": "删除", + "add": "添加", + "yes": "是", + "no": "否", + "update": "更新", + "remove": "移除", + "search": "查询", + "clear-search": "清除查询", + "assign": "分配", + "unassign": "取消分配", + "share": "分享", + "make-private": "私有", + "apply": "应用", + "apply-changes": "应用更改", + "edit-mode": "编辑模式", + "enter-edit-mode": "进入编辑模式", + "decline-changes": "撤销更改", + "close": "关闭", + "back": "后退", + "run": "运行", + "sign-in": "登录!", + "edit": "编辑", + "view": "查看", + "create": "创建", + "drag": "拖拽", + "refresh": "刷新", + "undo": "撤销", + "copy": "复制", + "paste": "粘贴", + "copy-reference": "复制引用", + "paste-reference": "粘贴引用", + "import": "导入", + "export": "导出", + "share-via": "通过 {{provider}}分享" + }, + "aggregation": { + "aggregation": "聚合", + "function": "数据聚合功能", + "limit": "最大值", + "group-interval": "分组间隔", + "min": "最少值", + "max": "最大值", + "avg": "平均值", + "sum": "求和", + "count": "计数", + "none": "空" + }, + "admin": { + "general": "常规", + "general-settings": "常规设置", + "outgoing-mail": "发送邮件", + "outgoing-mail-settings": "发送邮件设置", + "system-settings": "系统设置", + "test-mail-sent": "测试邮件发送成功!", + "base-url": "基本URL", + "base-url-required": "基本URL必填。", + "mail-from": "邮件来自", + "mail-from-required": "邮件发件人必填。", + "smtp-protocol": "SMTP协议", + "smtp-host": "SMTP主机", + "smtp-host-required": "SMTP主机必填。", + "smtp-port": "SMTP端口", + "smtp-port-required": "您必须提供一个smtp端口。", + "smtp-port-invalid": "这看起来不是有效的smtp端口。", + "timeout-msec": "超时(ms)", + "timeout-required": "超时必填。", + "timeout-invalid": "这看起来不像有效的超时值。", + "enable-tls": "启用TLS", + "send-test-mail": "发送测试邮件" + }, + "alarm": { + "alarm": "警告", + "alarms": "警告", + "select-alarm": "选择警告", + "no-alarms-matching": "没有找到匹配 '{{entity}}' 的警告", + "alarm-required": "警告必填", + "alarm-status": "警告状态", + "search-status": { + "ANY": "所有", + "ACTIVE": "已激活", + "CLEARED": "已清除", + "ACK": "已应答", + "UNACK": "未应答" + }, + "display-status": { + "ACTIVE_UNACK": "激活未应答", + "ACTIVE_ACK": "激活已应答", + "CLEARED_UNACK": "清除未应答", + "CLEARED_ACK": "清除已应答" + }, + "no-alarms-prompt": "未发现警告", + "created-time": "创建时间", + "type": "类型", + "severity": "严重程度", + "originator": "起因", + "originator-type": "起因类型", + "details": "详情", + "status": "状态", + "alarm-details": "警告详情", + "start-time": "开始时间", + "end-time": "结束时间", + "ack-time": "应答时间", + "clear-time": "创建时间", + "severity-critical": "危险", + "severity-major": "重要", + "severity-minor": "次要", + "severity-warning": "警告", + "severity-indeterminate": "不确定", + "acknowledge": "应答", + "clear": "清除", + "search": "搜索警告", + "selected-alarms": "已选择 { count, plural, 1 {1 警告} other {# 警告} } ", + "no-data": "无数据显示", + "polling-interval": "警告轮询间隔(秒)", + "polling-interval-required": "警告轮询间隔必填。", + "min-polling-interval-message": "轮询间隔至少是1秒。", + "aknowledge-alarms-title": "应答 { count, plural, 1 {1 警告} other {# 警告} }", + "aknowledge-alarms-text": "确定要应答 { count, plural, 1 {1 警告} other {# 警告} }?", + "clear-alarms-title": "清除 { count, plural, 1 {1 警告} other {# 警告} }", + "clear-alarms-text": "确定要清除 { count, plural, 1 {1 警告} other {# 警告} }?" + }, + "alias": { + "add": "添加别名", + "edit": "编辑别名", + "name": "别名", + "name-required": "别名必填", + "duplicate-alias": "别名已经存在。", + "filter-type-single-entity": "单个实体", + "filter-type-entity-list": "实体列表", + "filter-type-entity-name": "实体名称", + "filter-type-state-entity": "实体(仪表板状态)", + "filter-type-state-entity-description": "实体令牌(仪表板状态参数)", + "filter-type-asset-type": "资产类型", + "filter-type-asset-type-description": "类型为 '{{assetType}}' 的资产", + "filter-type-asset-type-and-name-description": "类型为 '{{assetType}}' 且以 '{{prefix}}' 开头的资产", + "filter-type-device-type": "设备类型", + "filter-type-device-type-description": "类型为 '{{deviceType}}' 的设备", + "filter-type-device-type-and-name-description": "类型为 '{{deviceType}}' 且以 '{{prefix}}' 开头的设备", + "filter-type-relations-query": "关系查询", + "filter-type-relations-query-description": "具有 {{relationType}} 关联 {{direction}} {{rootEntity}} 的 {{entities}} ", + "filter-type-asset-search-query": "资产搜索查询", + "filter-type-asset-search-query-description": "类型为 {{assetTypes}} 且具有 {{relationType}} 关联 {{direction}} {{rootEntity}} 的资产", + "filter-type-device-search-query": "设备搜索查询", + "filter-type-device-search-query-description": "类型为 {{deviceTypes}} 且具有 {{relationType}} 关联 {{direction}} {{rootEntity}} 的设备", + "entity-filter": "实体过滤", + "resolve-multiple": "解决为多实体", + "filter-type": "过滤类型", + "filter-type-required": "过滤类型必填。", + "entity-filter-no-entity-matched": "未找到符合指定过滤条件的实体。", + "no-entity-filter-specified": "没有指定实体过滤条件", + "root-state-entity": "使用仪表板状态实体作为根实体", + "root-entity": "根实体", + "state-entity-parameter-name": "状态实体参数名称", + "default-state-entity": "默认状态实体", + "default-entity-parameter-name": "默认", + "max-relation-level": "最大关系层级", + "unlimited-level": "不限层级", + "state-entity": "仪表板状态实体", + "all-entities": "所有实体", + "any-relation": "不限" + }, + "asset": { + "asset": "资产", + "assets": "资产", + "management": "资产管理", + "view-assets": "查看资产", + "add": "添加资产", + "assign-to-customer": "分配给客户", + "assign-asset-to-customer": "将资产分配给客户", + "assign-asset-to-customer-text": "请选择要分配给客户的资产", + "no-assets-text": "未找到资产", + "assign-to-customer-text": "请选择客户以分配资产", + "public": "公开", + "assignedToCustomer": "分配客户", + "make-public": "资产设为公开", + "make-private": "资产设为私有", + "unassign-from-customer": "取消分配客户", + "delete": "删除资产", + "asset-public": "资产公开", + "asset-type": "资产类型", + "asset-type-required": "资产类型必填。", + "select-asset-type": "选择资产类型", + "enter-asset-type": "输入资产类型", + "any-asset": "任何资产", + "no-asset-types-matching": "没有找到匹配 '{{entitySubtype}}' 的资产类型。", + "asset-type-list-empty": "资产类型未选择。", + "asset-types": "资产类型", + "name": "名称", + "name-required": "名称必填。", + "description": "描述", + "type": "类型", + "type-required": "类型必填。", + "details": "详情", + "events": "事件", + "add-asset-text": "添加新资产", + "asset-details": "资产详情", + "assign-assets": "分配资产", + "assign-assets-text": "分配 { count, plural, 1 {1 资产} other {# 资产} } 给客户", + "delete-assets": "删除资产", + "unassign-assets": "取消分配资产", + "unassign-assets-action-title": "从客户处取消分配 { count, plural, 1 {1 资产} other {# 资产} } ", + "assign-new-asset": "分配新资产", + "delete-asset-title": "确定要删除资产 '{{assetName}}'?", + "delete-asset-text": "小心!确认后资产及其所有相关数据将不可恢复。", + "delete-assets-title": "确定要删除 { count, plural, 1 {1 资产} other {# 资产} }?", + "delete-assets-action-title": "删除 { count, plural, 1 {1 资产} other {# 资产} }", + "delete-assets-text": "小心,确认后,所有选定的资产将被删除,所有相关的数据将变得不可恢复。", + "make-public-asset-title": "你确定你想创建公开'{{assetName}}'资产?", + "make-public-asset-text": "确认后,资产及其所有数据将被公开并被他人访问。", + "make-private-asset-title": "你确定你想创建私有 '{{assetName}}' 资产?", + "make-private-asset-text": "确认后,资产及其所有数据将被私有化,无法被他人访问。", + "unassign-asset-title": "您确定要取消对'{{assetName}}'资产的分配吗?", + "unassign-asset-text": "确认后,资产将未分配,客户无法访问。", + "unassign-asset": "未分配资产", + "unassign-assets-title": "您确定要取消分配 { count, plural, 1 {1 资产} other {# 资产} }吗?", + "unassign-assets-text": "确认后,所有选定的资产将被分配,客户无法访问。", + "copyId": "复制资产ID", + "idCopiedMessage": "资产ID已经复制到粘贴板", + "select-asset": "选择资产", + "no-assets-matching": "没有找到匹配 '{{entity}}' 的资产。", + "asset-required": "资产必填", + "name-starts-with": "资产名称以此开头" + }, + "attribute": { + "attributes": "属性", + "latest-telemetry": "最新遥测", + "attributes-scope": "设备属性范围", + "scope-latest-telemetry": "最新遥测", + "scope-client": "客户端属性", + "scope-server": "服务端属性", + "scope-shared": "共享属性", + "add": "添加属性", + "key": "键", + "last-update-time": "最后更新时间", + "key-required": "属性键必填。", + "value": "值", + "value-required": "属性值必填。", + "delete-attributes-title": "您确定要删除 { count, plural, 1 {1 属性} other {# 属性} }吗?", + "delete-attributes-text": "注意,确认后所有选中的属性都会被删除。", + "delete-attributes": "删除属性", + "enter-attribute-value": "输入属性值", + "show-on-widget": "在部件上显示", + "widget-mode": "部件模式", + "next-widget": "下一个部件", + "prev-widget": "上一个部件", + "add-to-dashboard": "添加到仪表板", + "add-widget-to-dashboard": "将部件添加到仪表板", + "selected-attributes": "{ count, plural, 1 {1 属性} other {# 属性} } 被选中", + "selected-telemetry": "{ count, plural, 1 {1 遥测} other {# 遥测} } 被选中" + }, + "audit-log": { + "audit": "审计", + "audit-logs": "审计日志", + "timestamp": "时间戳", + "entity-type": "实体类型", + "entity-name": "实体名称", + "user": "用户", + "type": "类型", + "status": "状态", + "details": "详情", + "type-added": "添加", + "type-deleted": "删除", + "type-updated": "更新", + "type-attributes-updated": "更新属性", + "type-attributes-deleted": "删除属性", + "type-rpc-call": "RPC调用", + "type-credentials-updated": "更新凭证", + "type-assigned-to-customer": "分配给客户", + "type-unassigned-from-customer": "未分配给客户", + "type-activated": "激活", + "type-suspended": "暂停", + "type-credentials-read": "读取凭证", + "type-attributes-read": "读取属性", + "status-success": "成功", + "status-failure": "失败", + "audit-log-details": "审计日志详情", + "no-audit-logs-prompt": "找不到日志", + "action-data": "活动数据", + "failure-details": "失败详情", + "search": "查找审计日志", + "clear-search": "清空查找" + }, + "confirm-on-exit": { + "message": "您有未保存的更改。确定要离开此页吗?", + "html-message": "您有未保存的更改。
确定要离开此页面吗?", + "title": "未保存的更改" + }, + "contact": { + "country": "国家", + "city": "城市", + "state": "州", + "postal-code": "邮政编码", + "postal-code-invalid": "只允许数字。", + "address": "地址", + "address2": "地址2", + "phone": "手机", + "email": "邮箱", + "no-address": "无地址" + }, + "common": { + "username": "用户名", + "password": "密码", + "enter-username": "输入用户名", + "enter-password": "输入密码", + "enter-search": "输入检索条件" + }, + "content-type": { + "json": "Json", + "text": "Text", + "binary": "Binary (Base64)" + }, + "customer": { + "customer": "客户", + "customers": "客户", + "management": "客户管理", + "dashboard": "客户仪表板", + "dashboards": "客户仪表板", + "devices": "客户设备", + "assets": "客户资产", + "public-dashboards": "公共仪表板", + "public-devices": "公共设备", + "public-assets": "公共资产", + "add": "添加客户", + "delete": "删除客户", + "manage-customer-users": "管理客户用户", + "manage-customer-devices": "管理客户设备", + "manage-customer-dashboards": "管理客户仪表板", + "manage-public-devices": "管理公共设备", + "manage-public-dashboards": "管理公共仪表板", + "manage-customer-assets": "管理客户资产", + "manage-public-assets": "管理公共资产", + "add-customer-text": "添加新客户", + "no-customers-text": "没有找到客户", + "customer-details": "客户详情", + "delete-customer-title": "您确定要删除客户'{{customerTitle}}'吗?", + "delete-customer-text": "小心!确认后,客户及其所有相关数据将不可恢复。", + "delete-customers-title": "您确定要删除 { count, plural, 1 {1 客户} other {# 客户} }吗?", + "delete-customers-action-title": "删除 { count, plural, 1 {1 客户} other {# 客户} }", + "delete-customers-text": "小心!确认后,所有选定的客户将被删除,所有相关数据将不可恢复。", + "manage-users": "管理用户", + "manage-assets": "管理资产", + "manage-devices": "管理设备", + "manage-dashboards": "管理仪表板", + "title": "标题", + "title-required": "需要标题", + "description": "描述", + "details": "详情", + "events": "事件", + "copyId": "复制客户ID", + "idCopiedMessage": "客户ID已复制到粘贴板", + "select-customer": "选择客户", + "no-customers-matching": "没有找到匹配 '{{entity}}' 的客户。", + "customer-required": "客户是必选项", + "select-default-customer": "选择默认的客户", + "default-customer": "默认客户", + "default-customer-required": "为了调试租户级别上的仪表板,需要默认客户。" + }, + "datetime": { + "date-from": "日期从", + "time-from": "时间从", + "date-to": "日期到", + "time-to": "时间到" + }, + "dashboard": { + "dashboard": "仪表板", + "dashboards": "仪表板库", + "management": "仪表板管理", + "view-dashboards": "查看仪表板", + "add": "添加仪表板", + "assign-dashboard-to-customer": "将仪表板分配给客户", + "assign-dashboard-to-customer-text": "请选择要分配给客户的仪表板", + "assign-to-customer-text": "请选择客户分配仪表板", + "assign-to-customer": "分配给客户", + "unassign-from-customer": "取消分配客户", + "make-public": "仪表板设为公开", + "make-private": "仪表板设为私有", + "manage-assigned-customers": "管理已分配的客户", + "assigned-customers": "已分配的客户", + "assign-to-customers": "将仪表板分配给客户", + "assign-to-customers-text": "请选择客户指定仪表板", + "unassign-from-customers": "客户未分配仪表板", + "unassign-from-customers-text": "请选择从仪表板中取消分配的客户", + "no-dashboards-text": "没有找到仪表板", + "no-widgets": "没有配置部件", + "add-widget": "添加新的部件", + "title": "标题", + "select-widget-title": "选择部件", + "select-widget-subtitle": "可用的部件类型列表", + "delete": "删除仪表板", + "title-required": "需要标题。", + "description": "描述", + "details": "详情", + "dashboard-details": "仪表板详情", + "add-dashboard-text": "添加新的仪表板", + "assign-dashboards": "分配仪表板", + "assign-new-dashboard": "分配新的仪表板", + "assign-dashboards-text": "分配 { count, plural, 1 {1 仪表板} other {# 仪表板} } 给客户", + "unassign-dashboards-action-text": "未分配 { count, plural, 1 {1 仪表板} other {# 仪表板} } 给客户", + "delete-dashboards": "删除仪表板", + "unassign-dashboards": "取消分配仪表板", + "unassign-dashboards-action-title": "从客户处取消分配 { count, plural, 1 {1 仪表板} other {# 仪表板} } ", + "delete-dashboard-title": "您确定要删除仪表板 '{{dashboardTitle}}'吗?", + "delete-dashboard-text": "小心!确认后仪表板及其所有相关数据将不可恢复。", + "delete-dashboards-title": "你确定你要删除 { count, plural, 1 {1 仪表板} other {# 仪表板} }吗?", + "delete-dashboards-action-title": "删除 { count, plural, 1 {1 仪表板} other {# 仪表板} }", + "delete-dashboards-text": "小心!确认后所有选定的仪表板将被删除,所有相关数据将不可恢复。", + "unassign-dashboard-title": "您确定要取消分配仪表板 '{{dashboardTitle}}'吗?", + "unassign-dashboard-text": "确认后,面板将被取消分配,客户将无法访问。", + "unassign-dashboard": "取消分配仪表板", + "unassign-dashboards-title": "您确定要取消分配仪表板 { count, plural, 1 {1 仪表板} other {# 仪表板} } 吗?", + "unassign-dashboards-text": "确认后,所有选定的仪表板将被取消分配,客户将无法访问。", + "public-dashboard-title": "仪表板现已公布", + "public-dashboard-text": "你的仪表板 {{dashboardTitle}} 已被公开,可通过如下 链接访问:", + "public-dashboard-notice": "提示: 不要忘记将相关设备公开以访问其数据。", + "make-private-dashboard-title": "您确定要将仪表板 '{{dashboardTitle}}' 设为私有吗?", + "make-private-dashboard-text": "确认后,仪表板将被设为私有,不能被其他人访问。", + "make-private-dashboard": "仪表板设为私有", + "socialshare-text": "'{{dashboardTitle}}' 由Thingsboard提供支持", + "socialshare-title": "'{{dashboardTitle}}' 由Thingsboard提供支持", + "select-dashboard": "选择仪表板", + "no-dashboards-matching": "找不到符合 '{{entity}}' 的仪表板。", + "dashboard-required": "仪表板必填。", + "select-existing": "选择现有仪表板", + "create-new": "创建新的仪表板", + "new-dashboard-title": "新仪表板标题", + "open-dashboard": "打开仪表板", + "set-background": "设置背景", + "background-color": "背景颜色", + "background-image": "背景图片", + "background-size-mode": "背景大小模式", + "no-image": "无图像选择", + "drop-image": "拖拽图像或单击以选择要上传的文件。", + "settings": "设置", + "columns-count": "列数", + "columns-count-required": "需要列数。", + "min-columns-count-message": "只允许最少10列", + "max-columns-count-message": "只允许最多1000列", + "widgets-margins": "部件间边距", + "horizontal-margin": "水平边距", + "horizontal-margin-required": "需要水平边距值。", + "min-horizontal-margin-message": "只允许0作为最小水平边距值。", + "max-horizontal-margin-message": "只允许50作为最大水平边距值。", + "vertical-margin": "垂直边距", + "vertical-margin-required": "需要垂直边距值。", + "min-vertical-margin-message": "只允许0作为最小垂直边距值。", + "max-vertical-margin-message": "只允许50作为最大垂直边距值。", + "autofill-height": "自动填充布局高度", + "mobile-layout": "移动端布局设置", + "mobile-row-height": "移动端行高距(px)", + "mobile-row-height-required": "移动端行高距必填。", + "min-mobile-row-height-message": "移动端行高距至少5px。", + "max-mobile-row-height-message": "移动端行高距最多200px。", + "display-title": "显示仪表板标题", + "toolbar-always-open": "工具栏常驻", + "title-color": "标题颜色", + "display-dashboards-selection": "显示仪表板选项", + "display-entities-selection": "显示实体选项", + "display-dashboard-timewindow": "显示时间窗口", + "display-dashboard-export": "显示导出", + "import": "导入仪表板", + "export": "导出仪表板", + "export-failed-error": "无法导出仪表板: {{error}}", + "create-new-dashboard": "创建新的仪表板", + "dashboard-file": "仪表板文件", + "invalid-dashboard-file-error": "无法导入仪表板: 仪表板数据结构无效。", + "dashboard-import-missing-aliases-title": "配置导入仪表板使用的别名", + "create-new-widget": "创建新部件", + "import-widget": "导入部件", + "widget-file": "部件文件", + "invalid-widget-file-error": "无法导入窗口部件: 窗口部件数据结构无效。", + "widget-import-missing-aliases-title": "配置导入的窗口部件使用的别名", + "open-toolbar": "打开仪表板工具栏", + "close-toolbar": "关闭工具栏", + "configuration-error": "配置错误", + "alias-resolution-error-title": "仪表板别名配置错误", + "invalid-aliases-config": "无法找到与某些别名过滤器匹配的任何设备。
请联系您的管理员以解决此问题。", + "select-devices": "选择设备", + "assignedToCustomer": "分配给客户", + "public": "公共", + "public-link": "公共链接", + "copy-public-link": "复制公共链接", + "public-link-copied-message": "仪表板的公共链接已被复制到剪贴板", + "manage-states": "仪表板状态管理", + "states": "仪表板状态", + "search-states": "仪表板状态检索", + "selected-states": "{ count, plural, 1 {1 仪表板状态} other {# 仪表板状态} } 选中", + "edit-state": "仪表板状态编辑", + "delete-state": "删除仪表板状态", + "add-state": "添加仪表板状态", + "state": "仪表板状态", + "state-name": "状态名", + "state-name-required": "仪表板状态名必填。", + "state-id": "状态ID", + "state-id-required": "仪表板状态ID必填。", + "state-id-exists": "仪表板状态ID已经存在。", + "is-root-state": "根状态", + "delete-state-title": "删除仪表板状态", + "delete-state-text": "确定要删除仪表板状态 '{{stateName}}' 吗?", + "show-details": "显示详情", + "hide-details": "隐藏详情", + "select-state": "选择目标状态", + "state-controller": "状态控制" + }, + "datakey": { + "settings": "设置", + "advanced": "高级", + "label": "标签", + "color": "颜色", + "units": "单位符号", + "decimals": "小数位数", + "data-generation-func": "数据生成功能", + "use-data-post-processing-func": "使用数据后处理功能", + "configuration": "数据键配置", + "timeseries": "时间序列", + "attributes": "属性", + "alarm": "报警字段", + "timeseries-required": "需要设备时间序列。", + "timeseries-or-attributes-required": "设备时间/属性必填。", + "maximum-timeseries-or-attributes": "最大允许 { count, plural, 1 {1 时间序列/属性} other {# 时间序列/属性} }", + "alarm-fields-required": "警告字段必填。", + "function-types": "函数类型", + "function-types-required": "需要函数类型。", + "maximum-function-types": "至少需要 { count, plural, 1 {1 函数类型} other {# 函数类型} }" + }, + "datasource": { + "type": "数据源类型", + "name": "数据源名称", + "add-datasource-prompt": "请添加数据源" + }, + "details": { + "edit-mode": "编辑模式", + "toggle-edit-mode": "切换编辑模式" + }, + "device": { + "device": "设备", + "device-required": "设备必填", + "devices": "设备", + "management": "设备管理", + "view-devices": "查看设备", + "device-alias": "设备别名", + "aliases": "设备别名", + "no-alias-matching": "'{{alias}}' 没有找到。", + "no-aliases-found": "找不到别名。", + "no-key-matching": "'{{key}}' 没有找到。", + "no-keys-found": "找不到密钥。", + "create-new-alias": "创建一个新的!", + "create-new-key": "创建一个新的!", + "duplicate-alias-error": "找到重复别名 '{{alias}}'。
设备别名必须是唯一的。", + "configure-alias": "配置 '{{alias}}' 别名", + "no-devices-matching": "找不到与 '{{entity}}' 匹配的设备。", + "alias": "别名", + "alias-required": "需要设备别名。", + "remove-alias": "删除设备别名", + "add-alias": "添加设备别名", + "name-starts-with": "名称前缀", + "device-list": "设备列表", + "use-device-name-filter": "使用过滤器", + "device-list-empty": "没有被选中的设备", + "device-name-filter-required": "设备名称过滤器必填。", + "device-name-filter-no-device-matched": "找不到以'{{device}}' 开头的设备。", + "add": "添加设备", + "assign-to-customer": "分配给客户", + "assign-device-to-customer": "将设备分配给客户", + "assign-device-to-customer-text": "请选择要分配给客户的设备", + "make-public": "公开", + "make-private": "私有", + "no-devices-text": "找不到设备", + "assign-to-customer-text": "请选择客户分配设备", + "device-details": "设备详细信息", + "add-device-text": "添加新设备", + "credentials": "凭据", + "manage-credentials": "管理凭据", + "delete": "删除设备", + "assign-devices": "分配设备", + "assign-devices-text": "将{count,select,1 {1 设备} other {# 设备}}分配给客户", + "delete-devices": "删除设备", + "unassign-from-customer": "取消分配客户", + "unassign-devices": "取消分配设备", + "unassign-devices-action-title": "从客户处取消分配{count,select,1 {1 设备} other {# 设备}}", + "assign-new-device": "分配新设备", + "make-public-device-title": "您确定要将设备 '{{deviceName}}' 设为公开吗?", + "make-public-device-text": "确认后,设备及其所有数据将被设为公开并可被其他人访问。", + "make-private-device-title": "您确定要将设备 '{{deviceName}}' 设为私有吗?", + "make-private-device-text": "确认后,设备及其所有数据将被设为私有,不被其他人访问。", + "view-credentials": "查看凭据", + "delete-device-title": "您确定要删除设备的{{deviceName}}吗?", + "delete-device-text": "小心!确认后设备及其所有相关数据将不可恢复。", + "delete-devices-title": "您确定要删除{count,select,1 {1 设备} other {# 设备}} 吗?", + "delete-devices-action-title": "删除 {count,select,1 {1 设备} other {# 设备}}", + "delete-devices-text": "小心!确认后所有选定的设备将被删除,所有相关数据将不可恢复。", + "unassign-device-title": "您确定要取消分配设备 '{{deviceName}}'?", + "unassign-device-text": "确认后,设备将被取消分配,客户将无法访问。", + "unassign-device": "取消分配设备", + "unassign-devices-title": "您确定要取消分配{count,select,1 {1 设备} other {# 设备}} 吗?", + "unassign-devices-text": "确认后,所有选定的设备将被取消分配,并且客户将无法访问。", + "device-credentials": "设备凭据", + "credentials-type": "凭据类型", + "access-token": "访问令牌", + "access-token-required": "需要访问令牌", + "access-token-invalid": "访问令牌长度必须为1到20个字符。", + "rsa-key": "RSA公钥", + "rsa-key-required": "需要RSA公钥", + "secret": "密钥", + "secret-required": "密钥必填", + "device-type": "设备类型", + "device-type-required": "设备类型必填。", + "select-device-type": "选择设备类型", + "enter-device-type": "输入设备类型", + "any-device": "任意设备", + "no-device-types-matching": "没有找到符合 '{{entitySubtype}}' 的设备类型。", + "device-type-list-empty": "未选择设备类型", + "device-types": "设备类型", + "name": "名称", + "name-required": "名称必填。", + "description": "说明", + "events": "事件", + "details": "详细信息", + "copyId": "复制设备ID", + "copyAccessToken": "复制访问令牌", + "idCopiedMessage": "设备ID已复制到剪贴板", + "accessTokenCopiedMessage": "设备访问令牌已复制到剪贴板", + "assignedToCustomer": "分配给客户", + "unable-delete-device-alias-title": "无法删除设备别名", + "unable-delete-device-alias-text": "设备别名 '{{deviceAlias}}' 不能够被删除,因为它被下列部件所使用:
{{widgetsList}}", + "is-gateway": "是网关", + "public": "公开", + "device-public": "设备公开", + "select-device": "选择设备" + }, + "dialog": { + "close": "关闭对话框" + }, + "error": { + "unable-to-connect": "无法连接到服务器!请检查您的互联网连接。", + "unhandled-error-code": "未处理的错误代码: {{errorCode}}", + "unknown-error": "未知错误" + }, + "entity": { + "entity": "实体", + "entities": "实体", + "aliases": "实体别名", + "entity-alias": "实体别名", + "unable-delete-entity-alias-title": "无法删除实体别名", + "unable-delete-entity-alias-text": "实体别名 '{{entityAlias}}' 被以下部件使用不能删除:
{{widgetsList}}", + "duplicate-alias-error": "别名 '{{alias}}' 重复。
同一仪表板别名必须唯一。", + "missing-entity-filter-error": "别名 '{{alias}}' 缺少过滤器", + "configure-alias": "别名 '{{alias}}' 配置", + "alias": "别名", + "alias-required": "实体别名必填。", + "remove-alias": "移除实体别名", + "add-alias": "添加实体别名", + "entity-list": "实体列表", + "entity-type": "实体类型", + "entity-types": "实体类型", + "entity-type-list": "实体类型列表", + "any-entity": "任意实体", + "enter-entity-type": "输入实体类型", + "no-entities-matching": "没有找到符合 '{{entity}}' 的实体。", + "no-entity-types-matching": "没有找到符合 '{{entityType}}' 类型的实体。", + "name-starts-with": "名称开始于", + "use-entity-name-filter": "用户过滤", + "entity-list-empty": "没有选择实体。", + "entity-type-list-empty": "没有选择实体类型。", + "entity-name-filter-required": "实体名过滤器必填。", + "entity-name-filter-no-entity-matched": "没有找到以 '{{entity}}' 开头的实体", + "all-subtypes": "所有", + "select-entities": "选择实体", + "no-aliases-found": "没有找到别名", + "no-alias-matching": "没有找到 '{{alias}}'", + "create-new-alias": "创建新别名", + "key": "键", + "key-name": "键名", + "no-keys-found": "没有找到键", + "no-key-matching": "没有找到键 '{{key}}'", + "create-new-key": "创建新键", + "type": "类型", + "type-required": "实体类型必填。", + "type-device": "设备", + "type-devices": "设备", + "list-of-devices": "{ count, plural, 1 {设备} other {# 设备列表} }", + "device-name-starts-with": "以 '{{prefix}}' 开头的设备", + "type-asset": "资产", + "type-assets": "资产", + "list-of-assets": "{ count, plural, 1 {资产} other {# 资产列表} }", + "asset-name-starts-with": "以 '{{prefix}}' 开头的资产", + "type-rule": "规则", + "type-rules": "规则", + "list-of-rules": "{ count, plural, 1 {规则} other {# 规则列表} }", + "rule-name-starts-with": "以 '{{prefix}}' 开头的规则", + "type-plugin": "插件", + "type-plugins": "插件", + "list-of-plugins": "{ count, plural, 1 {插件} other {# 插件列表} }", + "plugin-name-starts-with": "以 '{{prefix}}' 开头的插件", + "type-tenant": "租户", + "type-tenants": "租户", + "list-of-tenants": "{ count, plural, 1 {租户} other {# 租户列表} }", + "tenant-name-starts-with": "以 '{{prefix}}' 开头的租户", + "type-customer": "客户", + "type-customers": "客户", + "list-of-customers": "{ count, plural, 1 {客户} other {# 客户列表} }", + "customer-name-starts-with": "以 '{{prefix}}' 开头的客户", + "type-user": "用户", + "type-users": "用户", + "list-of-users": "{ count, plural, 1 {用户} other {# 用户列表} }", + "user-name-starts-with": "以 '{{prefix}}' 开头的用户", + "type-dashboard": "仪表板", + "type-dashboards": "仪表板", + "list-of-dashboards": "{ count, plural, 1 {仪表板} other {# 仪表板列表} }", + "dashboard-name-starts-with": "以 '{{prefix}}' 开头的仪表板", + "type-alarm": "警告", + "type-alarms": "警告", + "list-of-alarms": "{ count, plural, 1 {警告} other {# 警告列表} }", + "alarm-name-starts-with": "以 '{{prefix}}' 开头的警告", + "type-rulechain": "规则链", + "type-rulechains": "规则链库", + "list-of-rulechains": "{ count, plural, 1 {一个规则链} other {# 规则链列表} }", + "rulechain-name-starts-with": "规则链前缀名称 '{{prefix}}'", + "type-current-customer": "当前客户", + "search": "实体检索", + "selected-entities": "{ count, plural, 1 {1 实体} other {# 实体} } 被选中", + "entity-name": "实体名", + "details": "实体详情", + "no-entities-prompt": "没有找到实体", + "no-data": "无数据" + }, + "event": { + "event-type": "事件类型", + "type-error": "错误", + "type-lc-event": "生命周期事件", + "type-stats": "类型统计", + "type-debug-rule-node": "调试", + "type-debug-rule-chain": "调试", + "no-events-prompt": "找不到事件", + "error": "错误", + "alarm": "报警", + "event-time": "事件时间", + "server": "服务器", + "body": "整体", + "method": "方法", + "type": "类型", + "entity": "实体", + "message-id": "消息ID", + "message-type": "消息类型", + "data-type": "数据类型", + "relation-type": "关系类型", + "metadata": "元数据", + "data": "数据", + "event": "事件", + "status": "状态", + "success": "成功", + "failed": "失败", + "messages-processed": "消息处理", + "errors-occurred": "错误发生" + }, + "extension": { + "extensions": "扩展", + "selected-extensions": "{ count, plural, 1 {1 扩展} 其它 {# 扩展} } 被选择", + "type": "类型", + "key": "健名", + "value": "值", + "id": "Id", + "extension-id": "扩展ID", + "extension-type": "扩展类型", + "transformer-json": "JSON *", + "unique-id-required": "当前扩展ID已经存在。", + "delete": "删除扩展", + "add": "添加扩展", + "edit": "编辑扩展", + "delete-extension-title": "确实要删除扩展名'{{extensionId}}'吗?", + "delete-extension-text": "小心,确认后,扩展和所有相关数据将变得不可恢复。", + "delete-extensions-title": "您确定要删除 { count, plural, 1 {1 表达式} 其它 {# 表达式} }吗?", + "delete-extensions-text": "小心,确认后,所有选定的扩展将被删除。", + "converters": "转换器", + "converter-id": "转换器序号", + "configuration": "配置", + "converter-configurations": "转换器的配置", + "token": "安全令牌", + "add-converter": "添加转换器", + "add-config": "添加转换器配置", + "device-name-expression": "设备名称表达式", + "device-type-expression": "设备类型表达式", + "custom": "顾客", + "to-double": "加倍", + "transformer": "转换器", + "json-required": "转换器JSON必填。", + "json-parse": "无法解析转换器JSON。", + "attributes": "属性", + "add-attribute": "添加属性", + "add-map": "添加映射元素", + "timeseries": "时间序列", + "add-timeseries": "添加时间序列", + "field-required": "必填字段", + "brokers": "代理服务器组", + "add-broker": "添加代理服务器", + "host": "主机", + "port": "端口", + "port-range": "端口应该在1到65535的范围内。", + "ssl": "Ssl", + "credentials": "证书", + "username": "用户名", + "password": "密码", + "retry-interval": "以毫秒为单位的重试间隔", + "anonymous": "匿名", + "basic": "Basic", + "pem": "PEM", + "ca-cert": "CA证书文件 *", + "private-key": "私钥文件 *", + "cert": "证书文件 *", + "no-file": "没有选择文件。", + "drop-file": "删除文件或单击以选择要上载的文件。", + "mapping": "映射", + "topic-filter": "主题滤波", + "converter-type": "转换类型", + "converter-json": "Json", + "json-name-expression": "设备名称JSON表达式", + "topic-name-expression": "设备名称主题表达式", + "json-type-expression": "设备类型JSON表达式", + "topic-type-expression": "设备类型主题表达式", + "attribute-key-expression": "属性关键字表达式", + "attr-json-key-expression": "属性键JSON表达式", + "attr-topic-key-expression": "属性关键字主题表达式", + "request-id-expression": "请求ID表达式", + "request-id-json-expression": "请求ID JSON表达式", + "request-id-topic-expression": "请求ID主题表达式", + "response-topic-expression": "响应主题表达式", + "value-expression": "值表达式", + "topic": "主题", + "timeout": "毫秒超时", + "converter-json-required": "转换JSON是必需的。", + "converter-json-parse": "无法解析转换JSON。", + "filter-expression": "过滤表达式", + "connect-requests": "连接请求", + "add-connect-request": "添加连接请求", + "disconnect-requests": "断开请求", + "add-disconnect-request": "添加断开请求", + "attribute-requests": "属性请求", + "add-attribute-request": "添加属性请求", + "attribute-updates": "属性更新", + "add-attribute-update": "添加属性更新", + "server-side-rpc": "服务端RPC", + "add-server-side-rpc-request": "添加服务端RPC请求", + "device-name-filter": "设备名称滤波", + "attribute-filter": "属性滤波", + "method-filter": "方法滤波", + "request-topic-expression": "请求主题表达式", + "response-timeout": "毫秒内响应超时", + "topic-expression": "主题表达", + "client-scope": "客户范围", + "add-device": "添加服务器", + "opc-server": "服务器组", + "opc-add-server": "添加服务器", + "opc-add-server-prompt": "请添加服务器", + "opc-application-name": "应用名称", + "opc-application-uri": "应用URI", + "opc-scan-period-in-seconds": "秒级扫描周期", + "opc-security": "安全性", + "opc-identity": "身份", + "opc-keystore": "密钥库", + "opc-type": "类型", + "opc-keystore-type": "类型", + "opc-keystore-location": "位置 *", + "opc-keystore-password": "密码", + "opc-keystore-alias": "别名", + "opc-keystore-key-password": "密钥密码", + "opc-device-node-pattern": "设备节点模式", + "opc-device-name-pattern": "设备名称模式", + "modbus-server": "Servers/slaves", + "modbus-add-server": "添加 server/slave", + "modbus-add-server-prompt": "请添加 server/slave", + "modbus-transport": "传输", + "modbus-port-name": "串口名称", + "modbus-encoding": "编码", + "modbus-parity": "奇偶性", + "modbus-baudrate": "波特率", + "modbus-databits": "数据位", + "modbus-stopbits": "停止位", + "modbus-databits-range": "数据位应该在7到8的范围内。", + "modbus-stopbits-range": "停止位应该在1到2的范围内。", + "modbus-unit-id": "单位编号", + "modbus-unit-id-range": "单位ID应该在1到247的范围内", + "modbus-device-name": "设备名称", + "modbus-poll-period": "轮询周期 (ms)", + "modbus-attributes-poll-period": "轮询属性周期 (ms)", + "modbus-timeseries-poll-period": "时间序列轮询周期 (ms)", + "modbus-poll-period-range": "轮询周期应为正值。", + "modbus-tag": "标签", + "modbus-function": "函数", + "modbus-register-address": "寄存器地址", + "modbus-register-address-range": "寄存器地址应该在0到65535的范围内。", + "modbus-register-bit-index": "位索引", + "modbus-register-bit-index-range": "位索引应该在0到15的范围内。", + "modbus-register-count": "寄存器计数", + "modbus-register-count-range": "寄存器计数应该是一个正值。", + "modbus-byte-order": "字节顺序", + "sync": { + "status": "状态", + "sync": "同步", + "not-sync": "不同步", + "last-sync-time": "最后同步时间", + "not-available": "无法使用" + }, + + "export-extensions-configuration": "导出扩展配置", + "import-extensions-configuration": "导入扩展配置", + "import-extensions": "导入扩展", + "import-extension": "导入扩展", + "export-extension": "导出扩展", + "file": "扩展文件", + "invalid-file-error": "无效的扩展文件" + }, + "fullscreen": { + "expand": "展开到全屏", + "exit": "退出全屏", + "toggle": "切换全屏模式", + "fullscreen": "全屏" + }, + "function": { + "function": "函数" + }, + "grid": { + "delete-item-title": "您确定要删除此项吗?", + "delete-item-text": "注意,确认后此项及其所有相关数据将变得不可恢复。", + "delete-items-title": "你确定你要删除 { count, plural, 1 {1 项} other {# 项} }吗?", + "delete-items-action-title": "删除 { count, plural, 1 {1 项} other {# 项} }", + "delete-items-text": "注意,确认后所有选择的项目将被删除,所有相关数据将不可恢复。", + "add-item-text": "添加新项目", + "no-items-text": "没有找到项目", + "item-details": "项目详细信息", + "delete-item": "删除项目", + "delete-items": "删除项目", + "scroll-to-top": "滚动到顶部" + }, + "help": { + "goto-help-page": "转到帮助页面" + }, + "home": { + "home": "首页", + "profile": "属性", + "logout": "注销", + "menu": "菜单", + "avatar": "头像", + "open-user-menu": "打开用户菜单" + }, + "import": { + "no-file": "没有选择文件", + "drop-file": "拖动一个JSON文件或者单击以选择要上传的文件。" + }, + "item": { + "selected": "选择" + }, + "js-func": { + "no-return-error": "函数必须返回值!", + "return-type-mismatch": "函数必须返回 '{{type}}' 类型的值!", + "tidy": "整洁" + }, + "key-val": { + "key": "键名", + "value": "值", + "remove-entry": "删除条目", + "add-entry": "增加条目", + "no-data": "没有条目" + }, + "layout": { + "layout": "布局", + "manage": "布局管理", + "settings": "布局设置", + "color": "颜色", + "main": "主体", + "right": "右侧", + "select": "选择目标布局" + }, + "legend": { + "position": "图例位置", + "show-max": "显示最大值", + "show-min": "显示最小值", + "show-avg": "显示平均值", + "show-total": "显示总数", + "settings": "图例设置", + "min": "最小值", + "max": "最大值", + "avg": "平均值", + "total": "总数" + }, + "login": { + "login": "登录", + "request-password-reset": "请求密码重置", + "reset-password": "重置密码", + "create-password": "创建密码", + "passwords-mismatch-error": "输入的密码必须相同!", + "password-again": "再次输入密码", + "sign-in": "登录 ", + "username": "用户名(电子邮件)", + "remember-me": "记住我", + "forgot-password": "忘记密码?", + "password-reset": "密码重置", + "new-password": "新密码", + "new-password-again": "再次输入新密码", + "password-link-sent-message": "密码重置链接已成功发送!", + "email": "电子邮件" + }, + "position": { + "top": "顶部", + "bottom": "底部", + "left": "左侧", + "right": "右侧" + }, + "profile": { + "profile": "属性", + "change-password": "更改密码", + "current-password": "当前密码" + }, + "relation": { + "relations": "关联", + "direction": "方向", + "search-direction": { + "FROM": "从", + "TO": "到" + }, + "direction-type": { + "FROM": "从", + "TO": "到" + }, + "from-relations": "向外的关联", + "to-relations": "向内的关联", + "selected-relations": "{ count, plural, 1 {1 关联} other {# 关联} } 被选中", + "type": "类型", + "to-entity-type": "到实体类型", + "to-entity-name": "到实体名称", + "from-entity-type": "从实体类型", + "from-entity-name": "从实体类型", + "to-entity": "到实体", + "from-entity": "从实体", + "delete": "删除关联", + "relation-type": "关联类型", + "relation-type-required": "关联类型必填", + "any-relation-type": "任意类型", + "add": "添加关联", + "edit": "编辑关联", + "delete-to-relation-title": "确定要删除实体 '{{entityName}}' 的关联吗?", + "delete-to-relation-text": "确定删除后实体 '{{entityName}}' 将取消与当前实体的关联关系。", + "delete-to-relations-title": "确定要删除 { count, plural, 1 {1 关联} other {# 关联} }?", + "delete-to-relations-text": "确定删除所有选择的关联关系后,与当前实体对应的所有关联关系将被移除。", + "delete-from-relation-title": "确定要从实体 '{{entityName}}' 删除关联吗?", + "delete-from-relation-text": "确定删除后,当前实体将与实体 '{{entityName}}' 取消关联", + "delete-from-relations-title": "确定删除 { count, plural, 1 {1 关联} other {# 关联} } 吗?", + "delete-from-relations-text": "确定删除所有选择的关联关系后,当前实体将与对应的实体取消关联", + "remove-relation-filter": "移除关联过滤器", + "add-relation-filter": "添加关联过滤器", + "any-relation": "任意关联", + "relation-filters": "关联过滤器", + "additional-info": "附加信息 (JSON)", + "invalid-additional-info": "无法解析附加信息json。" + }, + "rulechain": { + "rulechain": "规则链", + "rulechains": "规则链库", + "root": "根实体", + "delete": "删除规则", + "activate": "激活规则", + "suspend": "暂停规则", + "active": "激活", + "suspended": "暂停", + "name": "名称", + "name-required": "名称必填。", + "description": "描述", + "add": "添加规则", + "set-root": "创建规则链根", + "set-root-rulechain-title": "您确定要生成规则链'{{RuleChainName}}'根吗?", + "set-root-rulechain-text": "确认之后,规则链将变为根规格链,并将处理所有传入的传输消息。", + "delete-rulechain-title": " 确实要删除规则链'{{ruleChainName}}'吗?", + "delete-rulechain-text": "小心,在确认规则链和所有相关数据将变得不可恢复。", + "delete-rulechains-title": "确实要删除{count, plural, 1 { 1 规则链}其他{# 规则链库}}吗?", + "delete-rulechains-action-title": "删除 { count, plural, 1 {1 规则链} other {# 规则链库} }", + "delete-rulechains-text": "小心,确认后,所有选定的规则链将被删除,所有相关的数据将变得不可恢复。", + "add-rulechain-text": "添加新的规则链", + "no-rulechains-text": "规则链没有发现", + "rulechain-details": "规则链详情", + "details": "详情", + "events": "事件", + "system": "系统", + "import": "导入规则", + "export": "导出规则", + "export-failed-error": "无法导出规则:{{error}}", + "create-new-rulechain": "创建新的规则链", + "rulechain-file": "规则链文件", + "invalid-rulechain-file-error": "不能导入规则链:无效的规则链数据格式。", + "copyId": "复制规则链ID", + "idCopiedMessage": "规则ID已经复制到粘贴板", + "select-rulechain": "选择规则链", + "no-rulechains-matching": "没有发现匹配'{{entity}}'的规则链。", + "rulechain-required": "规则链必填", + "management": "规则集管理", + "debug-mode": "调试模式" + }, + "rulenode": { + "details": "详情", + "events": "事件", + "search": "搜索节点", + "open-node-library": "打开节点库", + "add": "添加规则节点", + "name": "名称", + "name-required": "名称必填。", + "type": "类型", + "description": "描述", + "delete": "删除规则节点", + "select-all-objects": "选择所有节点和连接", + "deselect-all-objects": "取消选择所有节点和连接", + "delete-selected-objects": "删除选定的节点和连接", + "delete-selected": "删除选定", + "select-all": "选择全部", + "copy-selected": "选择副本", + "deselect-all": "取消选择", + "rulenode-details": "规则节点详情", + "debug-mode": "调试模式", + "configuration": "配置", + "link": "链接", + "link-details": "规则节点链接详情", + "add-link": "添加链接", + "link-label": "链接标签", + "link-label-required": "链接标签必填", + "custom-link-label": "自定义链接标签", + "custom-link-label-required": "自定义链接标签必填", + "type-filter": "滤波器", + "type-filter-details": "使用配置条件过滤传入消息", + "type-enrichment": "属性集", + "type-enrichment-details": "向消息元数据中添加附加信息", + "type-transformation": "变换", + "type-transformation-details": "更改消息有效载荷和元数据", + "type-action": "动作", + "type-action-details": "执行特别动作", + "type-external": "外部的", + "type-external-details": "与外部系统交互", + "type-rule-chain": "规则链", + "type-rule-chain-details": "将传入消息转发到指定的规则链", + "type-input": "输入", + "type-input-details": "规则链的逻辑输入,将传入消息转发到下一个相关规则节点", + "directive-is-not-loaded": "定义的配置指令 '{{directiveName}}' 不可用。", + "ui-resources-load-error": "加载配置UI资源失败。", + "invalid-target-rulechain": "无法解析目标规则链!", + "test-script-function": "测试脚本功能", + "message": "消息", + "message-type": "消息类型", + "message-type-required": "消息类型必填", + "metadata": "元数据", + "metadata-required": "元数据项不能为空。", + "output": "输出", + "test": "测试", + "help": "帮助" + }, + "tenant": { + "tenant": "租户", + "tenants": "租户", + "management": "租户管理", + "add": "添加租户", + "admins": "管理员", + "manage-tenant-admins": "管理租户管理员", + "delete": "删除租户", + "add-tenant-text": "添加新租户", + "no-tenants-text": "没有找到租户", + "tenant-details": "租客详情", + "delete-tenant-title": "您确定要删除租户'{{tenantTitle}}'吗?", + "delete-tenant-text": "小心!确认后,租户和所有相关数据将不可恢复。", + "delete-tenants-title": "您确定要删除 {count,select,1 {1 租户} other {# 租户}} 吗?", + "delete-tenants-action-title": "删除 { count, plural, 1 {1 租户} other {# 租户} }", + "delete-tenants-text": "小心!确认后,所有选定的租户将被删除,所有相关数据将不可恢复。", + "title": "标题", + "title-required": "标题必填。", + "description": "描述", + "details": "详情", + "events": "事件", + "copyId": "复制租户ID", + "idCopiedMessage": "租户ID已经复制到粘贴板", + "select-tenant": "选择租户", + "no-tenants-matching": "没有找到符合 '{{entity}}' 的租户", + "tenant-required": "租户必填" + }, + "timeinterval": { + "seconds-interval": "{ seconds, plural, 1 {1 秒} other {# 秒} }", + "minutes-interval": "{ minutes, plural, 1 {1 分} other {# 分} }", + "hours-interval": "{ hours, plural, 1 {1 小时} other {# 小时} }", + "days-interval": "{ days, plural, 1 {1 天} other {# 天} }", + "days": "天", + "hours": "时", + "minutes": "分", + "seconds": "秒", + "advanced": "高级" + }, + "timewindow": { + "days": "{ days, plural, 1 { 天 } other {# 天 } }", + "hours": "{ hours, plural, 0 { 小时 } 1 {1 小时 } other {# 小时 } }", + "minutes": "{ minutes, plural, 0 { 分 } 1 {1 分 } other {# 分 } }", + "seconds": "{ seconds, plural, 0 { 秒 } 1 {1 秒 } other {# 秒 } }", + "realtime": "实时", + "history": "历史", + "last-prefix": "最后", + "period": "从 {{ startTime }} 到 {{ endTime }}", + "edit": "编辑时间窗口", + "date-range": "日期范围", + "last": "最后", + "time-period": "时间段" + }, + "user": { + "user": "用户", + "users": "用户", + "customer-users": "客户用户", + "tenant-admins": "租户管理员", + "sys-admin": "系统管理员", + "tenant-admin": "租户管理员", + "customer": "客户", + "anonymous": "匿名", + "add": "添加用户", + "delete": "删除用户", + "add-user-text": "添加新用户", + "no-users-text": "找不到用户", + "user-details": "用户详细信息", + "delete-user-title": "您确定要删除用户 '{{userEmail}}' 吗?", + "delete-user-text": "小心!确认后,用户和所有相关数据将不可恢复。", + "delete-users-title": "你确定你要删除 { count, plural, 1 {1 用户} other {# 用户} } 吗?", + "delete-users-action-title": "删除 { count, plural, 1 {1 用户} other {# 用户} }", + "delete-users-text": "小心!确认后,所有选定的用户将被删除,所有相关数据将不可恢复。", + "activation-email-sent-message": "激活电子邮件已成功发送!", + "resend-activation": "重新发送激活", + "email": "电子邮件", + "email-required": "电子邮件必填。", + "invalid-email-format": "无效的邮件格式。", + "first-name": "名字", + "last-name": "姓", + "description": "描述", + "default-dashboard": "默认面板", + "always-fullscreen": "始终全屏", + "select-user": "选择用户", + "no-users-matching": "没有找到符合 '{{entity}}' 的用户。", + "user-required": "用户必填", + "activation-method": "激活方式", + "display-activation-link": "显示激活链接", + "send-activation-mail": "发送激活邮件", + "activation-link": "用户激活链接", + "activation-link-text": "使用该链接 激活 激活用户:", + "copy-activation-link": "复制用户激活链接", + "activation-link-copied-message": "用户激活链接已经复制到粘贴板", + "details": "详细信息" + }, + "value": { + "type": "值类型", + "string": "字符串", + "string-value": "字符串值", + "integer": "数字", + "integer-value": "数字值", + "invalid-integer-value": "整数值无效", + "double": "双精度小数", + "double-value": "双精度小数值", + "boolean": "布尔", + "boolean-value": "布尔值", + "false": "假", + "true": "真", + "long": "Long" + }, + "widget": { + "widget-library": "部件库", + "widget-bundle": "部件包", + "select-widgets-bundle": "选择部件包", + "management": "管理部件", + "editor": "部件编辑器", + "widget-type-not-found": "加载部件配置出错。
可能关联的\n 部件已经删除了。", + "widget-type-load-error": "由于以下错误未加载小部件:", + "remove": "删除部件", + "edit": "编辑部件", + "remove-widget-title": "确实要删除 '{{widgetTitle}}'部件吗?", + "remove-widget-text": "确认后,控件和所有相关数据将变得不可恢复。", + "timeseries": "时间序列", + "search-data": "搜索数据", + "no-data-found": "没有找到数据", + "latest-values": "最新值", + "rpc": "控件部件", + "alarm": "警告部件", + "static": "静态部件", + "select-widget-type": "选择窗口部件类型", + "missing-widget-title-error": "部件标题必须指定!", + "widget-saved": "部件已保存", + "unable-to-save-widget-error": "无法保存部件!控件有错误!", + "save": "保存部件", + "saveAs": "部件另存为", + "save-widget-type-as": "部件类型另存为", + "save-widget-type-as-text": "请输入新的部件标题或选择目标部件包", + + "toggle-fullscreen": "切换全屏", + "run": "运行部件", + "title": "部件标题", + "title-required": "需要部件标题。", + "type": "部件类型", + "resources": "资源", + "resource-url": "JavaScript/CSS URL", + "remove-resource": "删除资源", + "add-resource": "添加资源", + "html": "HTML", + "tidy": "整理", + "css": "CSS", + "settings-schema": "设置模式", + "datakey-settings-schema": "数据键设置模式", + "javascript": "Javascript", + "remove-widget-type-title": "您确定要删除部件类型 '{{widgetName}}'吗?", + "remove-widget-type-text": "确认后,窗口部件类型和所有相关数据将不可恢复。", + "remove-widget-type": "删除部件类型", + "add-widget-type": "添加新的部件类型", + "widget-type-load-failed-error": "无法加载部件类型!", + "widget-template-load-failed-error": "无法加载部件模板!", + "add": "添加部件", + "undo": "撤消部件更改", + "export": "导出部件" + }, + "widget-action": { + "header-button": "部件顶部按钮", + "open-dashboard-state": "切换到新仪表板状态", + "update-dashboard-state": "更新当前仪表板状态", + "open-dashboard": "切换到另一个仪表板", + "custom": "自定义动作", + "target-dashboard-state": "目标仪表板状态", + "target-dashboard-state-required": "目标仪表板状态必填", + "set-entity-from-widget": "从部件中设置实体", + "target-dashboard": "目标仪表板", + "open-right-layout": "打开右侧布局 (移动端视图)" + }, + "widgets-bundle": { + "current": "当前包", + "widgets-bundles": "部件包", + "add": "添加部件包", + "delete": "删除部件包", + "title": "标题", + "title-required": "标题必填。", + "add-widgets-bundle-text": "添加新的部件包", + "no-widgets-bundles-text": "找不到部件包", + "empty": "部件包是空的", + "details": "详情", + "widgets-bundle-details": "部件包详细信息", + "delete-widgets-bundle-title": "您确定要删除部件包 '{{widgetsBundleTitle}}'吗?", + "delete-widgets-bundle-text": "小心!确认后,部件包和所有相关数据将不可恢复。", + "delete-widgets-bundles-title": "你确定你要删除 { count, plural, 1 {1 部件包} other {# 部件包} } 吗?", + "delete-widgets-bundles-action-title": "删除 { count, plural, 1 {1 部件包} other {# 部件包} }", + "delete-widgets-bundles-text": "小心!确认后,所有选定的部件包将被删除,所有相关数据将不可恢复。", + "no-widgets-bundles-matching": "没有找到与 '{{widgetsBundle}}' 匹配的部件包。", + "widgets-bundle-required": "需要部件包。", + "system": "系统", + "import": "导入部件包", + "export": "导出部件包", + "export-failed-error": "无法导出部件包: {{error}}", + "create-new-widgets-bundle": "创建新的部件包", + "widgets-bundle-file": "部件包文件", + "invalid-widgets-bundle-file-error": "无法导入部件包:无效的部件包数据结构。" + }, + "widget-config": { + "data": "数据", + "settings": "设置", + "advanced": "高级", + "title": "标题", + "general-settings": "常规设置", + "display-title": "显示标题", + "drop-shadow": "阴影", + "enable-fullscreen": "启用全屏", + "background-color": "背景颜色", + "text-color": "文字颜色", + "padding": "填充", + "margin": "边缘", + "widget-style": "部件风格", + "title-style": "标题风格", + "mobile-mode-settings": "移动端设置", + "order": "顺序", + "height": "高度", + "units": "特殊符号展示值", + "decimals": "浮点数后的位数", + "timewindow": "时间窗口", + "use-dashboard-timewindow": "使用仪表板的时间窗口", + "display-legend": "显示图例", + "datasources": "数据源", + "maximum-datasources": "最大允许 { count, plural, 1 {1 数据} other {# 数据} }", + "datasource-type": "类型", + "datasource-parameters": "参数", + "remove-datasource": "移除数据源", + "add-datasource": "添加数据源", + "target-device": "目标设备", + "alarm-source": "警告源", + "actions": "动作", + "action": "动作", + "add-action": "添加动作", + "search-actions": "动作检索", + "action-source": "动作源", + "action-source-required": "动作源必填", + "action-name": "动作名称", + "action-name-required": "动作名称必填。", + "action-name-not-unique": "动作名称已经存在。
统一动作源的动作名称必须唯一。", + "action-icon": "图标", + "action-type": "类型", + "action-type-required": "类型必填", + "edit-action": "编辑动作", + "delete-action": "删除动作", + "delete-action-title": "删除部件动作", + "delete-action-text": "确定要删除部件动作 '{{actionName}}' 吗?" + }, + "widget-type": { + "import": "导入部件类型", + "export": "导出部件类型", + "export-failed-error": "无法导出部件类型: {{error}}", + "create-new-widget-type": "创建新的部件类型", + "widget-type-file": "部件类型文件", + "invalid-widget-type-file-error": "无法导入部件类型:无效的部件类型数据结构。" + }, + "icon": { + "icon": "图标", + "select-icon": "选择图标", + "material-icons": "素材图标", + "show-all": "显示所有图标" + }, + "custom": { + "widget-action": { + "action-cell-button": "动作单元格按钮", + "row-click": "点击行", + "marker-click": "点击标记", + "tooltip-tag-action": "提示标签动作" + } + }, + "language": { + "language": "语言", + "locales": { + "en_US": "英语", + "ko_KR": "韩语", + "zh_CN": "汉语", + "ru_RU": "俄语", + "es_ES": "西班牙语", + "it_IT": "意大利" + } + } +} diff --git a/ui/src/app/locale/locale.constant.js b/ui/src/app/locale/locale.constant.js deleted file mode 100644 index 29f6f8e8f8..0000000000 --- a/ui/src/app/locale/locale.constant.js +++ /dev/null @@ -1,1466 +0,0 @@ -/* - * Copyright © 2016-2018 The Thingsboard Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import ThingsboardMissingTranslateHandler from './translate-handler'; - -export default angular.module('thingsboard.locale', []) - .factory('tbMissingTranslationHandler', ThingsboardMissingTranslateHandler) - .constant('locales', - { - 'en_US': { - "access": { - "unauthorized": "Unauthorized", - "unauthorized-access": "Unauthorized Access", - "unauthorized-access-text": "You should sign in to have access to this resource!", - "access-forbidden": "Access Forbidden", - "access-forbidden-text": "You haven't access rights to this location!
Try to sign in with different user if you still wish to gain access to this location.", - "refresh-token-expired": "Session has expired", - "refresh-token-failed": "Unable to refresh session" - }, - "action": { - "activate": "Activate", - "suspend": "Suspend", - "save": "Save", - "saveAs": "Save as", - "cancel": "Cancel", - "ok": "OK", - "delete": "Delete", - "add": "Add", - "yes": "Yes", - "no": "No", - "update": "Update", - "remove": "Remove", - "search": "Search", - "clear-search": "Clear search", - "assign": "Assign", - "unassign": "Unassign", - "share": "Share", - "make-private": "Make private", - "apply": "Apply", - "apply-changes": "Apply changes", - "edit-mode": "Edit mode", - "enter-edit-mode": "Enter edit mode", - "decline-changes": "Decline changes", - "close": "Close", - "back": "Back", - "run": "Run", - "sign-in": "Sign in!", - "edit": "Edit", - "view": "View", - "create": "Create", - "drag": "Drag", - "refresh": "Refresh", - "undo": "Undo", - "copy": "Copy", - "paste": "Paste", - "copy-reference": "Copy reference", - "paste-reference": "Paste reference", - "import": "Import", - "export": "Export", - "share-via": "Share via {{provider}}" - }, - "aggregation": { - "aggregation": "Aggregation", - "function": "Data aggregation function", - "limit": "Max values", - "group-interval": "Grouping interval", - "min": "Min", - "max": "Max", - "avg": "Average", - "sum": "Sum", - "count": "Count", - "none": "None" - }, - "admin": { - "general": "General", - "general-settings": "General Settings", - "outgoing-mail": "Outgoing Mail", - "outgoing-mail-settings": "Outgoing Mail Settings", - "system-settings": "System Settings", - "test-mail-sent": "Test mail was successfully sent!", - "base-url": "Base URL", - "base-url-required": "Base URL is required.", - "mail-from": "Mail From", - "mail-from-required": "Mail From is required.", - "smtp-protocol": "SMTP 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-invalid": "That doesn't look like a valid smtp port.", - "timeout-msec": "Timeout (msec)", - "timeout-required": "Timeout is required.", - "timeout-invalid": "That doesn't look like a valid timeout.", - "enable-tls": "Enable TLS", - "send-test-mail": "Send test mail" - }, - "alarm": { - "alarm": "Alarm", - "alarms": "Alarms", - "select-alarm": "Select alarm", - "no-alarms-matching": "No alarms matching '{{entity}}' were found.", - "alarm-required": "Alarm is required", - "alarm-status": "Alarm status", - "search-status": { - "ANY": "Any", - "ACTIVE": "Active", - "CLEARED": "Cleared", - "ACK": "Acknowledged", - "UNACK": "Unacknowledged" - }, - "display-status": { - "ACTIVE_UNACK": "Active Unacknowledged", - "ACTIVE_ACK": "Active Acknowledged", - "CLEARED_UNACK": "Cleared Unacknowledged", - "CLEARED_ACK": "Cleared Acknowledged" - }, - "no-alarms-prompt": "No alarms found", - "created-time": "Created time", - "type": "Type", - "severity": "Severity", - "originator": "Originator", - "originator-type": "Originator type", - "details": "Details", - "status": "Status", - "alarm-details": "Alarm details", - "start-time": "Start time", - "end-time": "End time", - "ack-time": "Acknowledged time", - "clear-time": "Cleared time", - "severity-critical": "Critical", - "severity-major": "Major", - "severity-minor": "Minor", - "severity-warning": "Warning", - "severity-indeterminate": "Indeterminate", - "acknowledge": "Acknowledge", - "clear": "Clear", - "search": "Search alarms", - "selected-alarms": "{ count, select, 1 {1 alarm} other {# alarms} } selected", - "no-data": "No data to display", - "polling-interval": "Alarms polling interval (sec)", - "polling-interval-required": "Alarms polling interval is required.", - "min-polling-interval-message": "At least 1 sec polling interval is allowed.", - "aknowledge-alarms-title": "Acknowledge { count, select, 1 {1 alarm} other {# alarms} }", - "aknowledge-alarms-text": "Are you sure you want to acknowledge { count, select, 1 {1 alarm} other {# alarms} }?", - "clear-alarms-title": "Clear { count, select, 1 {1 alarm} other {# alarms} }", - "clear-alarms-text": "Are you sure you want to clear { count, select, 1 {1 alarm} other {# alarms} }?" - }, - "alias": { - "add": "Add alias", - "edit": "Edit alias", - "name": "Alias name", - "name-required": "Alias name is required", - "duplicate-alias": "Alias with same name is already exists.", - "filter-type-single-entity": "Single entity", - "filter-type-entity-list": "Entity list", - "filter-type-entity-name": "Entity name", - "filter-type-state-entity": "Entity from dashboard state", - "filter-type-state-entity-description": "Entity taken from dashboard state parameters", - "filter-type-asset-type": "Asset type", - "filter-type-asset-type-description": "Assets of type '{{assetType}}'", - "filter-type-asset-type-and-name-description": "Assets of type '{{assetType}}' and with name starting with '{{prefix}}'", - "filter-type-device-type": "Device type", - "filter-type-device-type-description": "Devices of type '{{deviceType}}'", - "filter-type-device-type-and-name-description": "Devices of type '{{deviceType}}' and with name starting with '{{prefix}}'", - "filter-type-relations-query": "Relations query", - "filter-type-relations-query-description": "{{entities}} that have {{relationType}} relation {{direction}} {{rootEntity}}", - "filter-type-asset-search-query": "Asset search query", - "filter-type-asset-search-query-description": "Assets with types {{assetTypes}} that have {{relationType}} relation {{direction}} {{rootEntity}}", - "filter-type-device-search-query": "Device search query", - "filter-type-device-search-query-description": "Devices with types {{deviceTypes}} that have {{relationType}} relation {{direction}} {{rootEntity}}", - "entity-filter": "Entity filter", - "resolve-multiple": "Resolve as multiple entities", - "filter-type": "Filter type", - "filter-type-required": "Filter type is required.", - "entity-filter-no-entity-matched": "No entities matching specified filter were found.", - "no-entity-filter-specified": "No entity filter specified", - "root-state-entity": "Use dashboard state entity as root", - "root-entity": "Root entity", - "state-entity-parameter-name": "State entity parameter name", - "default-state-entity": "Default state entity", - "default-entity-parameter-name": "By default", - "max-relation-level": "Max relation level", - "unlimited-level": "Unlimited level", - "state-entity": "Dashboard state entity", - "all-entities": "All entities", - "any-relation": "any" - }, - "asset": { - "asset": "Asset", - "assets": "Assets", - "management": "Asset management", - "view-assets": "View Assets", - "add": "Add Asset", - "assign-to-customer": "Assign to customer", - "assign-asset-to-customer": "Assign Asset(s) To Customer", - "assign-asset-to-customer-text": "Please select the assets to assign to the customer", - "no-assets-text": "No assets found", - "assign-to-customer-text": "Please select the customer to assign the asset(s)", - "public": "Public", - "assignedToCustomer": "Assigned to customer", - "make-public": "Make asset public", - "make-private": "Make asset private", - "unassign-from-customer": "Unassign from customer", - "delete": "Delete asset", - "asset-public": "Asset is public", - "asset-type": "Asset type", - "asset-type-required": "Asset type is required.", - "select-asset-type": "Select asset type", - "enter-asset-type": "Enter asset type", - "any-asset": "Any asset", - "no-asset-types-matching": "No asset types matching '{{entitySubtype}}' were found.", - "asset-type-list-empty": "No asset types selected.", - "asset-types": "Asset types", - "name": "Name", - "name-required": "Name is required.", - "description": "Description", - "type": "Type", - "type-required": "Type is required.", - "details": "Details", - "events": "Events", - "add-asset-text": "Add new asset", - "asset-details": "Asset details", - "assign-assets": "Assign assets", - "assign-assets-text": "Assign { count, select, 1 {1 asset} other {# assets} } to customer", - "delete-assets": "Delete assets", - "unassign-assets": "Unassign assets", - "unassign-assets-action-title": "Unassign { count, select, 1 {1 asset} other {# assets} } from customer", - "assign-new-asset": "Assign new asset", - "delete-asset-title": "Are you sure you want to delete the asset '{{assetName}}'?", - "delete-asset-text": "Be careful, after the confirmation the asset and all related data will become unrecoverable.", - "delete-assets-title": "Are you sure you want to delete { count, select, 1 {1 asset} other {# assets} }?", - "delete-assets-action-title": "Delete { count, select, 1 {1 asset} other {# assets} }", - "delete-assets-text": "Be careful, after the confirmation all selected assets will be removed and all related data will become unrecoverable.", - "make-public-asset-title": "Are you sure you want to make the asset '{{assetName}}' public?", - "make-public-asset-text": "After the confirmation the asset and all its data will be made public and accessible by others.", - "make-private-asset-title": "Are you sure you want to make the asset '{{assetName}}' private?", - "make-private-asset-text": "After the confirmation the asset and all its data will be made private and won't be accessible by others.", - "unassign-asset-title": "Are you sure you want to unassign the asset '{{assetName}}'?", - "unassign-asset-text": "After the confirmation the asset will be unassigned and won't be accessible by the customer.", - "unassign-asset": "Unassign asset", - "unassign-assets-title": "Are you sure you want to unassign { count, select, 1 {1 asset} other {# assets} }?", - "unassign-assets-text": "After the confirmation all selected assets will be unassigned and won't be accessible by the customer.", - "copyId": "Copy asset Id", - "idCopiedMessage": "Asset Id has been copied to clipboard", - "select-asset": "Select asset", - "no-assets-matching": "No assets matching '{{entity}}' were found.", - "asset-required": "Asset is required", - "name-starts-with": "Asset name starts with" - }, - "attribute": { - "attributes": "Attributes", - "latest-telemetry": "Latest telemetry", - "attributes-scope": "Entity attributes scope", - "scope-latest-telemetry": "Latest telemetry", - "scope-client": "Client attributes", - "scope-server": "Server attributes", - "scope-shared": "Shared attributes", - "add": "Add attribute", - "key": "Key", - "last-update-time": "Last update time", - "key-required": "Attribute key is required.", - "value": "Value", - "value-required": "Attribute value is required.", - "delete-attributes-title": "Are you sure you want to delete { count, select, 1 {1 attribute} other {# attributes} }?", - "delete-attributes-text": "Be careful, after the confirmation all selected attributes will be removed.", - "delete-attributes": "Delete attributes", - "enter-attribute-value": "Enter attribute value", - "show-on-widget": "Show on widget", - "widget-mode": "Widget mode", - "next-widget": "Next widget", - "prev-widget": "Previous widget", - "add-to-dashboard": "Add to dashboard", - "add-widget-to-dashboard": "Add widget to dashboard", - "selected-attributes": "{ count, select, 1 {1 attribute} other {# attributes} } selected", - "selected-telemetry": "{ count, select, 1 {1 telemetry unit} other {# telemetry units} } selected" - }, - "audit-log": { - "audit": "Audit", - "audit-logs": "Audit Logs", - "timestamp": "Timestamp", - "entity-type": "Entity Type", - "entity-name": "Entity Name", - "user": "User", - "type": "Type", - "status": "Status", - "details": "Details", - "type-added": "Added", - "type-deleted": "Deleted", - "type-updated": "Updated", - "type-attributes-updated": "Attributes updated", - "type-attributes-deleted": "Attributes deleted", - "type-rpc-call": "RPC call", - "type-credentials-updated": "Credentials updated", - "type-assigned-to-customer": "Assigned to Customer", - "type-unassigned-from-customer": "Unassigned from Customer", - "type-activated": "Activated", - "type-suspended": "Suspended", - "type-credentials-read": "Credentials read", - "type-attributes-read": "Attributes read", - "status-success": "Success", - "status-failure": "Failure", - "audit-log-details": "Audit log details", - "no-audit-logs-prompt": "No logs found", - "action-data": "Action data", - "failure-details": "Failure details", - "search": "Search audit logs", - "clear-search": "Clear search" - }, - "confirm-on-exit": { - "message": "You have unsaved changes. Are you sure you want to leave this page?", - "html-message": "You have unsaved changes.
Are you sure you want to leave this page?", - "title": "Unsaved changes" - }, - "contact": { - "country": "Country", - "city": "City", - "state": "State / Province", - "postal-code": "Zip / Postal Code", - "postal-code-invalid": "Invalid Zip / Postal Code format.", - "address": "Address", - "address2": "Address 2", - "phone": "Phone", - "email": "Email", - "no-address": "No address" - }, - "common": { - "username": "Username", - "password": "Password", - "enter-username": "Enter username", - "enter-password": "Enter password", - "enter-search": "Enter search" - }, - "content-type": { - "json": "Json", - "text": "Text", - "binary": "Binary (Base64)" - }, - "customer": { - "customer": "Customer", - "customers": "Customers", - "management": "Customer management", - "dashboard": "Customer Dashboard", - "dashboards": "Customer Dashboards", - "devices": "Customer Devices", - "assets": "Customer Assets", - "public-dashboards": "Public Dashboards", - "public-devices": "Public Devices", - "public-assets": "Public Assets", - "add": "Add Customer", - "delete": "Delete customer", - "manage-customer-users": "Manage customer users", - "manage-customer-devices": "Manage customer devices", - "manage-customer-dashboards": "Manage customer dashboards", - "manage-public-devices": "Manage public devices", - "manage-public-dashboards": "Manage public dashboards", - "manage-customer-assets": "Manage customer assets", - "manage-public-assets": "Manage public assets", - "add-customer-text": "Add new customer", - "no-customers-text": "No customers found", - "customer-details": "Customer details", - "delete-customer-title": "Are you sure you want to delete the customer '{{customerTitle}}'?", - "delete-customer-text": "Be careful, after the confirmation the customer and all related data will become unrecoverable.", - "delete-customers-title": "Are you sure you want to delete { count, select, 1 {1 customer} other {# customers} }?", - "delete-customers-action-title": "Delete { count, select, 1 {1 customer} other {# customers} }", - "delete-customers-text": "Be careful, after the confirmation all selected customers will be removed and all related data will become unrecoverable.", - "manage-users": "Manage users", - "manage-assets": "Manage assets", - "manage-devices": "Manage devices", - "manage-dashboards": "Manage dashboards", - "title": "Title", - "title-required": "Title is required.", - "description": "Description", - "details": "Details", - "events": "Events", - "copyId": "Copy customer Id", - "idCopiedMessage": "Customer Id has been copied to clipboard", - "select-customer": "Select customer", - "no-customers-matching": "No customers matching '{{entity}}' were found.", - "customer-required": "Customer is required", - "select-default-customer": "Select default customer", - "default-customer": "Default customer", - "default-customer-required": "Default customer is required in order to debug dashboard on Tenant level" - }, - "datetime": { - "date-from": "Date from", - "time-from": "Time from", - "date-to": "Date to", - "time-to": "Time to" - }, - "dashboard": { - "dashboard": "Dashboard", - "dashboards": "Dashboards", - "management": "Dashboard management", - "view-dashboards": "View Dashboards", - "add": "Add Dashboard", - "assign-dashboard-to-customer": "Assign Dashboard(s) To Customer", - "assign-dashboard-to-customer-text": "Please select the dashboards to assign to the customer", - "assign-to-customer-text": "Please select the customer to assign the dashboard(s)", - "assign-to-customer": "Assign to customer", - "unassign-from-customer": "Unassign from customer", - "make-public": "Make dashboard public", - "make-private": "Make dashboard private", - "manage-assigned-customers": "Manage assigned customers", - "assigned-customers": "Assigned customers", - "assign-to-customers": "Assign Dashboard(s) To Customers", - "assign-to-customers-text": "Please select the customers to assign the dashboard(s)", - "unassign-from-customers": "Unassign Dashboard(s) From Customers", - "unassign-from-customers-text": "Please select the customers to unassign from the dashboard(s)", - "no-dashboards-text": "No dashboards found", - "no-widgets": "No widgets configured", - "add-widget": "Add new widget", - "title": "Title", - "select-widget-title": "Select widget", - "select-widget-subtitle": "List of available widget types", - "delete": "Delete dashboard", - "title-required": "Title is required.", - "description": "Description", - "details": "Details", - "dashboard-details": "Dashboard details", - "add-dashboard-text": "Add new dashboard", - "assign-dashboards": "Assign dashboards", - "assign-new-dashboard": "Assign new dashboard", - "assign-dashboards-text": "Assign { count, select, 1 {1 dashboard} other {# dashboards} } to customers", - "unassign-dashboards-action-text": "Unassign { count, select, 1 {1 dashboard} other {# dashboards} } from customers", - "delete-dashboards": "Delete dashboards", - "unassign-dashboards": "Unassign dashboards", - "unassign-dashboards-action-title": "Unassign { count, select, 1 {1 dashboard} other {# dashboards} } from customer", - "delete-dashboard-title": "Are you sure you want to delete the dashboard '{{dashboardTitle}}'?", - "delete-dashboard-text": "Be careful, after the confirmation the dashboard and all related data will become unrecoverable.", - "delete-dashboards-title": "Are you sure you want to delete { count, select, 1 {1 dashboard} other {# dashboards} }?", - "delete-dashboards-action-title": "Delete { count, select, 1 {1 dashboard} other {# dashboards} }", - "delete-dashboards-text": "Be careful, after the confirmation all selected dashboards will be removed and all related data will become unrecoverable.", - "unassign-dashboard-title": "Are you sure you want to unassign the dashboard '{{dashboardTitle}}'?", - "unassign-dashboard-text": "After the confirmation the dashboard will be unassigned and won't be accessible by the customer.", - "unassign-dashboard": "Unassign dashboard", - "unassign-dashboards-title": "Are you sure you want to unassign { count, select, 1 {1 dashboard} other {# dashboards} }?", - "unassign-dashboards-text": "After the confirmation all selected dashboards will be unassigned and won't be accessible by the customer.", - "public-dashboard-title": "Dashboard is now public", - "public-dashboard-text": "Your dashboard {{dashboardTitle}} is now public and accessible via next public link:", - "public-dashboard-notice": "Note: Do not forget to make related devices public in order to access their data.", - "make-private-dashboard-title": "Are you sure you want to make the dashboard '{{dashboardTitle}}' private?", - "make-private-dashboard-text": "After the confirmation the dashboard will be made private and won't be accessible by others.", - "make-private-dashboard": "Make dashboard private", - "socialshare-text": "'{{dashboardTitle}}' powered by ThingsBoard", - "socialshare-title": "'{{dashboardTitle}}' powered by ThingsBoard", - "select-dashboard": "Select dashboard", - "no-dashboards-matching": "No dashboards matching '{{entity}}' were found.", - "dashboard-required": "Dashboard is required.", - "select-existing": "Select existing dashboard", - "create-new": "Create new dashboard", - "new-dashboard-title": "New dashboard title", - "open-dashboard": "Open dashboard", - "set-background": "Set background", - "background-color": "Background color", - "background-image": "Background image", - "background-size-mode": "Background size mode", - "no-image": "No image selected", - "drop-image": "Drop an image or click to select a file to upload.", - "settings": "Settings", - "columns-count": "Columns count", - "columns-count-required": "Columns count is required.", - "min-columns-count-message": "Only 10 minimum column count is allowed.", - "max-columns-count-message": "Only 1000 maximum column count is allowed.", - "widgets-margins": "Margin between widgets", - "horizontal-margin": "Horizontal margin", - "horizontal-margin-required": "Horizontal margin value is required.", - "min-horizontal-margin-message": "Only 0 is allowed as minimum horizontal margin value.", - "max-horizontal-margin-message": "Only 50 is allowed as maximum horizontal margin value.", - "vertical-margin": "Vertical margin", - "vertical-margin-required": "Vertical margin value is required.", - "min-vertical-margin-message": "Only 0 is allowed as minimum vertical margin value.", - "max-vertical-margin-message": "Only 50 is allowed as maximum vertical margin value.", - "autofill-height": "Auto fill layout height", - "mobile-layout": "Mobile layout settings", - "mobile-row-height": "Mobile row height, px", - "mobile-row-height-required": "Mobile row height value is required.", - "min-mobile-row-height-message": "Only 5 pixels is allowed as minimum mobile row height value.", - "max-mobile-row-height-message": "Only 200 pixels is allowed as maximum mobile row height value.", - "display-title": "Display dashboard title", - "toolbar-always-open": "Keep toolbar opened", - "title-color": "Title color", - "display-dashboards-selection": "Display dashboards selection", - "display-entities-selection": "Display entities selection", - "display-dashboard-timewindow": "Display timewindow", - "display-dashboard-export": "Display export", - "import": "Import dashboard", - "export": "Export dashboard", - "export-failed-error": "Unable to export dashboard: {{error}}", - "create-new-dashboard": "Create new dashboard", - "dashboard-file": "Dashboard file", - "invalid-dashboard-file-error": "Unable to import dashboard: Invalid dashboard data structure.", - "dashboard-import-missing-aliases-title": "Configure aliases used by imported dashboard", - "create-new-widget": "Create new widget", - "import-widget": "Import widget", - "widget-file": "Widget file", - "invalid-widget-file-error": "Unable to import widget: Invalid widget data structure.", - "widget-import-missing-aliases-title": "Configure aliases used by imported widget", - "open-toolbar": "Open dashboard toolbar", - "close-toolbar": "Close toolbar", - "configuration-error": "Configuration error", - "alias-resolution-error-title": "Dashboard aliases configuration error", - "invalid-aliases-config": "Unable to find any devices matching to some of the aliases filter.
" + - "Please contact your administrator in order to resolve this issue.", - "select-devices": "Select devices", - "assignedToCustomer": "Assigned to customer", - "assignedToCustomers": "Assigned to customers", - "public": "Public", - "public-link": "Public link", - "copy-public-link": "Copy public link", - "public-link-copied-message": "Dashboard public link has been copied to clipboard", - "manage-states": "Manage dashboard states", - "states": "Dashboard states", - "search-states": "Search dashboard states", - "selected-states": "{ count, select, 1 {1 dashboard state} other {# dashboard states} } selected", - "edit-state": "Edit dashboard state", - "delete-state": "Delete dashboard state", - "add-state": "Add dashboard state", - "state": "Dashboard state", - "state-name": "Name", - "state-name-required": "Dashboard state name is required.", - "state-id": "State Id", - "state-id-required": "Dashboard state id is required.", - "state-id-exists": "Dashboard state with the same id is already exists.", - "is-root-state": "Root state", - "delete-state-title": "Delete dashboard state", - "delete-state-text": "Are you sure you want delete dashboard state with name '{{stateName}}'?", - "show-details": "Show details", - "hide-details": "Hide details", - "select-state": "Select target state", - "state-controller": "State controller" - }, - "datakey": { - "settings": "Settings", - "advanced": "Advanced", - "label": "Label", - "color": "Color", - "units": "Special symbol to show next to value", - "decimals": "Number of digits after floating point", - "data-generation-func": "Data generation function", - "use-data-post-processing-func": "Use data post-processing function", - "configuration": "Data key configuration", - "timeseries": "Timeseries", - "attributes": "Attributes", - "alarm": "Alarm fields", - "timeseries-required": "Entity timeseries are required.", - "timeseries-or-attributes-required": "Entity timeseries/attributes are required.", - "maximum-timeseries-or-attributes": "Maximum { count, select, 1 {1 timeseries/attribute is allowed.} other {# timeseries/attributes are allowed} }", - "alarm-fields-required": "Alarm fields are required.", - "function-types": "Function types", - "function-types-required": "Function types are required.", - "maximum-function-types": "Maximum { count, select, 1 {1 function type is allowed.} other {# function types are allowed} }" - }, - "datasource": { - "type": "Datasource type", - "name": "Name", - "add-datasource-prompt": "Please add datasource" - }, - "details": { - "edit-mode": "Edit mode", - "toggle-edit-mode": "Toggle edit mode" - }, - "device": { - "device": "Device", - "device-required": "Device is required.", - "devices": "Devices", - "management": "Device management", - "view-devices": "View Devices", - "device-alias": "Device alias", - "aliases": "Device aliases", - "no-alias-matching": "'{{alias}}' not found.", - "no-aliases-found": "No aliases found.", - "no-key-matching": "'{{key}}' not found.", - "no-keys-found": "No keys found.", - "create-new-alias": "Create a new one!", - "create-new-key": "Create a new one!", - "duplicate-alias-error": "Duplicate alias found '{{alias}}'.
Device aliases must be unique whithin the dashboard.", - "configure-alias": "Configure '{{alias}}' alias", - "no-devices-matching": "No devices matching '{{entity}}' were found.", - "alias": "Alias", - "alias-required": "Device alias is required.", - "remove-alias": "Remove device alias", - "add-alias": "Add device alias", - "name-starts-with": "Device name starts with", - "device-list": "Device list", - "use-device-name-filter": "Use filter", - "device-list-empty": "No devices selected.", - "device-name-filter-required": "Device name filter is required.", - "device-name-filter-no-device-matched": "No devices starting with '{{device}}' were found.", - "add": "Add Device", - "assign-to-customer": "Assign to customer", - "assign-device-to-customer": "Assign Device(s) To Customer", - "assign-device-to-customer-text": "Please select the devices to assign to the customer", - "make-public": "Make device public", - "make-private": "Make device private", - "no-devices-text": "No devices found", - "assign-to-customer-text": "Please select the customer to assign the device(s)", - "device-details": "Device details", - "add-device-text": "Add new device", - "credentials": "Credentials", - "manage-credentials": "Manage credentials", - "delete": "Delete device", - "assign-devices": "Assign devices", - "assign-devices-text": "Assign { count, select, 1 {1 device} other {# devices} } to customer", - "delete-devices": "Delete devices", - "unassign-from-customer": "Unassign from customer", - "unassign-devices": "Unassign devices", - "unassign-devices-action-title": "Unassign { count, select, 1 {1 device} other {# devices} } from customer", - "assign-new-device": "Assign new device", - "make-public-device-title": "Are you sure you want to make the device '{{deviceName}}' public?", - "make-public-device-text": "After the confirmation the device and all its data will be made public and accessible by others.", - "make-private-device-title": "Are you sure you want to make the device '{{deviceName}}' private?", - "make-private-device-text": "After the confirmation the device and all its data will be made private and won't be accessible by others.", - "view-credentials": "View credentials", - "delete-device-title": "Are you sure you want to delete the device '{{deviceName}}'?", - "delete-device-text": "Be careful, after the confirmation the device and all related data will become unrecoverable.", - "delete-devices-title": "Are you sure you want to delete { count, select, 1 {1 device} other {# devices} }?", - "delete-devices-action-title": "Delete { count, select, 1 {1 device} other {# devices} }", - "delete-devices-text": "Be careful, after the confirmation all selected devices will be removed and all related data will become unrecoverable.", - "unassign-device-title": "Are you sure you want to unassign the device '{{deviceName}}'?", - "unassign-device-text": "After the confirmation the device will be unassigned and won't be accessible by the customer.", - "unassign-device": "Unassign device", - "unassign-devices-title": "Are you sure you want to unassign { count, select, 1 {1 device} other {# devices} }?", - "unassign-devices-text": "After the confirmation all selected devices will be unassigned and won't be accessible by the customer.", - "device-credentials": "Device Credentials", - "credentials-type": "Credentials type", - "access-token": "Access token", - "access-token-required": "Access token is required.", - "access-token-invalid": "Access token length must be from 1 to 20 characters.", - "rsa-key": "RSA public key", - "rsa-key-required": "RSA public key is required.", - "secret": "Secret", - "secret-required": "Secret is required.", - "device-type": "Device type", - "device-type-required": "Device type is required.", - "select-device-type": "Select device type", - "enter-device-type": "Enter device type", - "any-device": "Any device", - "no-device-types-matching": "No device types matching '{{entitySubtype}}' were found.", - "device-type-list-empty": "No device types selected.", - "device-types": "Device types", - "name": "Name", - "name-required": "Name is required.", - "description": "Description", - "events": "Events", - "details": "Details", - "copyId": "Copy device Id", - "copyAccessToken": "Copy access token", - "idCopiedMessage": "Device Id has been copied to clipboard", - "accessTokenCopiedMessage": "Device access token has been copied to clipboard", - "assignedToCustomer": "Assigned to customer", - "unable-delete-device-alias-title": "Unable to delete device alias", - "unable-delete-device-alias-text": "Device alias '{{deviceAlias}}' can't be deleted as it used by the following widget(s):
{{widgetsList}}", - "is-gateway": "Is gateway", - "public": "Public", - "device-public": "Device is public", - "select-device": "Select device" - }, - "dialog": { - "close": "Close dialog" - }, - "error": { - "unable-to-connect": "Unable to connect to the server! Please check your internet connection.", - "unhandled-error-code": "Unhandled error code: {{errorCode}}", - "unknown-error": "Unknown error" - }, - "entity": { - "entity": "Entity", - "entities": "Entities", - "aliases": "Entity aliases", - "entity-alias": "Entity alias", - "unable-delete-entity-alias-title": "Unable to delete entity alias", - "unable-delete-entity-alias-text": "Entity alias '{{entityAlias}}' can't be deleted as it used by the following widget(s):
{{widgetsList}}", - "duplicate-alias-error": "Duplicate alias found '{{alias}}'.
Entity aliases must be unique whithin the dashboard.", - "missing-entity-filter-error": "Filter is missing for alias '{{alias}}'.", - "configure-alias": "Configure '{{alias}}' alias", - "alias": "Alias", - "alias-required": "Entity alias is required.", - "remove-alias": "Remove entity alias", - "add-alias": "Add entity alias", - "entity-list": "Entity list", - "entity-type": "Entity type", - "entity-types": "Entity types", - "entity-type-list": "Entity type list", - "any-entity": "Any entity", - "enter-entity-type": "Enter entity type", - "no-entities-matching": "No entities matching '{{entity}}' were found.", - "no-entity-types-matching": "No entity types matching '{{entityType}}' were found.", - "name-starts-with": "Name starts with", - "use-entity-name-filter": "Use filter", - "entity-list-empty": "No entities selected.", - "entity-type-list-empty": "No entity types selected.", - "entity-name-filter-required": "Entity name filter is required.", - "entity-name-filter-no-entity-matched": "No entities starting with '{{entity}}' were found.", - "all-subtypes": "All", - "select-entities": "Select entities", - "no-aliases-found": "No aliases found.", - "no-alias-matching": "'{{alias}}' not found.", - "create-new-alias": "Create a new one!", - "key": "Key", - "key-name": "Key name", - "no-keys-found": "No keys found.", - "no-key-matching": "'{{key}}' not found.", - "create-new-key": "Create a new one!", - "type": "Type", - "type-required": "Entity type is required.", - "type-device": "Device", - "type-devices": "Devices", - "list-of-devices": "{ count, select, 1 {One device} other {List of # devices} }", - "device-name-starts-with": "Devices whose names start with '{{prefix}}'", - "type-asset": "Asset", - "type-assets": "Assets", - "list-of-assets": "{ count, select, 1 {One asset} other {List of # assets} }", - "asset-name-starts-with": "Assets whose names start with '{{prefix}}'", - "type-rule": "Rule", - "type-rules": "Rules", - "list-of-rules": "{ count, select, 1 {One rule} other {List of # rules} }", - "rule-name-starts-with": "Rules whose names start with '{{prefix}}'", - "type-plugin": "Plugin", - "type-plugins": "Plugins", - "list-of-plugins": "{ count, select, 1 {One plugin} other {List of # plugins} }", - "plugin-name-starts-with": "Plugins whose names start with '{{prefix}}'", - "type-tenant": "Tenant", - "type-tenants": "Tenants", - "list-of-tenants": "{ count, select, 1 {One tenant} other {List of # tenants} }", - "tenant-name-starts-with": "Tenants whose names start with '{{prefix}}'", - "type-customer": "Customer", - "type-customers": "Customers", - "list-of-customers": "{ count, select, 1 {One customer} other {List of # customers} }", - "customer-name-starts-with": "Customers whose names start with '{{prefix}}'", - "type-user": "User", - "type-users": "Users", - "list-of-users": "{ count, select, 1 {One user} other {List of # users} }", - "user-name-starts-with": "Users whose names start with '{{prefix}}'", - "type-dashboard": "Dashboard", - "type-dashboards": "Dashboards", - "list-of-dashboards": "{ count, select, 1 {One dashboard} other {List of # dashboards} }", - "dashboard-name-starts-with": "Dashboards whose names start with '{{prefix}}'", - "type-alarm": "Alarm", - "type-alarms": "Alarms", - "list-of-alarms": "{ count, select, 1 {One alarms} other {List of # alarms} }", - "alarm-name-starts-with": "Alarms whose names start with '{{prefix}}'", - "type-rulechain": "Rule chain", - "type-rulechains": "Rule chains", - "list-of-rulechains": "{ count, select, 1 {One rule chain} other {List of # rule chains} }", - "rulechain-name-starts-with": "Rule chains whose names start with '{{prefix}}'", - "type-current-customer": "Current Customer", - "search": "Search entities", - "selected-entities": "{ count, select, 1 {1 entity} other {# entities} } selected", - "entity-name": "Entity name", - "details": "Entity details", - "no-entities-prompt": "No entities found", - "no-data": "No data to display" - }, - "event": { - "event-type": "Event type", - "type-error": "Error", - "type-lc-event": "Lifecycle event", - "type-stats": "Statistics", - "type-debug-rule-node": "Debug", - "type-debug-rule-chain": "Debug", - "no-events-prompt": "No events found", - "error": "Error", - "alarm": "Alarm", - "event-time": "Event time", - "server": "Server", - "body": "Body", - "method": "Method", - "type": "Type", - "entity": "Entity", - "message-id": "Message Id", - "message-type": "Message Type", - "data-type": "Data Type", - "relation-type": "Relation Type", - "metadata": "Metadata", - "data": "Data", - "event": "Event", - "status": "Status", - "success": "Success", - "failed": "Failed", - "messages-processed": "Messages processed", - "errors-occurred": "Errors occurred" - }, - "extension": { - "extensions": "Extensions", - "selected-extensions": "{ count, select, 1 {1 extension} other {# extensions} } selected", - "type": "Type", - "key": "Key", - "value": "Value", - "id": "Id", - "extension-id": "Extension id", - "extension-type": "Extension type", - "transformer-json": "JSON *", - "unique-id-required": "Current extension id already exists.", - "delete": "Delete extension", - "add": "Add extension", - "edit": "Edit extension", - "delete-extension-title": "Are you sure you want to delete the extension '{{extensionId}}'?", - "delete-extension-text": "Be careful, after the confirmation the extension and all related data will become unrecoverable.", - "delete-extensions-title": "Are you sure you want to delete { count, select, 1 {1 extension} other {# extensions} }?", - "delete-extensions-text": "Be careful, after the confirmation all selected extensions will be removed.", - "converters": "Converters", - "converter-id": "Converter id", - "configuration": "Configuration", - "converter-configurations": "Converter configurations", - "token": "Security token", - "add-converter": "Add converter", - "add-config": "Add converter configuration", - "device-name-expression": "Device name expression", - "device-type-expression": "Device type expression", - "custom": "Custom", - "to-double": "To Double", - "transformer": "Transformer", - "json-required": "Transformer json is required.", - "json-parse": "Unable to parse transformer json.", - "attributes": "Attributes", - "add-attribute": "Add attribute", - "add-map": "Add mapping element", - "timeseries": "Timeseries", - "add-timeseries": "Add timeseries", - "field-required": "Field is required", - "brokers": "Brokers", - "add-broker": "Add broker", - "host": "Host", - "port": "Port", - "port-range": "Port should be in a range from 1 to 65535.", - "ssl": "Ssl", - "credentials": "Credentials", - "username": "Username", - "password": "Password", - "retry-interval": "Retry interval in milliseconds", - "anonymous": "Anonymous", - "basic": "Basic", - "pem": "PEM", - "ca-cert": "CA certificate file *", - "private-key": "Private key file *", - "cert": "Certificate file *", - "no-file": "No file selected.", - "drop-file": "Drop a file or click to select a file to upload.", - "mapping": "Mapping", - "topic-filter": "Topic filter", - "converter-type": "Converter type", - "converter-json": "Json", - "json-name-expression": "Device name json expression", - "topic-name-expression": "Device name topic expression", - "json-type-expression": "Device type json expression", - "topic-type-expression": "Device type topic expression", - "attribute-key-expression": "Attribute key expression", - "attr-json-key-expression": "Attribute key json expression", - "attr-topic-key-expression": "Attribute key topic expression", - "request-id-expression": "Request id expression", - "request-id-json-expression": "Request id json expression", - "request-id-topic-expression": "Request id topic expression", - "response-topic-expression": "Response topic expression", - "value-expression": "Value expression", - "topic": "Topic", - "timeout": "Timeout in milliseconds", - "converter-json-required": "Converter json is required.", - "converter-json-parse": "Unable to parse converter json.", - "filter-expression": "Filter expression", - "connect-requests": "Connect requests", - "add-connect-request": "Add connect request", - "disconnect-requests": "Disconnect requests", - "add-disconnect-request": "Add disconnect request", - "attribute-requests": "Attribute requests", - "add-attribute-request": "Add attribute request", - "attribute-updates": "Attribute updates", - "add-attribute-update": "Add attribute update", - "server-side-rpc": "Server side RPC", - "add-server-side-rpc-request": "Add server-side RPC request", - "device-name-filter": "Device name filter", - "attribute-filter": "Attribute filter", - "method-filter": "Method filter", - "request-topic-expression": "Request topic expression", - "response-timeout": "Response timeout in milliseconds", - "topic-expression": "Topic expression", - "client-scope": "Client scope", - "add-device": "Add device", - "opc-server": "Servers", - "opc-add-server": "Add server", - "opc-add-server-prompt": "Please add server", - "opc-application-name": "Application name", - "opc-application-uri": "Application uri", - "opc-scan-period-in-seconds": "Scan period in seconds", - "opc-security": "Security", - "opc-identity": "Identity", - "opc-keystore": "Keystore", - "opc-type": "Type", - "opc-keystore-type": "Type", - "opc-keystore-location": "Location *", - "opc-keystore-password": "Password", - "opc-keystore-alias": "Alias", - "opc-keystore-key-password": "Key password", - "opc-device-node-pattern": "Device node pattern", - "opc-device-name-pattern": "Device name pattern", - "modbus-server": "Servers/slaves", - "modbus-add-server": "Add server/slave", - "modbus-add-server-prompt": "Please add server/slave", - "modbus-transport": "Transport", - "modbus-port-name": "Serial port name", - "modbus-encoding": "Encoding", - "modbus-parity": "Parity", - "modbus-baudrate": "Baud rate", - "modbus-databits": "Data bits", - "modbus-stopbits": "Stop bits", - "modbus-databits-range": "Data bits should be in a range from 7 to 8.", - "modbus-stopbits-range": "Stop bits should be in a range from 1 to 2.", - "modbus-unit-id": "Unit ID", - "modbus-unit-id-range": "Unit ID should be in a range from 1 to 247.", - "modbus-device-name": "Device name", - "modbus-poll-period": "Poll period (ms)", - "modbus-attributes-poll-period": "Attributes poll period (ms)", - "modbus-timeseries-poll-period": "Timeseries poll period (ms)", - "modbus-poll-period-range": "Poll period should be positive value.", - "modbus-tag": "Tag", - "modbus-function": "Function", - "modbus-register-address": "Register address", - "modbus-register-address-range": "Register address should be in a range from 0 to 65535.", - "modbus-register-bit-index": "Bit index", - "modbus-register-bit-index-range": "Bit index should be in a range from 0 to 15.", - "modbus-register-count": "Register count", - "modbus-register-count-range": "Register count should be a positive value.", - "modbus-byte-order": "Byte order", - - "sync": { - "status": "Status", - "sync": "Sync", - "not-sync": "Not sync", - "last-sync-time": "Last sync time", - "not-available": "Not available" - }, - - "export-extensions-configuration": "Export extensions configuration", - "import-extensions-configuration": "Import extensions configuration", - "import-extensions": "Import extensions", - "import-extension": "Import extension", - "export-extension": "Export extension", - "file": "Extensions file", - "invalid-file-error": "Invalid extension file" - }, - "fullscreen": { - "expand": "Expand to fullscreen", - "exit": "Exit fullscreen", - "toggle": "Toggle fullscreen mode", - "fullscreen": "Fullscreen" - }, - "function": { - "function": "Function" - }, - "grid": { - "delete-item-title": "Are you sure you want to delete this item?", - "delete-item-text": "Be careful, after the confirmation this item and all related data will become unrecoverable.", - "delete-items-title": "Are you sure you want to delete { count, select, 1 {1 item} other {# items} }?", - "delete-items-action-title": "Delete { count, select, 1 {1 item} other {# items} }", - "delete-items-text": "Be careful, after the confirmation all selected items will be removed and all related data will become unrecoverable.", - "add-item-text": "Add new item", - "no-items-text": "No items found", - "item-details": "Item details", - "delete-item": "Delete Item", - "delete-items": "Delete Items", - "scroll-to-top": "Scroll to top" - }, - "help": { - "goto-help-page": "Go to help page" - }, - "home": { - "home": "Home", - "profile": "Profile", - "logout": "Logout", - "menu": "Menu", - "avatar": "Avatar", - "open-user-menu": "Open user menu" - }, - "import": { - "no-file": "No file selected", - "drop-file": "Drop a JSON file or click to select a file to upload." - }, - "item": { - "selected": "Selected" - }, - "js-func": { - "no-return-error": "Function must return value!", - "return-type-mismatch": "Function must return value of '{{type}}' type!", - "tidy": "Tidy" - }, - "key-val": { - "key": "Key", - "value": "Value", - "remove-entry": "Remove entry", - "add-entry": "Add entry", - "no-data": "No entries" - }, - "layout": { - "layout": "Layout", - "manage": "Manage layouts", - "settings": "Layout settings", - "color": "Color", - "main": "Main", - "right": "Right", - "select": "Select target layout" - }, - "legend": { - "position": "Legend position", - "show-max": "Show max value", - "show-min": "Show min value", - "show-avg": "Show average value", - "show-total": "Show total value", - "settings": "Legend settings", - "min": "min", - "max": "max", - "avg": "avg", - "total": "total" - }, - "login": { - "login": "Login", - "request-password-reset": "Request Password Reset", - "reset-password": "Reset Password", - "create-password": "Create Password", - "passwords-mismatch-error": "Entered passwords must be same!", - "password-again": "Password again", - "sign-in": "Please sign in", - "username": "Username (email)", - "remember-me": "Remember me", - "forgot-password": "Forgot Password?", - "password-reset": "Password reset", - "new-password": "New password", - "new-password-again": "New password again", - "password-link-sent-message": "Password reset link was successfully sent!", - "email": "Email" - }, - "position": { - "top": "Top", - "bottom": "Bottom", - "left": "Left", - "right": "Right" - }, - "profile": { - "profile": "Profile", - "change-password": "Change Password", - "current-password": "Current password" - }, - "relation": { - "relations": "Relations", - "direction": "Direction", - "search-direction": { - "FROM": "From", - "TO": "To" - }, - "direction-type": { - "FROM": "from", - "TO": "to" - }, - "from-relations": "Outbound relations", - "to-relations": "Inbound relations", - "selected-relations": "{ count, select, 1 {1 relation} other {# relations} } selected", - "type": "Type", - "to-entity-type": "To entity type", - "to-entity-name": "To entity name", - "from-entity-type": "From entity type", - "from-entity-name": "From entity name", - "to-entity": "To entity", - "from-entity": "From entity", - "delete": "Delete relation", - "relation-type": "Relation type", - "relation-type-required": "Relation type is required.", - "any-relation-type": "Any type", - "add": "Add relation", - "edit": "Edit relation", - "delete-to-relation-title": "Are you sure you want to delete relation to the entity '{{entityName}}'?", - "delete-to-relation-text": "Be careful, after the confirmation the entity '{{entityName}}' will be unrelated from the current entity.", - "delete-to-relations-title": "Are you sure you want to delete { count, select, 1 {1 relation} other {# relations} }?", - "delete-to-relations-text": "Be careful, after the confirmation all selected relations will be removed and corresponding entities will be unrelated from the current entity.", - "delete-from-relation-title": "Are you sure you want to delete relation from the entity '{{entityName}}'?", - "delete-from-relation-text": "Be careful, after the confirmation current entity will be unrelated from the entity '{{entityName}}'.", - "delete-from-relations-title": "Are you sure you want to delete { count, select, 1 {1 relation} other {# relations} }?", - "delete-from-relations-text": "Be careful, after the confirmation all selected relations will be removed and current entity will be unrelated from the corresponding entities.", - "remove-relation-filter": "Remove relation filter", - "add-relation-filter": "Add relation filter", - "any-relation": "Any relation", - "relation-filters": "Relation filters", - "additional-info": "Additional info (JSON)", - "invalid-additional-info": "Unable to parse additional info json." - }, - "rulechain": { - "rulechain": "Rule chain", - "rulechains": "Rule chains", - "root": "Root", - "delete": "Delete rule chain", - "name": "Name", - "name-required": "Name is required.", - "description": "Description", - "add": "Add Rule Chain", - "set-root": "Make rule chain root", - "set-root-rulechain-title": "Are you sure you want to make the rule chain '{{ruleChainName}}' root?", - "set-root-rulechain-text": "After the confirmation the rule chain will become root and will handle all incoming transport messages.", - "delete-rulechain-title": "Are you sure you want to delete the rule chain '{{ruleChainName}}'?", - "delete-rulechain-text": "Be careful, after the confirmation the rule chain and all related data will become unrecoverable.", - "delete-rulechains-title": "Are you sure you want to delete { count, select, 1 {1 rule chain} other {# rule chains} }?", - "delete-rulechains-action-title": "Delete { count, select, 1 {1 rule chain} other {# rule chains} }", - "delete-rulechains-text": "Be careful, after the confirmation all selected rule chains will be removed and all related data will become unrecoverable.", - "add-rulechain-text": "Add new rule chain", - "no-rulechains-text": "No rule chains found", - "rulechain-details": "Rule chain details", - "details": "Details", - "events": "Events", - "system": "System", - "import": "Import rule chain", - "export": "Export rule chain", - "export-failed-error": "Unable to export rule chain: {{error}}", - "create-new-rulechain": "Create new rule chain", - "rulechain-file": "Rule chain file", - "invalid-rulechain-file-error": "Unable to import rule chain: Invalid rule chain data structure.", - "copyId": "Copy rule chain Id", - "idCopiedMessage": "Rule chain Id has been copied to clipboard", - "select-rulechain": "Select rule chain", - "no-rulechains-matching": "No rule chains matching '{{entity}}' were found.", - "rulechain-required": "Rule chain is required", - "management": "Rules management", - "debug-mode": "Debug mode" - }, - "rulenode": { - "details": "Details", - "events": "Events", - "search": "Search nodes", - "open-node-library": "Open node library", - "add": "Add rule node", - "name": "Name", - "name-required": "Name is required.", - "type": "Type", - "description": "Description", - "delete": "Delete rule node", - "select-all-objects": "Select all nodes and connections", - "deselect-all-objects": "Deselect all nodes and connections", - "delete-selected-objects": "Delete selected nodes and connections", - "delete-selected": "Delete selected", - "select-all": "Select all", - "copy-selected": "Copy selected", - "deselect-all": "Deselect all", - "rulenode-details": "Rule node details", - "debug-mode": "Debug mode", - "configuration": "Configuration", - "link": "Link", - "link-details": "Rule node link details", - "add-link": "Add link", - "link-label": "Link label", - "link-label-required": "Link label is required.", - "custom-link-label": "Custom link label", - "custom-link-label-required": "Custom link label is required.", - "type-filter": "Filter", - "type-filter-details": "Filter incoming messages with configured conditions", - "type-enrichment": "Enrichment", - "type-enrichment-details": "Add additional information into Message Metadata", - "type-transformation": "Transformation", - "type-transformation-details": "Change Message payload and Metadata", - "type-action": "Action", - "type-action-details": "Perform special action", - "type-external": "External", - "type-external-details": "Interacts with external system", - "type-rule-chain": "Rule Chain", - "type-rule-chain-details": "Forwards incoming messages to specified Rule Chain", - "type-input": "Input", - "type-input-details": "Logical input of Rule Chain, forwards incoming messages to next related Rule Node", - "directive-is-not-loaded": "Defined configuration directive '{{directiveName}}' is not available.", - "ui-resources-load-error": "Failed to load configuration ui resources.", - "invalid-target-rulechain": "Unable to resolve target rule chain!", - "test-script-function": "Test script function", - "message": "Message", - "message-type": "Message type", - "message-type-required": "Message type is required", - "metadata": "Metadata", - "metadata-required": "Metadata entries can't be empty.", - "output": "Output", - "test": "Test", - "help": "Help" - }, - "tenant": { - "tenant": "Tenant", - "tenants": "Tenants", - "management": "Tenant management", - "add": "Add Tenant", - "admins": "Admins", - "manage-tenant-admins": "Manage tenant admins", - "delete": "Delete tenant", - "add-tenant-text": "Add new tenant", - "no-tenants-text": "No tenants found", - "tenant-details": "Tenant details", - "delete-tenant-title": "Are you sure you want to delete the tenant '{{tenantTitle}}'?", - "delete-tenant-text": "Be careful, after the confirmation the tenant and all related data will become unrecoverable.", - "delete-tenants-title": "Are you sure you want to delete { count, select, 1 {1 tenant} other {# tenants} }?", - "delete-tenants-action-title": "Delete { count, select, 1 {1 tenant} other {# tenants} }", - "delete-tenants-text": "Be careful, after the confirmation all selected tenants will be removed and all related data will become unrecoverable.", - "title": "Title", - "title-required": "Title is required.", - "description": "Description", - "details": "Details", - "events": "Events", - "copyId": "Copy tenant Id", - "idCopiedMessage": "Tenant Id has been copied to clipboard", - "select-tenant": "Select tenant", - "no-tenants-matching": "No tenants matching '{{entity}}' were found.", - "tenant-required": "Tenant is required" - }, - "timeinterval": { - "seconds-interval": "{ seconds, select, 1 {1 second} other {# seconds} }", - "minutes-interval": "{ minutes, select, 1 {1 minute} other {# minutes} }", - "hours-interval": "{ hours, select, 1 {1 hour} other {# hours} }", - "days-interval": "{ days, select, 1 {1 day} other {# days} }", - "days": "Days", - "hours": "Hours", - "minutes": "Minutes", - "seconds": "Seconds", - "advanced": "Advanced" - }, - "timewindow": { - "days": "{ days, select, 1 { day } other {# days } }", - "hours": "{ hours, select, 0 { hour } 1 {1 hour } other {# hours } }", - "minutes": "{ minutes, select, 0 { minute } 1 {1 minute } other {# minutes } }", - "seconds": "{ seconds, select, 0 { second } 1 {1 second } other {# seconds } }", - "realtime": "Realtime", - "history": "History", - "last-prefix": "last", - "period": "from {{ startTime }} to {{ endTime }}", - "edit": "Edit timewindow", - "date-range": "Date range", - "last": "Last", - "time-period": "Time period" - }, - "user": { - "user": "User", - "users": "Users", - "customer-users": "Customer Users", - "tenant-admins": "Tenant Admins", - "sys-admin": "System administrator", - "tenant-admin": "Tenant administrator", - "customer": "Customer", - "anonymous": "Anonymous", - "add": "Add User", - "delete": "Delete user", - "add-user-text": "Add new user", - "no-users-text": "No users found", - "user-details": "User details", - "delete-user-title": "Are you sure you want to delete the user '{{userEmail}}'?", - "delete-user-text": "Be careful, after the confirmation the user and all related data will become unrecoverable.", - "delete-users-title": "Are you sure you want to delete { count, select, 1 {1 user} other {# users} }?", - "delete-users-action-title": "Delete { count, select, 1 {1 user} other {# users} }", - "delete-users-text": "Be careful, after the confirmation all selected users will be removed and all related data will become unrecoverable.", - "activation-email-sent-message": "Activation email was successfully sent!", - "resend-activation": "Resend activation", - "email": "Email", - "email-required": "Email is required.", - "invalid-email-format": "Invalid email format.", - "first-name": "First Name", - "last-name": "Last Name", - "description": "Description", - "default-dashboard": "Default dashboard", - "always-fullscreen": "Always fullscreen", - "select-user": "Select user", - "no-users-matching": "No users matching '{{entity}}' were found.", - "user-required": "User is required", - "activation-method": "Activation method", - "display-activation-link": "Display activation link", - "send-activation-mail": "Send activation mail", - "activation-link": "User activation link", - "activation-link-text": "In order to activate user use the following activation link :", - "copy-activation-link": "Copy activation link", - "activation-link-copied-message": "User activation link has been copied to clipboard", - "details": "Details" - }, - "value": { - "type": "Value type", - "string": "String", - "string-value": "String value", - "integer": "Integer", - "integer-value": "Integer value", - "invalid-integer-value": "Invalid integer value", - "double": "Double", - "double-value": "Double value", - "boolean": "Boolean", - "boolean-value": "Boolean value", - "false": "False", - "true": "True", - "long": "Long" - }, - "widget": { - "widget-library": "Widgets Library", - "widget-bundle": "Widgets Bundle", - "select-widgets-bundle": "Select widgets bundle", - "management": "Widget management", - "editor": "Widget Editor", - "widget-type-not-found": "Problem loading widget configuration.
Probably associated\n widget type was removed.", - "widget-type-load-error": "Widget wasn't loaded due to the following errors:", - "remove": "Remove widget", - "edit": "Edit widget", - "remove-widget-title": "Are you sure you want to remove the widget '{{widgetTitle}}'?", - "remove-widget-text": "After the confirmation the widget and all related data will become unrecoverable.", - "timeseries": "Time series", - "search-data": "Search data", - "no-data-found": "No data found", - "latest-values": "Latest values", - "rpc": "Control widget", - "alarm": "Alarm widget", - "static": "Static widget", - "select-widget-type": "Select widget type", - "missing-widget-title-error": "Widget title must be specified!", - "widget-saved": "Widget saved", - "unable-to-save-widget-error": "Unable to save widget! Widget has errors!", - "save": "Save widget", - "saveAs": "Save widget as", - "save-widget-type-as": "Save widget type as", - "save-widget-type-as-text": "Please enter new widget title and/or select target widgets bundle", - "toggle-fullscreen": "Toggle fullscreen", - "run": "Run widget", - "title": "Widget title", - "title-required": "Widget title is required.", - "type": "Widget type", - "resources": "Resources", - "resource-url": "JavaScript/CSS URL", - "remove-resource": "Remove resource", - "add-resource": "Add resource", - "html": "HTML", - "tidy": "Tidy", - "css": "CSS", - "settings-schema": "Settings schema", - "datakey-settings-schema": "Data key settings schema", - "javascript": "Javascript", - "remove-widget-type-title": "Are you sure you want to remove the widget type '{{widgetName}}'?", - "remove-widget-type-text": "After the confirmation the widget type and all related data will become unrecoverable.", - "remove-widget-type": "Remove widget type", - "add-widget-type": "Add new widget type", - "widget-type-load-failed-error": "Failed to load widget type!", - "widget-template-load-failed-error": "Failed to load widget template!", - "add": "Add Widget", - "undo": "Undo widget changes", - "export": "Export widget" - }, - "widget-action": { - "header-button": "Widget header button", - "open-dashboard-state": "Navigate to new dashboard state", - "update-dashboard-state": "Update current dashboard state", - "open-dashboard": "Navigate to other dashboard", - "custom": "Custom action", - "target-dashboard-state": "Target dashboard state", - "target-dashboard-state-required": "Target dashboard state is required", - "set-entity-from-widget": "Set entity from widget", - "target-dashboard": "Target dashboard", - "open-right-layout": "Open right dashboard layout (mobile view)" - }, - "widgets-bundle": { - "current": "Current bundle", - "widgets-bundles": "Widgets Bundles", - "add": "Add Widgets Bundle", - "delete": "Delete widgets bundle", - "title": "Title", - "title-required": "Title is required.", - "add-widgets-bundle-text": "Add new widgets bundle", - "no-widgets-bundles-text": "No widgets bundles found", - "empty": "Widgets bundle is empty", - "details": "Details", - "widgets-bundle-details": "Widgets bundle details", - "delete-widgets-bundle-title": "Are you sure you want to delete the widgets bundle '{{widgetsBundleTitle}}'?", - "delete-widgets-bundle-text": "Be careful, after the confirmation the widgets bundle and all related data will become unrecoverable.", - "delete-widgets-bundles-title": "Are you sure you want to delete { count, select, 1 {1 widgets bundle} other {# widgets bundles} }?", - "delete-widgets-bundles-action-title": "Delete { count, select, 1 {1 widgets bundle} other {# widgets bundles} }", - "delete-widgets-bundles-text": "Be careful, after the confirmation all selected widgets bundles will be removed and all related data will become unrecoverable.", - "no-widgets-bundles-matching": "No widgets bundles matching '{{widgetsBundle}}' were found.", - "widgets-bundle-required": "Widgets bundle is required.", - "system": "System", - "import": "Import widgets bundle", - "export": "Export widgets bundle", - "export-failed-error": "Unable to export widgets bundle: {{error}}", - "create-new-widgets-bundle": "Create new widgets bundle", - "widgets-bundle-file": "Widgets bundle file", - "invalid-widgets-bundle-file-error": "Unable to import widgets bundle: Invalid widgets bundle data structure." - }, - "widget-config": { - "data": "Data", - "settings": "Settings", - "advanced": "Advanced", - "title": "Title", - "general-settings": "General settings", - "display-title": "Display title", - "drop-shadow": "Drop shadow", - "enable-fullscreen": "Enable fullscreen", - "background-color": "Background color", - "text-color": "Text color", - "padding": "Padding", - "margin": "Margin", - "widget-style": "Widget style", - "title-style": "Title style", - "mobile-mode-settings": "Mobile mode settings", - "order": "Order", - "height": "Height", - "units": "Special symbol to show next to value", - "decimals": "Number of digits after floating point", - "timewindow": "Timewindow", - "use-dashboard-timewindow": "Use dashboard timewindow", - "display-legend": "Display legend", - "datasources": "Datasources", - "maximum-datasources": "Maximum { count, select, 1 {1 datasource is allowed.} other {# datasources are allowed} }", - "datasource-type": "Type", - "datasource-parameters": "Parameters", - "remove-datasource": "Remove datasource", - "add-datasource": "Add datasource", - "target-device": "Target device", - "alarm-source": "Alarm source", - "actions": "Actions", - "action": "Action", - "add-action": "Add action", - "search-actions": "Search actions", - "action-source": "Action source", - "action-source-required": "Action source is required.", - "action-name": "Name", - "action-name-required": "Action name is required.", - "action-name-not-unique": "Another action with the same name already exists.
Action name should be unique within the same action source.", - "action-icon": "Icon", - "action-type": "Type", - "action-type-required": "Action type is required.", - "edit-action": "Edit action", - "delete-action": "Delete action", - "delete-action-title": "Delete widget action", - "delete-action-text": "Are you sure you want delete widget action with name '{{actionName}}'?" - }, - "widget-type": { - "import": "Import widget type", - "export": "Export widget type", - "export-failed-error": "Unable to export widget type: {{error}}", - "create-new-widget-type": "Create new widget type", - "widget-type-file": "Widget type file", - "invalid-widget-type-file-error": "Unable to import widget type: Invalid widget type data structure." - }, - "icon": { - "icon": "Icon", - "select-icon": "Select icon", - "material-icons": "Material icons", - "show-all": "Show all icons" - }, - "custom": { - "widget-action": { - "action-cell-button": "Action cell button", - "row-click": "On row click", - "marker-click": "On marker click", - "tooltip-tag-action": "Tooltip tag action" - } - }, - "language": { - "language": "Language", - "en_US": "English", - "ko_KR": "Korean", - "zh_CN": "Chinese", - "ru_RU": "Russian", - "es_ES": "Spanish" - } - } - } - ).name; diff --git a/ui/src/app/locale/translate-handler.js b/ui/src/app/locale/translate-handler.js index 11feb00d62..9fb28f5cf2 100644 --- a/ui/src/app/locale/translate-handler.js +++ b/ui/src/app/locale/translate-handler.js @@ -13,8 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + export default angular.module('thingsboard.locale', []) + .factory('tbMissingTranslationHandler', ThingsboardMissingTranslateHandler) + .name; + /*@ngInject*/ -export default function ThingsboardMissingTranslateHandler($log, types) { +function ThingsboardMissingTranslateHandler($log, types) { return function (translationId) { if (translationId && !translationId.startsWith(types.translate.customTranslationsPrefix)) { diff --git a/ui/src/app/profile/profile.controller.js b/ui/src/app/profile/profile.controller.js index d17a65a0e5..b947bde054 100644 --- a/ui/src/app/profile/profile.controller.js +++ b/ui/src/app/profile/profile.controller.js @@ -24,16 +24,9 @@ export default function ProfileController(userService, $scope, $document, $mdDia var vm = this; vm.profileUser = {}; - vm.save = save; vm.changePassword = changePassword; - vm.languageList = { - en_US: {value : "en_US", name: "language.en_US"}, - ko_KR: {value : "ko_KR", name: "language.ko_KR"}, - zh_CN: {value : "zh_CN", name: "language.zh_CN"}, - ru_RU: {value : "ru_RU", name: "language.ru_RU"}, - es_ES: {value : "es_ES", name: "language.es_ES"}, - }; + vm.languageList = SUPPORTED_LANGS; //eslint-disable-line loadProfile(); diff --git a/ui/src/app/profile/profile.tpl.html b/ui/src/app/profile/profile.tpl.html index a0358c15e4..26d992547f 100644 --- a/ui/src/app/profile/profile.tpl.html +++ b/ui/src/app/profile/profile.tpl.html @@ -43,8 +43,8 @@ - - {{lang.name | translate}} + + {{ lang ? ('language.locales.' + lang | translate) : ''}} diff --git a/ui/src/app/rulechain/add-link.tpl.html b/ui/src/app/rulechain/add-link.tpl.html index 0a21104e76..c5855b7738 100644 --- a/ui/src/app/rulechain/add-link.tpl.html +++ b/ui/src/app/rulechain/add-link.tpl.html @@ -31,7 +31,7 @@
- +
diff --git a/ui/src/app/rulechain/index.js b/ui/src/app/rulechain/index.js index 7740dd0669..1ed3680b12 100644 --- a/ui/src/app/rulechain/index.js +++ b/ui/src/app/rulechain/index.js @@ -23,6 +23,7 @@ import RuleNodeDefinedConfigDirective from './rulenode-defined-config.directive' import RuleNodeConfigDirective from './rulenode-config.directive'; import RuleNodeDirective from './rulenode.directive'; import LinkDirective from './link.directive'; +import MessageTypeAutocompleteDirective from './message-type-autocomplete.directive'; import NodeScriptTest from './script/node-script-test.service'; export default angular.module('thingsboard.ruleChain', []) @@ -37,5 +38,6 @@ export default angular.module('thingsboard.ruleChain', []) .directive('tbRuleNodeConfig', RuleNodeConfigDirective) .directive('tbRuleNode', RuleNodeDirective) .directive('tbRuleNodeLink', LinkDirective) + .directive('tbMessageTypeAutocomplete', MessageTypeAutocompleteDirective) .factory('ruleNodeScriptTest', NodeScriptTest) .name; diff --git a/ui/src/app/rulechain/link-fieldset.tpl.html b/ui/src/app/rulechain/link-fieldset.tpl.html index 13ec6c3ce8..e74542fc03 100644 --- a/ui/src/app/rulechain/link-fieldset.tpl.html +++ b/ui/src/app/rulechain/link-fieldset.tpl.html @@ -17,23 +17,44 @@ -->
- - - - - {{label.name}} - - -
-
rulenode.link-label-required
-
-
- - - -
-
rulenode.custom-link-label-required
-
-
+ + + + {{item}} + +
+
+ rulenode.no-link-labels-found +
+
+ rulenode.no-link-label-matching + + rulenode.create-new-link-label + +
+
+
+
+ + {{$chip.name}} + +
+
diff --git a/ui/src/app/rulechain/link.directive.js b/ui/src/app/rulechain/link.directive.js index b3565a3954..40c7a61dc7 100644 --- a/ui/src/app/rulechain/link.directive.js +++ b/ui/src/app/rulechain/link.directive.js @@ -14,6 +14,8 @@ * limitations under the License. */ +import './link.scss'; + /* eslint-disable import/no-unresolved, import/default */ import linkFieldsetTemplate from './link-fieldset.tpl.html'; @@ -22,50 +24,109 @@ import linkFieldsetTemplate from './link-fieldset.tpl.html'; /*@ngInject*/ export default function LinkDirective($compile, $templateCache, $filter) { - var linker = function (scope, element) { + var linker = function (scope, element, attrs, ngModelCtrl) { var template = $templateCache.get(linkFieldsetTemplate); element.html(template); scope.selectedLabel = null; + scope.labelSearchText = null; + + scope.ngModelCtrl = ngModelCtrl; + + var labelsList = []; + + scope.transformLinkLabelChip = function (chip) { + var res = $filter('filter')(labelsList, {name: chip}, true); + var result; + if (res && res.length) { + result = angular.copy(res[0]); + } else { + result = { + name: chip, + value: chip + }; + } + return result; + }; + + scope.labelsSearch = function (searchText) { + var labels = searchText ? $filter('filter')(labelsList, {name: searchText}) : labelsList; + return labels.map((label) => label.name); + }; + + scope.createLinkLabel = function (event, chipsId) { + var chipsChild = angular.element(chipsId, element)[0].firstElementChild; + var el = angular.element(chipsChild); + var chipBuffer = el.scope().$mdChipsCtrl.getChipBuffer(); + event.preventDefault(); + event.stopPropagation(); + el.scope().$mdChipsCtrl.appendChip(chipBuffer.trim()); + el.scope().$mdChipsCtrl.resetChipBuffer(); + }; - scope.$watch('link', function() { - scope.selectedLabel = null; - if (scope.link && scope.labels) { - if (scope.link.label) { - var result = $filter('filter')(scope.labels, {name: scope.link.label}); - if (result && result.length) { - scope.selectedLabel = result[0]; - } else { - result = $filter('filter')(scope.labels, {custom: true}); - if (result && result.length && result[0].custom) { - scope.selectedLabel = result[0]; - } - } - } - } - }); - - scope.selectedLabelChanged = function() { - if (scope.link && scope.selectedLabel) { - if (!scope.selectedLabel.custom) { - scope.link.label = scope.selectedLabel.name; - } else { - scope.link.label = ""; + + ngModelCtrl.$render = function () { + labelsList.length = 0; + for (var label in scope.allowedLabels) { + var linkLabel = { + name: scope.allowedLabels[label].name, + value: scope.allowedLabels[label].value + }; + labelsList.push(linkLabel); + } + + var link = ngModelCtrl.$viewValue; + var labels = []; + if (link && link.labels) { + for (var i = 0; i < link.labels.length; i++) { + label = link.labels[i]; + if (scope.allowedLabels[label]) { + labels.push(angular.copy(scope.allowedLabels[label])); + } else { + labels.push({ + name: label, + value: label + }); + } } } + scope.labels = labels; + scope.$watch('labels', function (newVal, prevVal) { + if (!angular.equals(newVal, prevVal)) { + updateLabels(); + } + }, true); }; + function updateLabels() { + if (ngModelCtrl.$viewValue) { + var labels = []; + for (var i = 0; i < scope.labels.length; i++) { + labels.push(scope.labels[i].value); + } + ngModelCtrl.$viewValue.labels = labels; + ngModelCtrl.$viewValue.label = labels.join(' / '); + updateValidity(); + } + } + + function updateValidity() { + var valid = ngModelCtrl.$viewValue.labels && + ngModelCtrl.$viewValue.labels.length ? true : false; + ngModelCtrl.$setValidity('linkLabels', valid); + } + $compile(element.contents())(scope); } return { restrict: "E", + require: "^ngModel", link: linker, scope: { - link: '=', - labels: '=', + allowedLabels: '=', + allowCustom: '=', isEdit: '=', - isReadOnly: '=', - theForm: '=' + isReadOnly: '=' } }; } diff --git a/ui/src/app/rulechain/link.scss b/ui/src/app/rulechain/link.scss new file mode 100644 index 0000000000..3e8661915b --- /dev/null +++ b/ui/src/app/rulechain/link.scss @@ -0,0 +1,30 @@ +/** + * Copyright © 2016-2018 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +.tb-link-label-autocomplete { + .tb-not-found { + display: block; + line-height: 1.5; + height: 48px; + .tb-no-entries { + line-height: 48px; + } + } + li { + height: auto !important; + white-space: normal !important; + } +} diff --git a/ui/src/app/rulechain/message-type-autocomplete.directive.js b/ui/src/app/rulechain/message-type-autocomplete.directive.js new file mode 100644 index 0000000000..afa5e35b0a --- /dev/null +++ b/ui/src/app/rulechain/message-type-autocomplete.directive.js @@ -0,0 +1,100 @@ +/* + * Copyright © 2016-2018 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import './message-type-autocomplete.scss'; + +/* eslint-disable import/no-unresolved, import/default */ + +import messageTypeAutocompleteTemplate from './message-type-autocomplete.tpl.html'; + +/* eslint-enable import/no-unresolved, import/default */ + +/*@ngInject*/ +export default function MessageTypeAutocomplete($compile, $templateCache, $q, $filter, types) { + + var linker = function (scope, element, attrs, ngModelCtrl) { + var template = $templateCache.get(messageTypeAutocompleteTemplate); + element.html(template); + + var messageTypeList = []; + for (var t in types.messageType) { + var type = types.messageType[t]; + messageTypeList.push(type); + } + + scope.messageType = null; + scope.messageTypeSearchText = ''; + + scope.fetchMessageTypes = function(searchText) { + var deferred = $q.defer(); + var result = $filter('filter')(messageTypeList, {'name': searchText}); + if (result && result.length) { + deferred.resolve(result); + } else { + deferred.resolve([{name: searchText, value: searchText}]); + } + return deferred.promise; + }; + + scope.messageTypeSearchTextChanged = function() { + }; + + scope.updateView = function () { + if (!scope.disabled) { + var value = null; + if (scope.messageType) { + value = scope.messageType.value; + } + ngModelCtrl.$setViewValue(value); + } + }; + + ngModelCtrl.$render = function () { + var value = ngModelCtrl.$viewValue; + if (value) { + var result = $filter('filter')(messageTypeList, {'value': value}, true); + if (result && result.length) { + scope.messageType = result[0]; + } else { + scope.messageType = { + name: value, + value: value + }; + } + } else { + scope.messageType = null; + } + }; + + scope.$watch('messageType', function (newValue, prevValue) { + if (!angular.equals(newValue, prevValue)) { + scope.updateView(); + } + }); + + $compile(element.contents())(scope); + } + + return { + restrict: "E", + require: "^ngModel", + link: linker, + scope: { + theForm: '=?', + disabled:'=ngDisabled', + required:'=ngRequired' + } + }; +} diff --git a/ui/src/app/rulechain/message-type-autocomplete.scss b/ui/src/app/rulechain/message-type-autocomplete.scss new file mode 100644 index 0000000000..4cad9cb17b --- /dev/null +++ b/ui/src/app/rulechain/message-type-autocomplete.scss @@ -0,0 +1,25 @@ +/** + * Copyright © 2016-2018 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +.tb-message-type-autocomplete { + .tb-message-type-item { + display: block; + height: 48px; + } + li { + height: auto !important; + white-space: normal !important; + } +} diff --git a/ui/src/app/rulechain/message-type-autocomplete.tpl.html b/ui/src/app/rulechain/message-type-autocomplete.tpl.html new file mode 100644 index 0000000000..bb3e71f8da --- /dev/null +++ b/ui/src/app/rulechain/message-type-autocomplete.tpl.html @@ -0,0 +1,41 @@ + + + +
+ {{item.name}} +
+
+
+
rulenode.message-type-required
+
+
diff --git a/ui/src/app/rulechain/rulechain.controller.js b/ui/src/app/rulechain/rulechain.controller.js index dfd1a971e8..a38f8a8a03 100644 --- a/ui/src/app/rulechain/rulechain.controller.js +++ b/ui/src/app/rulechain/rulechain.controller.js @@ -669,11 +669,15 @@ export function RuleChainController($state, $scope, $compile, $q, $mdUtil, $time } } else { if (edge.label) { + if (!edge.labels) { + edge.labels = edge.label.split(' / '); + } deferred.resolve(edge); } else { var labels = ruleChainService.getRuleNodeSupportedLinks(sourceNode.component); + var allowCustomLabels = ruleChainService.ruleNodeAllowCustomLinks(sourceNode.component); vm.enableHotKeys = false; - addRuleNodeLink(event, edge, labels).then( + addRuleNodeLink(event, edge, labels, allowCustomLabels).then( (link) => { deferred.resolve(link); vm.enableHotKeys = true; @@ -713,6 +717,7 @@ export function RuleChainController($state, $scope, $compile, $q, $mdUtil, $time vm.isEditingRuleNode = false; vm.editingRuleNode = null; vm.editingRuleNodeLinkLabels = ruleChainService.getRuleNodeSupportedLinks(sourceNode.component); + vm.editingRuleNodeAllowCustomLabels = ruleChainService.ruleNodeAllowCustomLinks(sourceNode.component); vm.isEditingRuleNodeLink = true; vm.editingRuleNodeLinkIndex = vm.ruleChainModel.edges.indexOf(edge); vm.editingRuleNodeLink = angular.copy(edge); @@ -744,7 +749,8 @@ export function RuleChainController($state, $scope, $compile, $q, $mdUtil, $time isInputSource: isInputSource, fromIndex: fromIndex, toIndex: toIndex, - label: edge.label + label: edge.label, + labels: edge.labels }; connections.push(connection); } @@ -816,7 +822,8 @@ export function RuleChainController($state, $scope, $compile, $q, $mdUtil, $time var edge = { source: source, destination: destination, - label: connection.label + label: connection.label, + labels: connection.labels }; vm.ruleChainModel.edges.push(edge); vm.modelservice.edges.select(edge); @@ -1024,6 +1031,7 @@ export function RuleChainController($state, $scope, $compile, $q, $mdUtil, $time } if (vm.ruleChainMetaData.connections) { + var edgeMap = {}; for (i = 0; i < vm.ruleChainMetaData.connections.length; i++) { var connection = vm.ruleChainMetaData.connections[i]; var sourceNode = nodes[connection.fromIndex]; @@ -1032,12 +1040,23 @@ export function RuleChainController($state, $scope, $compile, $q, $mdUtil, $time var sourceConnectors = vm.modelservice.nodes.getConnectorsByType(sourceNode, flowchartConstants.rightConnectorType); var destConnectors = vm.modelservice.nodes.getConnectorsByType(destNode, flowchartConstants.leftConnectorType); if (sourceConnectors && sourceConnectors.length && destConnectors && destConnectors.length) { - edge = { - source: sourceConnectors[0].id, - destination: destConnectors[0].id, - label: connection.type - }; - vm.ruleChainModel.edges.push(edge); + var sourceId = sourceConnectors[0].id; + var destId = destConnectors[0].id; + var edgeKey = sourceId + '_' + destId; + edge = edgeMap[edgeKey]; + if (!edge) { + edge = { + source: sourceId, + destination: destId, + label: connection.type, + labels: [connection.type] + }; + edgeMap[edgeKey] = edge; + vm.ruleChainModel.edges.push(edge); + } else { + edge.label += ' / ' +connection.type; + edge.labels.push(connection.type); + } } } } @@ -1045,6 +1064,7 @@ export function RuleChainController($state, $scope, $compile, $q, $mdUtil, $time if (vm.ruleChainMetaData.ruleChainConnections) { var ruleChainNodesMap = {}; + var ruleChainEdgeMap = {}; for (i = 0; i < vm.ruleChainMetaData.ruleChainConnections.length; i++) { var ruleChainConnection = vm.ruleChainMetaData.ruleChainConnections[i]; var ruleChain = ruleChainsMap[ruleChainConnection.targetRuleChainId.id]; @@ -1081,12 +1101,23 @@ export function RuleChainController($state, $scope, $compile, $q, $mdUtil, $time if (sourceNode) { connectors = vm.modelservice.nodes.getConnectorsByType(sourceNode, flowchartConstants.rightConnectorType); if (connectors && connectors.length) { - var ruleChainEdge = { - source: connectors[0].id, - destination: ruleChainNode.connectors[0].id, - label: ruleChainConnection.type - }; - vm.ruleChainModel.edges.push(ruleChainEdge); + sourceId = connectors[0].id; + destId = ruleChainNode.connectors[0].id; + edgeKey = sourceId + '_' + destId; + var ruleChainEdge = ruleChainEdgeMap[edgeKey]; + if (!ruleChainEdge) { + ruleChainEdge = { + source: sourceId, + destination: destId, + label: ruleChainConnection.type, + labels: [ruleChainConnection.type] + }; + ruleChainEdgeMap[edgeKey] = ruleChainEdge; + vm.ruleChainModel.edges.push(ruleChainEdge); + } else { + ruleChainEdge.label += ' / ' +ruleChainConnection.type; + ruleChainEdge.labels.push(ruleChainConnection.type); + } } } } @@ -1199,8 +1230,7 @@ export function RuleChainController($state, $scope, $compile, $q, $mdUtil, $time var ruleChainConnection = { fromIndex: fromIndex, targetRuleChainId: {entityType: vm.types.entityType.rulechain, id: destNode.targetRuleChainId}, - additionalInfo: destNode.additionalInfo, - type: edge.label + additionalInfo: destNode.additionalInfo }; if (!ruleChainConnection.additionalInfo) { ruleChainConnection.additionalInfo = {}; @@ -1208,15 +1238,22 @@ export function RuleChainController($state, $scope, $compile, $q, $mdUtil, $time ruleChainConnection.additionalInfo.layoutX = Math.round(destNode.x); ruleChainConnection.additionalInfo.layoutY = Math.round(destNode.y); ruleChainConnection.additionalInfo.ruleChainNodeId = destNode.id; - ruleChainMetaData.ruleChainConnections.push(ruleChainConnection); + for (var rcIndex=0;rcIndex
+ is-read-only="false">
diff --git a/ui/src/app/rulechain/script/node-script-test.tpl.html b/ui/src/app/rulechain/script/node-script-test.tpl.html index 0ce57e8e95..e5fb9c38de 100644 --- a/ui/src/app/rulechain/script/node-script-test.tpl.html +++ b/ui/src/app/rulechain/script/node-script-test.tpl.html @@ -38,13 +38,12 @@
- - - -
-
rulenode.message-type-required
-
-
+ +
- + generateReport
- + {{ 'rulenode.test' | translate }} diff --git a/ui/src/app/services/item-buffer.service.js b/ui/src/app/services/item-buffer.service.js index a9fe348794..09ed9c552c 100644 --- a/ui/src/app/services/item-buffer.service.js +++ b/ui/src/app/services/item-buffer.service.js @@ -214,10 +214,19 @@ function ItemBuffer($q, bufferStore, types, utils, dashboardUtils, ruleChainServ var node = ruleNodes.nodes[i]; var component = ruleChainService.getRuleNodeComponentByClazz(node.componentClazz); if (component) { + var icon = types.ruleNodeType[component.type].icon; + var iconUrl = null; + if (component.configurationDescriptor.nodeDefinition.icon) { + icon = component.configurationDescriptor.nodeDefinition.icon; + } + if (component.configurationDescriptor.nodeDefinition.iconUrl) { + iconUrl = component.configurationDescriptor.nodeDefinition.iconUrl; + } delete node.componentClazz; node.component = component; node.nodeClass = types.ruleNodeType[component.type].nodeClass; - node.icon = types.ruleNodeType[component.type].icon; + node.icon = icon; + node.iconUrl = iconUrl; node.connectors = []; node.x = Math.round(node.x + deltaX); node.y = Math.round(node.y + deltaY); diff --git a/ui/src/app/widget/lib/CanvasDigitalGauge.js b/ui/src/app/widget/lib/CanvasDigitalGauge.js index 0166e913c1..ee8b0ed559 100644 --- a/ui/src/app/widget/lib/CanvasDigitalGauge.js +++ b/ui/src/app/widget/lib/CanvasDigitalGauge.js @@ -204,8 +204,13 @@ export default class CanvasDigitalGauge extends canvasGauges.BaseGauge { } var valueChanged = false; - - if (!this.elementValueClone.initialized || this.elementValueClone.renderedValue !== this.value || (options.showTimestamp && this.elementValueClone.renderedTimestamp !== this.timestamp)) { + if (!this.elementValueClone.initialized || angular.isDefined(this._value) && this.elementValueClone.renderedValue !== this._value || (options.showTimestamp && this.elementValueClone.renderedTimestamp !== this.timestamp)) { + if (angular.isDefined(this._value)) { + this.elementValueClone.renderedValue = this._value; + } + if (angular.isUndefined(this.elementValueClone.renderedValue)) { + this.elementValueClone.renderedValue = options.minValue; + } let context = this.contextValueClone; // clear the cache context.clearRect(x, y, w, h); @@ -214,7 +219,7 @@ export default class CanvasDigitalGauge extends canvasGauges.BaseGauge { context.drawImage(canvas.elementClone, x, y, w, h); context.save(); - drawDigitalValue(context, options, this.value); + drawDigitalValue(context, options, this.elementValueClone.renderedValue); if (options.showTimestamp) { drawDigitalLabel(context, options); @@ -222,7 +227,6 @@ export default class CanvasDigitalGauge extends canvasGauges.BaseGauge { } this.elementValueClone.initialized = true; - this.elementValueClone.renderedValue = this.value; valueChanged = true; } diff --git a/ui/src/app/widget/lib/alarms-table-widget.js b/ui/src/app/widget/lib/alarms-table-widget.js index 0a5bbce8ba..0696a7b873 100644 --- a/ui/src/app/widget/lib/alarms-table-widget.js +++ b/ui/src/app/widget/lib/alarms-table-widget.js @@ -45,7 +45,7 @@ function AlarmsTableWidget() { } /*@ngInject*/ -function AlarmsTableWidgetController($element, $scope, $filter, $mdMedia, $mdDialog, $document, $translate, $q, alarmService, utils, types) { +function AlarmsTableWidgetController($element, $scope, $filter, $mdMedia, $mdDialog, $document, $translate, $q, $timeout, alarmService, utils, types) { var vm = this; vm.stylesInfo = {}; @@ -266,6 +266,9 @@ function AlarmsTableWidgetController($element, $scope, $filter, $mdMedia, $mdDia function enterFilterMode () { vm.query.search = ''; vm.ctx.hideTitlePanel = true; + $timeout(()=>{ + angular.element(vm.ctx.$container).find('.searchInput').focus(); + }) } function exitFilterMode () { diff --git a/ui/src/app/widget/lib/alarms-table-widget.tpl.html b/ui/src/app/widget/lib/alarms-table-widget.tpl.html index 1cca18bb86..8480058bc2 100644 --- a/ui/src/app/widget/lib/alarms-table-widget.tpl.html +++ b/ui/src/app/widget/lib/alarms-table-widget.tpl.html @@ -28,7 +28,7 @@ - + close diff --git a/ui/src/app/widget/lib/canvas-digital-gauge.js b/ui/src/app/widget/lib/canvas-digital-gauge.js index 8e6db0468e..283a42676b 100644 --- a/ui/src/app/widget/lib/canvas-digital-gauge.js +++ b/ui/src/app/widget/lib/canvas-digital-gauge.js @@ -70,6 +70,10 @@ export default class TbCanvasDigitalGauge { (settings.title && settings.title.length > 0 ? settings.title : dataKey.label) : ''); + if (!this.localSettings.unitTitle && this.localSettings.showTimestamp) { + this.localSettings.unitTitle = ' '; + } + this.localSettings.titleFont = {}; var settingsTitleFont = settings.titleFont; if (!settingsTitleFont) { @@ -206,6 +210,7 @@ export default class TbCanvasDigitalGauge { var value = tvPair[1]; if(value !== this.gauge.value) { this.gauge.value = value; + this.gauge._value = value; } else if (this.localSettings.showTimestamp && this.gauge.timestamp != timestamp) { this.gauge.timestamp = timestamp; } diff --git a/ui/src/app/widget/lib/entities-table-widget.js b/ui/src/app/widget/lib/entities-table-widget.js index 1601e71332..d0b629d290 100644 --- a/ui/src/app/widget/lib/entities-table-widget.js +++ b/ui/src/app/widget/lib/entities-table-widget.js @@ -45,7 +45,7 @@ function EntitiesTableWidget() { } /*@ngInject*/ -function EntitiesTableWidgetController($element, $scope, $filter, $mdMedia, $translate, utils, types) { +function EntitiesTableWidgetController($element, $scope, $filter, $mdMedia, $translate, $timeout, utils, types) { var vm = this; vm.stylesInfo = {}; @@ -254,6 +254,9 @@ function EntitiesTableWidgetController($element, $scope, $filter, $mdMedia, $tra function enterFilterMode () { vm.query.search = ''; vm.ctx.hideTitlePanel = true; + $timeout(()=>{ + angular.element(vm.ctx.$container).find('.searchInput').focus(); + }) } function exitFilterMode () { diff --git a/ui/src/app/widget/lib/entities-table-widget.tpl.html b/ui/src/app/widget/lib/entities-table-widget.tpl.html index 97a8d699db..474d536024 100644 --- a/ui/src/app/widget/lib/entities-table-widget.tpl.html +++ b/ui/src/app/widget/lib/entities-table-widget.tpl.html @@ -27,7 +27,7 @@ - + close diff --git a/ui/src/app/widget/lib/timeseries-table-widget.js b/ui/src/app/widget/lib/timeseries-table-widget.js index 684bbde1e3..bca79565af 100644 --- a/ui/src/app/widget/lib/timeseries-table-widget.js +++ b/ui/src/app/widget/lib/timeseries-table-widget.js @@ -44,7 +44,7 @@ function TimeseriesTableWidget() { } /*@ngInject*/ -function TimeseriesTableWidgetController($element, $scope, $filter) { +function TimeseriesTableWidgetController($element, $scope, $filter, $timeout) { var vm = this; let dateFormatFilter = 'yyyy-MM-dd HH:mm:ss'; @@ -62,6 +62,9 @@ function TimeseriesTableWidgetController($element, $scope, $filter) { function enterFilterMode () { vm.query.search = ''; vm.ctx.hideTitlePanel = true; + $timeout(()=>{ + angular.element(vm.ctx.$container).find('.searchInput').focus(); + }) } function exitFilterMode () { diff --git a/ui/src/app/widget/lib/timeseries-table-widget.tpl.html b/ui/src/app/widget/lib/timeseries-table-widget.tpl.html index eb9b8caa75..08c4c9ef9a 100644 --- a/ui/src/app/widget/lib/timeseries-table-widget.tpl.html +++ b/ui/src/app/widget/lib/timeseries-table-widget.tpl.html @@ -27,7 +27,7 @@ - + close diff --git a/ui/src/app/widget/widget-editor.controller.js b/ui/src/app/widget/widget-editor.controller.js index 6f0ad8761e..089d64cf5a 100644 --- a/ui/src/app/widget/widget-editor.controller.js +++ b/ui/src/app/widget/widget-editor.controller.js @@ -20,12 +20,11 @@ import 'brace/mode/javascript'; import 'brace/mode/html'; import 'brace/mode/css'; import 'brace/mode/json'; -import 'ace-builds/src-min-noconflict/ace'; -import 'ace-builds/src-min-noconflict/snippets/javascript'; -import 'ace-builds/src-min-noconflict/snippets/text'; -import 'ace-builds/src-min-noconflict/snippets/html'; -import 'ace-builds/src-min-noconflict/snippets/css'; -import 'ace-builds/src-min-noconflict/snippets/json'; +import 'brace/snippets/javascript'; +import 'brace/snippets/text'; +import 'brace/snippets/html'; +import 'brace/snippets/css'; +import 'brace/snippets/json'; /* eslint-disable import/no-unresolved, import/default */ diff --git a/ui/src/scss/main.scss b/ui/src/scss/main.scss index 8fed892b06..2852a7bd60 100644 --- a/ui/src/scss/main.scss +++ b/ui/src/scss/main.scss @@ -16,6 +16,7 @@ @import "~compass-sass-mixins/lib/compass"; @import "constants"; @import "animations"; +@import "mixins"; @import "fonts"; /*************** @@ -437,6 +438,12 @@ pre.tb-highlight { } } +.tb-card-description { + color: rgba(0,0,0,0.54); + font-size: 13px; + @include line-clamp(2, 1.1); +} + /*********************** * Flow ***********************/ diff --git a/ui/src/scss/mixins.scss b/ui/src/scss/mixins.scss index 9e8b7df349..cb661719f2 100644 --- a/ui/src/scss/mixins.scss +++ b/ui/src/scss/mixins.scss @@ -31,4 +31,29 @@ &:-ms-input-placeholder { @content; } -} \ No newline at end of file +} + +@mixin line-clamp($numLines: 1, $lineHeight: 1.412) { + overflow: hidden; + position: relative; + line-height: $lineHeight; + text-align: justify; + margin-right: -1em; + padding-right: 2em; + max-height: ($numLines*$lineHeight)+em; + &:before { + content: '...'; + position: absolute; + right: 1em; + bottom: 0; + } + &:after { + content: ''; + position: absolute; + right: 1em; + width: 1em; + height: 1em; + margin-top: 0.2em; + background: white; + } +} diff --git a/ui/webpack.config.dev.js b/ui/webpack.config.dev.js index b1a1911400..242ad9d7aa 100644 --- a/ui/webpack.config.dev.js +++ b/ui/webpack.config.dev.js @@ -20,6 +20,17 @@ const ExtractTextPlugin = require('extract-text-webpack-plugin'); const CopyWebpackPlugin = require('copy-webpack-plugin'); const webpack = require('webpack'); const path = require('path'); +const dirTree = require('directory-tree'); +const jsonminify = require("jsonminify"); + +const PUBLIC_RESOURCE_PATH = '/'; + +var langs = []; +dirTree('./src/app/locale/', {extensions:/\.json$/}, (item) => { + /* It is expected what the name of a locale file has the following format: */ + /* 'locale.constant-LANG_CODE[_REGION_CODE].json', e.g. locale.constant-es.json or locale.constant-zh_CN.json*/ + langs.push(item.name.slice(item.name.lastIndexOf('-') + 1, -5)); +}); /* devtool: 'cheap-module-eval-source-map', */ @@ -32,7 +43,7 @@ module.exports = { ], output: { path: path.resolve(__dirname, 'target/generated-resources/public/static'), - publicPath: '/', + publicPath: PUBLIC_RESOURCE_PATH, filename: 'bundle.js', }, plugins: [ @@ -45,7 +56,18 @@ module.exports = { moment: "moment" }), new CopyWebpackPlugin([ - { from: './src/thingsboard.ico', to: 'thingsboard.ico' } + { + from: './src/thingsboard.ico', + to: 'thingsboard.ico' + }, + { + from: './src/app/locale', + to: 'locale', + ignore: [ '*.js' ], + transform: function(content, path) { + return Buffer.from(jsonminify(content.toString())); + } + } ]), new webpack.HotModuleReplacementPlugin(), new HtmlWebpackPlugin({ @@ -65,6 +87,8 @@ module.exports = { 'process.env': { NODE_ENV: JSON.stringify('development'), }, + PUBLIC_PATH: JSON.stringify(PUBLIC_RESOURCE_PATH), + SUPPORTED_LANGS: JSON.stringify(langs) }), ], node: { @@ -117,7 +141,7 @@ module.exports = { 'url?limit=8192', 'img?minimize' ] - }, + } ], }, 'html-minifier-loader': { diff --git a/ui/webpack.config.prod.js b/ui/webpack.config.prod.js index 150638def1..a442590d8b 100644 --- a/ui/webpack.config.prod.js +++ b/ui/webpack.config.prod.js @@ -18,8 +18,20 @@ const HtmlWebpackPlugin = require('html-webpack-plugin'); const ExtractTextPlugin = require('extract-text-webpack-plugin'); const CopyWebpackPlugin = require('copy-webpack-plugin'); +const CompressionPlugin = require('compression-webpack-plugin'); const webpack = require('webpack'); const path = require('path'); +const dirTree = require('directory-tree'); +const jsonminify = require("jsonminify"); + +const PUBLIC_RESOURCE_PATH = '/static/'; + +var langs = []; +dirTree('./src/app/locale/', {extensions:/\.json$/}, (item) => { + /* It is expected what the name of a locale file has the following format: */ + /* 'locale.constant-LANG_CODE[_REGION_CODE].json', e.g. locale.constant-es.json or locale.constant-zh_CN.json*/ + langs.push(item.name.slice(item.name.lastIndexOf('-') + 1, -5)); +}); module.exports = { devtool: 'source-map', @@ -29,7 +41,7 @@ module.exports = { ], output: { path: path.resolve(__dirname, 'target/generated-resources/public/static'), - publicPath: '/static/', + publicPath: PUBLIC_RESOURCE_PATH, filename: 'bundle.[hash].js', }, plugins: [ @@ -42,7 +54,18 @@ module.exports = { moment: "moment" }), new CopyWebpackPlugin([ - {from: './src/thingsboard.ico', to: 'thingsboard.ico'} + { + from: './src/thingsboard.ico', + to: 'thingsboard.ico' + }, + { + from: './src/app/locale', + to: 'locale', + ignore: [ '*.js' ], + transform: function(content, path) { + return Buffer.from(jsonminify(content.toString())); + } + } ]), new HtmlWebpackPlugin({ template: './src/index.html', @@ -63,7 +86,16 @@ module.exports = { 'process.env': { NODE_ENV: JSON.stringify('production'), }, + PUBLIC_PATH: PUBLIC_RESOURCE_PATH, + SUPPORTED_LANGS: JSON.stringify(langs) }), + new CompressionPlugin({ + asset: "[path].gz[query]", + algorithm: "gzip", + test: /\.js$|\.css$|\.svg$|\.ttf$|\.woff$|\.woff2|\.eot$\.json$/, + threshold: 10240, + minRatio: 0.8 + }) ], node: { tls: "empty", @@ -115,7 +147,7 @@ module.exports = { 'url?limit=8192', 'img?minimize' ] - }, + } ], }, 'html-minifier-loader': {