Browse Source

Merge with master

pull/3477/head
Igor Kulikov 6 years ago
parent
commit
16f088ecf9
  1. 21
      application/src/main/java/org/thingsboard/server/actors/device/DeviceActorMessageProcessor.java
  2. 2
      application/src/main/java/org/thingsboard/server/service/transport/DefaultTransportApiService.java
  3. 2
      application/src/main/resources/thingsboard.yml
  4. 19
      common/dao-api/pom.xml
  5. 19
      common/data/pom.xml
  6. 19
      common/message/pom.xml
  7. 29
      common/message/src/main/java/org/thingsboard/server/common/msg/kv/AttributesKVMsg.java
  8. 52
      common/message/src/main/java/org/thingsboard/server/common/msg/kv/BasicAttributeKVMsg.java
  9. 18
      common/queue/src/main/java/org/thingsboard/server/queue/memory/InMemoryStorage.java
  10. 2
      common/queue/src/main/java/org/thingsboard/server/queue/memory/InMemoryTbQueueProducer.java
  11. 1
      common/queue/src/main/proto/queue.proto
  12. 2
      common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/adaptors/JsonCoapAdaptor.java
  13. 35
      common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/adaptor/JsonConverter.java
  14. 3
      dao/src/main/java/org/thingsboard/server/dao/sql/alarm/AlarmRepository.java
  15. 7
      dao/src/main/java/org/thingsboard/server/dao/sql/alarm/JpaAlarmDao.java
  16. 1
      dao/src/main/java/org/thingsboard/server/dao/sqlts/hsql/JpaHsqlTimeseriesDao.java
  17. 4
      dao/src/main/java/org/thingsboard/server/dao/sqlts/insert/latest/hsql/HsqlLatestInsertTsRepository.java
  18. 19
      dao/src/main/java/org/thingsboard/server/dao/timeseries/AbstractCassandraBaseTimeseriesDao.java
  19. 9
      dao/src/main/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesLatestDao.java
  20. 1
      dao/src/test/resources/sql/hsql/drop-all-tables.sql
  21. 4621
      msa/js-executor/package-lock.json
  22. 28
      msa/js-executor/package.json
  23. 24
      msa/js-executor/pom.xml
  24. 2902
      msa/js-executor/yarn.lock
  25. 3554
      msa/web-ui/package-lock.json
  26. 26
      msa/web-ui/package.json
  27. 194
      msa/web-ui/pom.xml
  28. 2155
      msa/web-ui/yarn.lock
  29. 4
      netty-mqtt/src/main/java/org/thingsboard/mqtt/MqttChannelHandler.java
  30. 21
      netty-mqtt/src/main/java/org/thingsboard/mqtt/MqttIncomingQos2Publish.java
  31. 23
      rest-client/pom.xml
  32. 24
      rule-engine/rule-engine-api/pom.xml
  33. 5
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbOriginatorTypeSwitchNode.java
  34. 84
      ui-ngx/src/app/modules/common/modules-map.ts
  35. 9
      ui-ngx/src/app/modules/home/pages/dashboard/states/state-controller.component.ts

21
application/src/main/java/org/thingsboard/server/actors/device/DeviceActorMessageProcessor.java

@ -28,6 +28,7 @@ import org.thingsboard.rule.engine.api.msg.DeviceNameOrTypeUpdateMsg;
import org.thingsboard.server.actors.ActorSystemContext;
import org.thingsboard.server.actors.TbActorCtx;
import org.thingsboard.server.actors.shared.AbstractContextAwareMsgProcessor;
import org.thingsboard.server.common.data.DataConstants;
import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.id.TenantId;
@ -79,8 +80,6 @@ import java.util.UUID;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import static org.thingsboard.server.common.data.DataConstants.CLIENT_SCOPE;
import static org.thingsboard.server.common.data.DataConstants.SHARED_SCOPE;
/**
* @author Andrew Shvayka
@ -279,17 +278,17 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor {
ListenableFuture<List<AttributeKvEntry>> clientAttributesFuture;
ListenableFuture<List<AttributeKvEntry>> sharedAttributesFuture;
if (CollectionUtils.isEmpty(request.getClientAttributeNamesList()) && CollectionUtils.isEmpty(request.getSharedAttributeNamesList())) {
clientAttributesFuture = findAllAttributesByScope(CLIENT_SCOPE);
sharedAttributesFuture = findAllAttributesByScope(SHARED_SCOPE);
clientAttributesFuture = findAllAttributesByScope(DataConstants.CLIENT_SCOPE);
sharedAttributesFuture = findAllAttributesByScope(DataConstants.SHARED_SCOPE);
} else if (!CollectionUtils.isEmpty(request.getClientAttributeNamesList()) && !CollectionUtils.isEmpty(request.getSharedAttributeNamesList())) {
clientAttributesFuture = findAttributesByScope(toSet(request.getClientAttributeNamesList()), CLIENT_SCOPE);
sharedAttributesFuture = findAttributesByScope(toSet(request.getSharedAttributeNamesList()), SHARED_SCOPE);
clientAttributesFuture = findAttributesByScope(toSet(request.getClientAttributeNamesList()), DataConstants.CLIENT_SCOPE);
sharedAttributesFuture = findAttributesByScope(toSet(request.getSharedAttributeNamesList()), DataConstants.SHARED_SCOPE);
} else if (CollectionUtils.isEmpty(request.getClientAttributeNamesList()) && !CollectionUtils.isEmpty(request.getSharedAttributeNamesList())) {
clientAttributesFuture = Futures.immediateFuture(Collections.emptyList());
sharedAttributesFuture = findAttributesByScope(toSet(request.getSharedAttributeNamesList()), SHARED_SCOPE);
sharedAttributesFuture = findAttributesByScope(toSet(request.getSharedAttributeNamesList()), DataConstants.SHARED_SCOPE);
} else {
sharedAttributesFuture = Futures.immediateFuture(Collections.emptyList());
clientAttributesFuture = findAttributesByScope(toSet(request.getClientAttributeNamesList()), CLIENT_SCOPE);
clientAttributesFuture = findAttributesByScope(toSet(request.getClientAttributeNamesList()), DataConstants.CLIENT_SCOPE);
}
return Futures.allAsList(Arrays.asList(clientAttributesFuture, sharedAttributesFuture));
}
@ -316,7 +315,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor {
AttributeUpdateNotificationMsg.Builder notification = AttributeUpdateNotificationMsg.newBuilder();
if (msg.isDeleted()) {
List<String> sharedKeys = msg.getDeletedKeys().stream()
.filter(key -> SHARED_SCOPE.equals(key.getScope()))
.filter(key -> DataConstants.SHARED_SCOPE.equals(key.getScope()))
.map(AttributeKey::getAttributeKey)
.collect(Collectors.toList());
if (!sharedKeys.isEmpty()) {
@ -324,7 +323,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor {
hasNotificationData = true;
}
} else {
if (SHARED_SCOPE.equals(msg.getScope())) {
if (DataConstants.SHARED_SCOPE.equals(msg.getScope())) {
List<AttributeKvEntry> attributes = new ArrayList<>(msg.getValues());
if (attributes.size() > 0) {
List<TsKvProto> sharedUpdated = msg.getValues().stream().map(this::toTsKvProto)
@ -334,7 +333,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor {
hasNotificationData = true;
}
} else {
log.debug("[{}] No public server side attributes changed!", deviceId);
log.debug("[{}] No public shared side attributes changed!", deviceId);
}
}
}

2
application/src/main/java/org/thingsboard/server/service/transport/DefaultTransportApiService.java

@ -163,7 +163,7 @@ public class DefaultTransportApiService implements TransportApiService {
return TransportApiResponseMsg.newBuilder()
.setGetOrCreateDeviceResponseMsg(GetOrCreateDeviceFromGatewayResponseMsg.newBuilder().setDeviceInfo(getDeviceInfoProto(device)).build()).build();
} catch (JsonProcessingException e) {
log.warn("[{}] Failed to lookup device by gateway id and name", gatewayId, requestMsg.getDeviceName(), e);
log.warn("[{}][{}] Failed to lookup device by gateway id and name", gatewayId, requestMsg.getDeviceName(), e);
throw new RuntimeException(e);
} finally {
deviceCreationLock.unlock();

2
application/src/main/resources/thingsboard.yml

@ -522,7 +522,7 @@ js:
# Specify thread pool size for JavaScript sandbox resource monitor
monitor_thread_pool_size: "${LOCAL_JS_SANDBOX_MONITOR_THREAD_POOL_SIZE:4}"
# Maximum CPU time in milliseconds allowed for script execution
max_cpu_time: "${LOCAL_JS_SANDBOX_MAX_CPU_TIME:10000}"
max_cpu_time: "${LOCAL_JS_SANDBOX_MAX_CPU_TIME:8000}"
# Maximum allowed JavaScript execution errors before JavaScript will be blacklisted
max_errors: "${LOCAL_JS_SANDBOX_MAX_ERRORS:3}"
# JS Eval max request timeout. 0 - no timeout

19
common/dao-api/pom.xml

@ -106,6 +106,25 @@
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<configuration>
<skip>false</skip>
</configuration>
</plugin>
</plugins>
</build>

19
common/data/pom.xml

@ -75,6 +75,25 @@
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<configuration>
<skip>false</skip>
</configuration>
</plugin>
</plugins>
</build>

19
common/message/pom.xml

@ -87,6 +87,25 @@
<groupId>org.xolstice.maven.plugins</groupId>
<artifactId>protobuf-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<configuration>
<skip>false</skip>
</configuration>
</plugin>
</plugins>
</build>

29
common/message/src/main/java/org/thingsboard/server/common/msg/kv/AttributesKVMsg.java

@ -1,29 +0,0 @@
/**
* Copyright © 2016-2020 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.common.msg.kv;
import java.io.Serializable;
import java.util.List;
import org.thingsboard.server.common.data.kv.AttributeKey;
import org.thingsboard.server.common.data.kv.AttributeKvEntry;
public interface AttributesKVMsg extends Serializable {
List<AttributeKvEntry> getClientAttributes();
List<AttributeKvEntry> getSharedAttributes();
List<AttributeKey> getDeletedAttributes();
}

52
common/message/src/main/java/org/thingsboard/server/common/msg/kv/BasicAttributeKVMsg.java

@ -1,52 +0,0 @@
/**
* Copyright © 2016-2020 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.common.msg.kv;
import lombok.AccessLevel;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import org.thingsboard.server.common.data.kv.AttributeKey;
import org.thingsboard.server.common.data.kv.AttributeKvEntry;
import java.util.Collections;
import java.util.List;
@Data
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
public class BasicAttributeKVMsg implements AttributesKVMsg {
private static final long serialVersionUID = 1L;
private final List<AttributeKvEntry> clientAttributes;
private final List<AttributeKvEntry> sharedAttributes;
private final List<AttributeKey> deletedAttributes;
public static BasicAttributeKVMsg fromClient(List<AttributeKvEntry> attributes) {
return new BasicAttributeKVMsg(attributes, Collections.emptyList(), Collections.emptyList());
}
public static BasicAttributeKVMsg fromShared(List<AttributeKvEntry> attributes) {
return new BasicAttributeKVMsg(Collections.emptyList(), attributes, Collections.emptyList());
}
public static BasicAttributeKVMsg from(List<AttributeKvEntry> client, List<AttributeKvEntry> shared) {
return new BasicAttributeKVMsg(client, shared, Collections.emptyList());
}
public static AttributesKVMsg fromDeleted(List<AttributeKey> shared) {
return new BasicAttributeKVMsg(Collections.emptyList(), Collections.emptyList(), shared);
}
}

18
common/queue/src/main/java/org/thingsboard/server/queue/memory/InMemoryStorage.java

@ -23,16 +23,29 @@ import java.util.Collections;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
@Slf4j
public final class InMemoryStorage {
private static InMemoryStorage instance;
private final ConcurrentHashMap<String, BlockingQueue<TbQueueMsg>> storage;
private static ScheduledExecutorService statExecutor;
private InMemoryStorage() {
storage = new ConcurrentHashMap<>();
statExecutor = Executors.newSingleThreadScheduledExecutor();
statExecutor.scheduleAtFixedRate(this::printStats, 60, 60, TimeUnit.SECONDS);
}
private void printStats() {
storage.forEach((topic, queue) -> {
if (queue.size() > 0) {
log.debug("Topic: [{}], Queue size: [{}]", topic, queue.size());
}
});
}
public static InMemoryStorage getInstance() {
@ -77,4 +90,9 @@ public final class InMemoryStorage {
storage.clear();
}
public void destroy() {
if (statExecutor != null) {
statExecutor.shutdownNow();
}
}
}

2
common/queue/src/main/java/org/thingsboard/server/queue/memory/InMemoryTbQueueProducer.java

@ -53,6 +53,6 @@ public class InMemoryTbQueueProducer<T extends TbQueueMsg> implements TbQueuePro
@Override
public void stop() {
storage.destroy();
}
}

1
common/queue/src/main/proto/queue.proto

@ -127,7 +127,6 @@ message GetAttributeResponseMsg {
int32 requestId = 1;
repeated TsKvProto clientAttributeList = 2;
repeated TsKvProto sharedAttributeList = 3;
repeated string deletedAttributeKeys = 4;
string error = 5;
}

2
common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/adaptors/JsonCoapAdaptor.java

@ -125,7 +125,7 @@ public class JsonCoapAdaptor implements CoapTransportAdaptor {
@Override
public Response convertToPublish(CoapTransportResource.CoapSessionListener session, TransportProtos.GetAttributeResponseMsg msg) throws AdaptorException {
if (msg.getClientAttributeListCount() == 0 && msg.getSharedAttributeListCount() == 0 && msg.getDeletedAttributeKeysCount() == 0) {
if (msg.getClientAttributeListCount() == 0 && msg.getSharedAttributeListCount() == 0) {
return new Response(CoAP.ResponseCode.NOT_FOUND);
} else {
Response response = new Response(CoAP.ResponseCode.CONTENT);

35
common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/adaptor/JsonConverter.java

@ -35,7 +35,6 @@ import org.thingsboard.server.common.data.kv.JsonDataEntry;
import org.thingsboard.server.common.data.kv.KvEntry;
import org.thingsboard.server.common.data.kv.LongDataEntry;
import org.thingsboard.server.common.data.kv.StringDataEntry;
import org.thingsboard.server.common.msg.kv.AttributesKVMsg;
import org.thingsboard.server.gen.transport.TransportProtos;
import org.thingsboard.server.gen.transport.TransportProtos.AttributeUpdateNotificationMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ClaimDeviceMsg;
@ -269,11 +268,6 @@ public class JsonConverter {
payload.getSharedAttributeListList().forEach(addToObjectFromProto(attrObject));
result.add("shared", attrObject);
}
if (payload.getDeletedAttributeKeysCount() > 0) {
JsonArray attrObject = new JsonArray();
payload.getDeletedAttributeKeysList().forEach(attrObject::add);
result.add("deleted", attrObject);
}
return result;
}
@ -290,31 +284,6 @@ public class JsonConverter {
return result;
}
public static JsonObject toJson(AttributesKVMsg payload, boolean asMap) {
JsonObject result = new JsonObject();
if (asMap) {
if (!payload.getClientAttributes().isEmpty()) {
JsonObject attrObject = new JsonObject();
payload.getClientAttributes().forEach(addToObject(attrObject));
result.add("client", attrObject);
}
if (!payload.getSharedAttributes().isEmpty()) {
JsonObject attrObject = new JsonObject();
payload.getSharedAttributes().forEach(addToObject(attrObject));
result.add("shared", attrObject);
}
} else {
payload.getClientAttributes().forEach(addToObject(result));
payload.getSharedAttributes().forEach(addToObject(result));
}
if (!payload.getDeletedAttributes().isEmpty()) {
JsonArray attrObject = new JsonArray();
payload.getDeletedAttributes().forEach(addToObject(attrObject));
result.add("deleted", attrObject);
}
return result;
}
public static JsonObject getJsonObjectForGateway(String deviceName, TransportProtos.GetAttributeResponseMsg responseMsg) {
JsonObject result = new JsonObject();
result.addProperty("id", responseMsg.getRequestId());
@ -370,10 +339,6 @@ public class JsonConverter {
}
}
private static Consumer<AttributeKey> addToObject(JsonArray result) {
return key -> result.add(key.getAttributeKey());
}
private static Consumer<TsKvProto> addToObjectFromProto(JsonObject result) {
return de -> {
switch (de.getKv().getType()) {

3
dao/src/main/java/org/thingsboard/server/dao/sql/alarm/AlarmRepository.java

@ -25,6 +25,7 @@ import org.thingsboard.server.dao.model.sql.AlarmEntity;
import org.thingsboard.server.dao.model.sql.AlarmInfoEntity;
import java.util.List;
import java.util.Set;
import java.util.UUID;
/**
@ -70,7 +71,7 @@ public interface AlarmRepository extends CrudRepository<AlarmEntity, UUID> {
@Param("affectedEntityType") String affectedEntityType,
@Param("startTime") Long startTime,
@Param("endTime") Long endTime,
@Param("alarmStatuses") List<AlarmStatus> alarmStatuses,
@Param("alarmStatuses") Set<AlarmStatus> alarmStatuses,
@Param("searchText") String searchText,
Pageable pageable);

7
dao/src/main/java/org/thingsboard/server/dao/sql/alarm/JpaAlarmDao.java

@ -24,14 +24,12 @@ import org.springframework.stereotype.Component;
import org.thingsboard.server.common.data.alarm.Alarm;
import org.thingsboard.server.common.data.alarm.AlarmInfo;
import org.thingsboard.server.common.data.alarm.AlarmQuery;
import org.thingsboard.server.common.data.alarm.AlarmSearchStatus;
import org.thingsboard.server.common.data.alarm.AlarmStatus;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.query.AlarmData;
import org.thingsboard.server.common.data.query.AlarmDataPageLink;
import org.thingsboard.server.common.data.query.AlarmDataQuery;
import org.thingsboard.server.dao.DaoUtil;
import org.thingsboard.server.dao.alarm.AlarmDao;
@ -40,7 +38,6 @@ import org.thingsboard.server.dao.relation.RelationDao;
import org.thingsboard.server.dao.sql.JpaAbstractDao;
import org.thingsboard.server.dao.sql.query.AlarmQueryRepository;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
@ -102,7 +99,7 @@ public class JpaAlarmDao extends JpaAbstractDao<AlarmEntity, Alarm> implements A
Set<AlarmStatus> statusSet = null;
if (query.getSearchStatus() != null) {
statusSet = query.getSearchStatus().getStatuses();
} else if (query.getStatus() != null){
} else if (query.getStatus() != null) {
statusSet = Collections.singleton(query.getStatus());
}
return DaoUtil.toPageData(
@ -112,7 +109,7 @@ public class JpaAlarmDao extends JpaAbstractDao<AlarmEntity, Alarm> implements A
affectedEntity.getEntityType().name(),
query.getPageLink().getStartTime(),
query.getPageLink().getEndTime(),
new ArrayList<>(statusSet),
statusSet,
Objects.toString(query.getPageLink().getTextSearch(), ""),
DaoUtil.toPageable(query.getPageLink())
)

1
dao/src/main/java/org/thingsboard/server/dao/sqlts/hsql/JpaHsqlTimeseriesDao.java

@ -46,6 +46,7 @@ public class JpaHsqlTimeseriesDao extends AbstractChunkedAggregationTimeseriesDa
entity.setDoubleValue(tsKvEntry.getDoubleValue().orElse(null));
entity.setLongValue(tsKvEntry.getLongValue().orElse(null));
entity.setBooleanValue(tsKvEntry.getBooleanValue().orElse(null));
entity.setJsonValue(tsKvEntry.getJsonValue().orElse(null));
log.trace("Saving entity: {}", entity);
return tsQueue.add(entity);
}

4
dao/src/main/java/org/thingsboard/server/dao/sqlts/insert/latest/hsql/HsqlLatestInsertTsRepository.java

@ -41,8 +41,8 @@ public class HsqlLatestInsertTsRepository extends AbstractInsertRepository imple
"ON (ts_kv_latest.entity_id=T.entity_id " +
"AND ts_kv_latest.key=T.key) " +
"WHEN MATCHED THEN UPDATE SET ts_kv_latest.ts = T.ts, ts_kv_latest.bool_v = T.bool_v, ts_kv_latest.str_v = T.str_v, ts_kv_latest.long_v = T.long_v, ts_kv_latest.dbl_v = T.dbl_v, ts_kv_latest.json_v = T.json_v " +
"WHEN NOT MATCHED THEN INSERT (entity_id, key, ts, bool_v, str_v, long_v, dbl_v) " +
"VALUES (T.entity_id, T.key, T.ts, T.bool_v, T.str_v, T.long_v, T.dbl_v);";
"WHEN NOT MATCHED THEN INSERT (entity_id, key, ts, bool_v, str_v, long_v, dbl_v, json_v) " +
"VALUES (T.entity_id, T.key, T.ts, T.bool_v, T.str_v, T.long_v, T.dbl_v, T.json_v);";
@Override
public void saveOrUpdate(List<TsKvLatestEntity> entities) {

19
dao/src/main/java/org/thingsboard/server/dao/timeseries/AbstractCassandraBaseTimeseriesDao.java

@ -31,6 +31,7 @@ import org.thingsboard.server.dao.nosql.CassandraAbstractAsyncDao;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
@Slf4j
public abstract class AbstractCassandraBaseTimeseriesDao extends CassandraAbstractAsyncDao {
@ -85,4 +86,22 @@ public abstract class AbstractCassandraBaseTimeseriesDao extends CassandraAbstra
return new BasicTsKvEntry(ts, toKvEntry(row, key));
}
protected TsKvEntry convertResultToTsKvEntry(String key, Row row) {
if (row != null) {
Optional<String> foundKeyOpt = getKey(row);
long ts = row.getLong(ModelConstants.TS_COLUMN);
return new BasicTsKvEntry(ts, toKvEntry(row, foundKeyOpt.orElse(key)));
} else {
return new BasicTsKvEntry(System.currentTimeMillis(), new StringDataEntry(key, null));
}
}
private Optional<String> getKey(Row row){
try{
return Optional.ofNullable(row.getString(ModelConstants.KEY_COLUMN));
} catch (IllegalArgumentException e){
return Optional.empty();
}
}
}

9
dao/src/main/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesLatestDao.java

@ -186,15 +186,6 @@ public class CassandraBaseTimeseriesLatestDao extends AbstractCassandraBaseTimes
rows -> this.convertResultToTsKvEntryList(rows), readResultsProcessingExecutor);
}
private TsKvEntry convertResultToTsKvEntry(String key, Row row) {
if (row != null) {
long ts = row.getLong(ModelConstants.TS_COLUMN);
return new BasicTsKvEntry(ts, toKvEntry(row, key));
} else {
return new BasicTsKvEntry(System.currentTimeMillis(), new StringDataEntry(key, null));
}
}
private PreparedStatement getLatestStmt() {
if (latestInsertStmt == null) {
latestInsertStmt = prepare(INSERT_INTO + ModelConstants.TS_KV_LATEST_CF +

1
dao/src/test/resources/sql/hsql/drop-all-tables.sql

@ -13,6 +13,7 @@ DROP TABLE IF EXISTS relation;
DROP TABLE IF EXISTS tb_user;
DROP TABLE IF EXISTS tenant;
DROP TABLE IF EXISTS ts_kv;
DROP TABLE IF EXISTS ts_kv_dictionary;
DROP TABLE IF EXISTS ts_kv_latest;
DROP TABLE IF EXISTS user_credentials;
DROP TABLE IF EXISTS widget_type;

4621
msa/js-executor/package-lock.json

File diff suppressed because it is too large

28
msa/js-executor/package.json

@ -6,28 +6,28 @@
"main": "server.js",
"bin": "server.js",
"scripts": {
"install": "pkg -t node10-linux-x64,node10-win-x64 --out-path ./target . && node install.js",
"install": "pkg -t node12-linux-x64,node12-win-x64 --out-path ./target . && node install.js",
"test": "echo \"Error: no test specified\" && exit 1",
"start": "nodemon server.js",
"start-prod": "NODE_ENV=production nodemon server.js"
},
"dependencies": {
"@azure/service-bus": "^1.1.7",
"@google-cloud/pubsub": "^1.7.3",
"amqplib": "^0.5.6",
"aws-sdk": "^2.677.0",
"@azure/service-bus": "^1.1.9",
"@google-cloud/pubsub": "^2.5.0",
"amqplib": "^0.6.0",
"aws-sdk": "^2.741.0",
"azure-sb": "^0.11.1",
"config": "^3.3.1",
"js-yaml": "^3.12.0",
"js-yaml": "^3.14.0",
"kafkajs": "^1.12.0",
"long": "^4.0.0",
"uuid-parse": "^1.0.0",
"uuid-random": "^1.3.0",
"winston": "^3.0.0",
"winston-daily-rotate-file": "^3.2.1"
"uuid-parse": "^1.1.0",
"uuid-random": "^1.3.2",
"winston": "^3.3.3",
"winston-daily-rotate-file": "^4.5.0"
},
"engines": {
"node": ">=8.0.0 <11.0.0"
"node": ">=12.0.0 <14.0.0"
},
"nyc": {
"exclude": [
@ -38,9 +38,9 @@
]
},
"devDependencies": {
"fs-extra": "^6.0.1",
"nodemon": "^1.17.5",
"pkg": "^4.4.8"
"fs-extra": "^9.0.1",
"nodemon": "^2.0.4",
"pkg": "^4.4.9"
},
"pkg": {
"assets": [

24
msa/js-executor/pom.xml

@ -59,26 +59,26 @@
<plugin>
<groupId>com.github.eirslett</groupId>
<artifactId>frontend-maven-plugin</artifactId>
<version>1.0</version>
<version>1.7.5</version>
<configuration>
<installDirectory>target</installDirectory>
<workingDirectory>${basedir}</workingDirectory>
</configuration>
<executions>
<execution>
<id>install node and npm</id>
<id>install node and yarn</id>
<goals>
<goal>install-node-and-npm</goal>
<goal>install-node-and-yarn</goal>
</goals>
<configuration>
<nodeVersion>v10.16.0</nodeVersion>
<npmVersion>6.4.1</npmVersion>
<nodeVersion>v12.16.1</nodeVersion>
<yarnVersion>v1.22.4</yarnVersion>
</configuration>
</execution>
<execution>
<id>npm install</id>
<id>yarn install</id>
<goals>
<goal>npm</goal>
<goal>yarn</goal>
</goals>
<configuration>
<arguments>install</arguments>
@ -138,10 +138,10 @@
</build>
<profiles>
<profile>
<id>npm-start</id>
<id>yarn-start</id>
<activation>
<property>
<name>npm-start</name>
<name>yarn-start</name>
</property>
</activation>
<build>
@ -149,16 +149,16 @@
<plugin>
<groupId>com.github.eirslett</groupId>
<artifactId>frontend-maven-plugin</artifactId>
<version>1.0</version>
<version>1.7.5</version>
<configuration>
<installDirectory>target</installDirectory>
<workingDirectory>${basedir}</workingDirectory>
</configuration>
<executions>
<execution>
<id>npm start</id>
<id>yarn start</id>
<goals>
<goal>npm</goal>
<goal>yarn</goal>
</goals>
<configuration>

2902
msa/js-executor/yarn.lock

File diff suppressed because it is too large

3554
msa/web-ui/package-lock.json

File diff suppressed because it is too large

26
msa/web-ui/package.json

@ -6,24 +6,24 @@
"main": "server.js",
"bin": "server.js",
"scripts": {
"install": "pkg -t node10-linux-x64,node10-win-x64 --out-path ./target . && node install.js",
"install": "pkg -t node12-linux-x64,node12-win-x64 --out-path ./target . && node install.js",
"test": "echo \"Error: no test specified\" && exit 1",
"start": "WEB_FOLDER=./target/web nodemon server.js",
"start-prod": "NODE_ENV=production nodemon server.js"
},
"dependencies": {
"compression": "^1.7.3",
"config": "^3.2.2",
"connect-history-api-fallback": "^1.5.0",
"express": "^4.16.3",
"compression": "^1.7.4",
"config": "^3.3.1",
"connect-history-api-fallback": "^1.6.0",
"express": "^4.17.1",
"http": "0.0.0",
"http-proxy": "^1.17.0",
"js-yaml": "^3.12.0",
"winston": "^3.0.0",
"winston-daily-rotate-file": "^3.2.1"
"http-proxy": "^1.18.1",
"js-yaml": "^3.14.0",
"winston": "^3.3.3",
"winston-daily-rotate-file": "^4.5.0"
},
"engines": {
"node": ">=8.0.0 <11.0.0"
"node": ">=12.0.0 <14.0.0"
},
"nyc": {
"exclude": [
@ -34,9 +34,9 @@
]
},
"devDependencies": {
"fs-extra": "^6.0.1",
"nodemon": "^1.17.5",
"pkg": "^4.4.0"
"fs-extra": "^9.0.1",
"nodemon": "^2.0.4",
"pkg": "^4.4.9"
},
"pkg": {
"assets": [

194
msa/web-ui/pom.xml

@ -68,26 +68,26 @@
<plugin>
<groupId>com.github.eirslett</groupId>
<artifactId>frontend-maven-plugin</artifactId>
<version>1.0</version>
<version>1.7.5</version>
<configuration>
<installDirectory>target</installDirectory>
<workingDirectory>${basedir}</workingDirectory>
</configuration>
<executions>
<execution>
<id>install node and npm</id>
<id>install node and yarn</id>
<goals>
<goal>install-node-and-npm</goal>
<goal>install-node-and-yarn</goal>
</goals>
<configuration>
<nodeVersion>v10.16.0</nodeVersion>
<npmVersion>6.4.1</npmVersion>
<nodeVersion>v12.16.1</nodeVersion>
<yarnVersion>v1.22.4</yarnVersion>
</configuration>
</execution>
<execution>
<id>npm install</id>
<id>yarn install</id>
<goals>
<goal>npm</goal>
<goal>yarn</goal>
</goals>
<configuration>
<arguments>install</arguments>
@ -149,176 +149,6 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
</plugin>
<!-- <plugin>-->
<!-- <groupId>org.apache.maven.plugins</groupId>-->
<!-- <artifactId>maven-resources-plugin</artifactId>-->
<!-- <executions>-->
<!-- <execution>-->
<!-- <id>copy-linux-conf</id>-->
<!-- <phase>process-resources</phase>-->
<!-- <goals>-->
<!-- <goal>copy-resources</goal>-->
<!-- </goals>-->
<!-- <configuration>-->
<!-- <outputDirectory>${pkg.linux.dist}/conf</outputDirectory>-->
<!-- <resources>-->
<!-- <resource>-->
<!-- <directory>config</directory>-->
<!-- <filtering>true</filtering>-->
<!-- </resource>-->
<!-- </resources>-->
<!-- <filters>-->
<!-- <filter>src/main/filters/unix.properties</filter>-->
<!-- </filters>-->
<!-- </configuration>-->
<!-- </execution>-->
<!-- <execution>-->
<!-- <id>copy-linux-init</id>-->
<!-- <phase>process-resources</phase>-->
<!-- <goals>-->
<!-- <goal>copy-resources</goal>-->
<!-- </goals>-->
<!-- <configuration>-->
<!-- <outputDirectory>${pkg.linux.dist}/init</outputDirectory>-->
<!-- <resources>-->
<!-- <resource>-->
<!-- <directory>src/main/scripts/init</directory>-->
<!-- <filtering>true</filtering>-->
<!-- </resource>-->
<!-- </resources>-->
<!-- <filters>-->
<!-- <filter>src/main/filters/unix.properties</filter>-->
<!-- </filters>-->
<!-- </configuration>-->
<!-- </execution>-->
<!-- <execution>-->
<!-- <id>copy-win-conf</id>-->
<!-- <phase>process-resources</phase>-->
<!-- <goals>-->
<!-- <goal>copy-resources</goal>-->
<!-- </goals>-->
<!-- <configuration>-->
<!-- <outputDirectory>${pkg.win.dist}/conf</outputDirectory>-->
<!-- <resources>-->
<!-- <resource>-->
<!-- <directory>config</directory>-->
<!-- <excludes>-->
<!-- <exclude>tb-web-ui.conf</exclude>-->
<!-- </excludes>-->
<!-- <filtering>true</filtering>-->
<!-- </resource>-->
<!-- </resources>-->
<!-- <filters>-->
<!-- <filter>src/main/filters/windows.properties</filter>-->
<!-- </filters>-->
<!-- </configuration>-->
<!-- </execution>-->
<!-- <execution>-->
<!-- <id>copy-control</id>-->
<!-- <phase>process-resources</phase>-->
<!-- <goals>-->
<!-- <goal>copy-resources</goal>-->
<!-- </goals>-->
<!-- <configuration>-->
<!-- <outputDirectory>${project.build.directory}/control</outputDirectory>-->
<!-- <resources>-->
<!-- <resource>-->
<!-- <directory>src/main/scripts/control</directory>-->
<!-- <filtering>true</filtering>-->
<!-- </resource>-->
<!-- </resources>-->
<!-- <filters>-->
<!-- <filter>src/main/filters/unix.properties</filter>-->
<!-- </filters>-->
<!-- </configuration>-->
<!-- </execution>-->
<!-- <execution>-->
<!-- <id>copy-windows-control</id>-->
<!-- <phase>process-resources</phase>-->
<!-- <goals>-->
<!-- <goal>copy-resources</goal>-->
<!-- </goals>-->
<!-- <configuration>-->
<!-- <outputDirectory>${pkg.win.dist}</outputDirectory>-->
<!-- <resources>-->
<!-- <resource>-->
<!-- <directory>src/main/scripts/windows</directory>-->
<!-- <filtering>true</filtering>-->
<!-- </resource>-->
<!-- </resources>-->
<!-- <filters>-->
<!-- <filter>src/main/filters/windows.properties</filter>-->
<!-- </filters>-->
<!-- </configuration>-->
<!-- </execution>-->
<!-- <execution>-->
<!-- <id>copy-docker-config</id>-->
<!-- <phase>process-resources</phase>-->
<!-- <goals>-->
<!-- <goal>copy-resources</goal>-->
<!-- </goals>-->
<!-- <configuration>-->
<!-- <outputDirectory>${project.build.directory}</outputDirectory>-->
<!-- <resources>-->
<!-- <resource>-->
<!-- <directory>docker</directory>-->
<!-- <filtering>true</filtering>-->
<!-- </resource>-->
<!-- </resources>-->
<!-- </configuration>-->
<!-- </execution>-->
<!-- </executions>-->
<!-- </plugin>-->
<!-- <plugin>-->
<!-- <groupId>org.thingsboard</groupId>-->
<!-- <artifactId>gradle-maven-plugin</artifactId>-->
<!-- <configuration>-->
<!-- <gradleProjectDirectory>${basedir}</gradleProjectDirectory>-->
<!-- <tasks>-->
<!-- <task>build</task>-->
<!-- <task>buildDeb</task>-->
<!-- <task>buildRpm</task>-->
<!-- <task>renameDeb</task>-->
<!-- <task>renameRpm</task>-->
<!-- </tasks>-->
<!-- <args>-->
<!-- <arg>-PprojectBuildDir=${project.build.directory}</arg>-->
<!-- <arg>-PprojectVersion=${project.version}</arg>-->
<!-- <arg>-PpkgName=${pkg.name}</arg>-->
<!-- <arg>-PpkgUser=${pkg.user}</arg>-->
<!-- <arg>-PpkgInstallFolder=${pkg.installFolder}</arg>-->
<!-- <arg>-PpkgLogFolder=${pkg.unixLogFolder}</arg>-->
<!-- </args>-->
<!-- </configuration>-->
<!-- <executions>-->
<!-- <execution>-->
<!-- <phase>package</phase>-->
<!-- <goals>-->
<!-- <goal>invoke</goal>-->
<!-- </goals>-->
<!-- </execution>-->
<!-- </executions>-->
<!-- </plugin>-->
<!-- <plugin>-->
<!-- <groupId>org.apache.maven.plugins</groupId>-->
<!-- <artifactId>maven-assembly-plugin</artifactId>-->
<!-- <version>3.0.0</version>-->
<!-- <configuration>-->
<!-- <finalName>${pkg.name}</finalName>-->
<!-- <descriptors>-->
<!-- <descriptor>../../packaging/js/assembly/windows.xml</descriptor>-->
<!-- </descriptors>-->
<!-- </configuration>-->
<!-- <executions>-->
<!-- <execution>-->
<!-- <id>assembly</id>-->
<!-- <phase>package</phase>-->
<!-- <goals>-->
<!-- <goal>single</goal>-->
<!-- </goals>-->
<!-- </execution>-->
<!-- </executions>-->
<!-- </plugin>-->
<plugin>
<groupId>com.spotify</groupId>
<artifactId>dockerfile-maven-plugin</artifactId>
@ -355,10 +185,10 @@
</build>
<profiles>
<profile>
<id>npm-start</id>
<id>yarn-start</id>
<activation>
<property>
<name>npm-start</name>
<name>yarn-start</name>
</property>
</activation>
<build>
@ -366,16 +196,16 @@
<plugin>
<groupId>com.github.eirslett</groupId>
<artifactId>frontend-maven-plugin</artifactId>
<version>1.0</version>
<version>1.7.5</version>
<configuration>
<installDirectory>target</installDirectory>
<workingDirectory>${basedir}</workingDirectory>
</configuration>
<executions>
<execution>
<id>npm start</id>
<id>yarn start</id>
<goals>
<goal>npm</goal>
<goal>yarn</goal>
</goals>
<configuration>

2155
msa/web-ui/yarn.lock

File diff suppressed because it is too large

4
netty-mqtt/src/main/java/org/thingsboard/mqtt/MqttChannelHandler.java

@ -198,10 +198,9 @@ final class MqttChannelHandler extends SimpleChannelInboundHandler<MqttMessage>
MqttMessageIdVariableHeader variableHeader = MqttMessageIdVariableHeader.from(message.variableHeader().packetId());
MqttMessage pubrecMessage = new MqttMessage(fixedHeader, variableHeader);
MqttIncomingQos2Publish incomingQos2Publish = new MqttIncomingQos2Publish(message, pubrecMessage);
MqttIncomingQos2Publish incomingQos2Publish = new MqttIncomingQos2Publish(message);
this.client.getQos2PendingIncomingPublishes().put(message.variableHeader().packetId(), incomingQos2Publish);
message.payload().retain();
incomingQos2Publish.startPubrecRetransmitTimer(this.client.getEventLoop().next(), this.client::sendAndFlushPacket);
channel.writeAndFlush(pubrecMessage);
}
@ -248,7 +247,6 @@ final class MqttChannelHandler extends SimpleChannelInboundHandler<MqttMessage>
if (this.client.getQos2PendingIncomingPublishes().containsKey(((MqttMessageIdVariableHeader) message.variableHeader()).messageId())) {
MqttIncomingQos2Publish incomingQos2Publish = this.client.getQos2PendingIncomingPublishes().get(((MqttMessageIdVariableHeader) message.variableHeader()).messageId());
this.invokeHandlersForIncomingPublish(incomingQos2Publish.getIncomingPublish());
incomingQos2Publish.onPubrelReceived();
this.client.getQos2PendingIncomingPublishes().remove(incomingQos2Publish.getIncomingPublish().variableHeader().packetId());
}
MqttFixedHeader fixedHeader = new MqttFixedHeader(MqttMessageType.PUBCOMP, false, MqttQoS.AT_MOST_ONCE, false, 0);

21
netty-mqtt/src/main/java/org/thingsboard/mqtt/MqttIncomingQos2Publish.java

@ -15,34 +15,17 @@
*/
package org.thingsboard.mqtt;
import io.netty.channel.EventLoop;
import io.netty.handler.codec.mqtt.*;
import java.util.function.Consumer;
import io.netty.handler.codec.mqtt.MqttPublishMessage;
final class MqttIncomingQos2Publish {
private final MqttPublishMessage incomingPublish;
private final RetransmissionHandler<MqttMessage> retransmissionHandler = new RetransmissionHandler<>();
MqttIncomingQos2Publish(MqttPublishMessage incomingPublish, MqttMessage originalMessage) {
MqttIncomingQos2Publish(MqttPublishMessage incomingPublish) {
this.incomingPublish = incomingPublish;
this.retransmissionHandler.setOriginalMessage(originalMessage);
}
MqttPublishMessage getIncomingPublish() {
return incomingPublish;
}
void startPubrecRetransmitTimer(EventLoop eventLoop, Consumer<Object> sendPacket) {
this.retransmissionHandler.setHandle((fixedHeader, originalMessage) ->
sendPacket.accept(new MqttMessage(fixedHeader, originalMessage.variableHeader())));
this.retransmissionHandler.start(eventLoop);
}
void onPubrelReceived() {
this.retransmissionHandler.stop();
}
}

23
rest-client/pom.xml

@ -45,4 +45,27 @@
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<configuration>
<skip>false</skip>
</configuration>
</plugin>
</plugins>
</build>
</project>

24
rule-engine/rule-engine-api/pom.xml

@ -89,4 +89,28 @@
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<configuration>
<skip>false</skip>
</configuration>
</plugin>
</plugins>
</build>
</project>

5
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbOriginatorTypeSwitchNode.java

@ -27,7 +27,7 @@ import org.thingsboard.server.common.msg.TbMsg;
type = ComponentType.FILTER,
name = "originator type switch",
configClazz = EmptyNodeConfiguration.class,
relationTypes = {"Device", "Asset", "Entity View", "Tenant", "Customer", "User", "Dashboard", "Rule chain", "Rule node"},
relationTypes = {"Device", "Asset", "Alarm", "Entity View", "Tenant", "Customer", "User", "Dashboard", "Rule chain", "Rule node"},
nodeDescription = "Route incoming messages by Message Originator Type",
nodeDetails = "Routes messages to chain according to the originator type ('Device', 'Asset', etc.).",
uiResources = {"static/rulenode/rulenode-core-config.js"},
@ -73,6 +73,9 @@ public class TbOriginatorTypeSwitchNode implements TbNode {
case RULE_NODE:
relationType = "Rule node";
break;
case ALARM:
relationType = "Alarm";
break;
default:
throw new TbNodeException("Unsupported originator type: " + originatorType);
}

84
ui-ngx/src/app/modules/common/modules-map.ts

@ -14,15 +14,53 @@
/// limitations under the License.
///
import * as AngularAnimations from '@angular/animations';
import * as AngularCore from '@angular/core';
import * as AngularCommon from '@angular/common';
import * as AngularForms from '@angular/forms';
import * as AngularFlexLayout from '@angular/flex-layout';
import * as AngularPlatformBrowser from '@angular/platform-browser';
import * as AngularRouter from '@angular/router';
import * as AngularCdkKeycodes from '@angular/cdk/keycodes';
import * as AngularCdkCoercion from '@angular/cdk/coercion';
import * as AngularMaterialChips from '@angular/material/chips';
import * as AngularCdkCollections from '@angular/cdk/collections';
import * as AngularCdkKeycodes from '@angular/cdk/keycodes';
import * as AngularCdkLayout from '@angular/cdk/layout';
import * as AngularCdkOverlay from '@angular/cdk/overlay';
import * as AngularCdkPortal from '@angular/cdk/portal';
import * as AngularMaterialAutocomplete from '@angular/material/autocomplete';
import * as AngularMaterialBadge from '@angular/material/badge';
import * as AngularMaterialBottomSheet from '@angular/material/bottom-sheet';
import * as AngularMaterialButton from '@angular/material/button';
import * as AngularMaterialButtonToggle from '@angular/material/button-toggle';
import * as AngularMaterialCard from '@angular/material/card';
import * as AngularMaterialCheckbox from '@angular/material/checkbox';
import * as AngularMaterialChips from '@angular/material/chips';
import * as AngularMaterialCore from '@angular/material/core';
import * as AngularMaterialDatepicker from '@angular/material/datepicker';
import * as AngularMaterialDialog from '@angular/material/dialog';
import * as AngularMaterialDivider from '@angular/material/divider';
import * as AngularMaterialExpansion from '@angular/material/expansion';
import * as AngularMaterialFormField from '@angular/material/form-field';
import * as AngularMaterialGridList from '@angular/material/grid-list';
import * as AngularMaterialIcon from '@angular/material/icon';
import * as AngularMaterialInput from '@angular/material/input';
import * as AngularMaterialList from '@angular/material/list';
import * as AngularMaterialMenu from '@angular/material/menu';
import * as AngularMaterialPaginator from '@angular/material/paginator';
import * as AngularMaterialProgressBar from '@angular/material/progress-bar';
import * as AngularMaterialProgressSpinner from '@angular/material/progress-spinner';
import * as AngularMaterialRadio from '@angular/material/radio';
import * as AngularMaterialSelect from '@angular/material/select';
import * as AngularMaterialSidenav from '@angular/material/sidenav';
import * as AngularMaterialSlideToggle from '@angular/material/slide-toggle';
import * as AngularMaterialSlider from '@angular/material/slider';
import * as AngularMaterialSnackBar from '@angular/material/snack-bar';
import * as AngularMaterialSort from '@angular/material/sort';
import * as AngularMaterialStepper from '@angular/material/stepper';
import * as AngularMaterialTable from '@angular/material/table';
import * as AngularMaterialTabs from '@angular/material/tabs';
import * as AngularMaterialToolbar from '@angular/material/toolbar';
import * as AngularMaterialTree from '@angular/material/tree';
import * as NgrxStore from '@ngrx/store';
import * as RxJs from 'rxjs';
import * as RxJsOperators from 'rxjs/operators';
@ -35,15 +73,53 @@ import * as _moment from 'moment';
declare const SystemJS;
export const modulesMap: {[key: string]: any} = {
'@angular/animations': SystemJS.newModule(AngularAnimations),
'@angular/core': SystemJS.newModule(AngularCore),
'@angular/common': SystemJS.newModule(AngularCommon),
'@angular/forms': SystemJS.newModule(AngularForms),
'@angular/flex-layout': SystemJS.newModule(AngularFlexLayout),
'@angular/platform-browser': SystemJS.newModule(AngularPlatformBrowser),
'@angular/router': SystemJS.newModule(AngularRouter),
'@angular/cdk/keycodes': SystemJS.newModule(AngularCdkKeycodes),
'@angular/cdk/coercion': SystemJS.newModule(AngularCdkCoercion),
'@angular/material/chips': SystemJS.newModule(AngularMaterialChips),
'@angular/cdk/collections': SystemJS.newModule(AngularCdkCollections),
'@angular/cdk/keycodes': SystemJS.newModule(AngularCdkKeycodes),
'@angular/cdk/layout': SystemJS.newModule(AngularCdkLayout),
'@angular/cdk/overlay': SystemJS.newModule(AngularCdkOverlay),
'@angular/cdk/portal': SystemJS.newModule(AngularCdkPortal),
'@angular/material/autocomplete': SystemJS.newModule(AngularMaterialAutocomplete),
'@angular/material/badge': SystemJS.newModule(AngularMaterialBadge),
'@angular/material/bottom-sheet': SystemJS.newModule(AngularMaterialBottomSheet),
'@angular/material/button': SystemJS.newModule(AngularMaterialButton),
'@angular/material/button-toggle': SystemJS.newModule(AngularMaterialButtonToggle),
'@angular/material/card': SystemJS.newModule(AngularMaterialCard),
'@angular/material/checkbox': SystemJS.newModule(AngularMaterialCheckbox),
'@angular/material/chips': SystemJS.newModule(AngularMaterialChips),
'@angular/material/core': SystemJS.newModule(AngularMaterialCore),
'@angular/material/datepicker': SystemJS.newModule(AngularMaterialDatepicker),
'@angular/material/dialog': SystemJS.newModule(AngularMaterialDialog),
'@angular/material/divider': SystemJS.newModule(AngularMaterialDivider),
'@angular/material/expansion': SystemJS.newModule(AngularMaterialExpansion),
'@angular/material/form-field': SystemJS.newModule(AngularMaterialFormField),
'@angular/material/grid-list': SystemJS.newModule(AngularMaterialGridList),
'@angular/material/icon': SystemJS.newModule(AngularMaterialIcon),
'@angular/material/input': SystemJS.newModule(AngularMaterialInput),
'@angular/material/list': SystemJS.newModule(AngularMaterialList),
'@angular/material/menu': SystemJS.newModule(AngularMaterialMenu),
'@angular/material/paginator': SystemJS.newModule(AngularMaterialPaginator),
'@angular/material/progress-bar': SystemJS.newModule(AngularMaterialProgressBar),
'@angular/material/progress-spinner': SystemJS.newModule(AngularMaterialProgressSpinner),
'@angular/material/radio': SystemJS.newModule(AngularMaterialRadio),
'@angular/material/select': SystemJS.newModule(AngularMaterialSelect),
'@angular/material/sidenav': SystemJS.newModule(AngularMaterialSidenav),
'@angular/material/slide-toggle': SystemJS.newModule(AngularMaterialSlideToggle),
'@angular/material/slider': SystemJS.newModule(AngularMaterialSlider),
'@angular/material/snack-bar': SystemJS.newModule(AngularMaterialSnackBar),
'@angular/material/sort': SystemJS.newModule(AngularMaterialSort),
'@angular/material/stepper': SystemJS.newModule(AngularMaterialStepper),
'@angular/material/table': SystemJS.newModule(AngularMaterialTable),
'@angular/material/tabs': SystemJS.newModule(AngularMaterialTabs),
'@angular/material/toolbar': SystemJS.newModule(AngularMaterialToolbar),
'@angular/material/tree': SystemJS.newModule(AngularMaterialTree),
'@ngrx/store': SystemJS.newModule(NgrxStore),
rxjs: SystemJS.newModule(RxJs),
'rxjs/operators': SystemJS.newModule(RxJsOperators),

9
ui-ngx/src/app/modules/home/pages/dashboard/states/state-controller.component.ts

@ -100,7 +100,7 @@ export abstract class StateControllerComponent implements IStateControllerCompon
this.rxSubscriptions.push(this.route.queryParamMap.subscribe((paramMap) => {
const dashboardId = this.route.snapshot.params.dashboardId;
if (this.dashboardId === dashboardId) {
const newState = decodeURIComponent(paramMap.get('state'));
const newState = this.decodeStateParam(paramMap.get('state'));
if (this.currentState !== newState) {
this.currentState = newState;
if (this.inited) {
@ -147,10 +147,15 @@ export abstract class StateControllerComponent implements IStateControllerCompon
}
public reInit() {
this.currentState = decodeURIComponent(this.route.snapshot.queryParamMap.get('state'));
this.preservedState = null;
this.currentState = this.decodeStateParam(this.route.snapshot.queryParamMap.get('state'));
this.init();
}
private decodeStateParam(stateURI: string): string{
return stateURI !== null ? decodeURIComponent(stateURI) : null;
}
protected abstract init();
protected abstract onMobileChanged();

Loading…
Cancel
Save