Merge branch 'rc' of github.com:thingsboard/thingsboard into cf-fixes
This commit is contained in:
commit
5ee6d41f77
@ -30,13 +30,12 @@ import org.thingsboard.server.common.msg.queue.TbCallback;
|
|||||||
import org.thingsboard.server.common.msg.queue.TopicPartitionInfo;
|
import org.thingsboard.server.common.msg.queue.TopicPartitionInfo;
|
||||||
import org.thingsboard.server.gen.transport.TransportProtos.CalculatedFieldStateProto;
|
import org.thingsboard.server.gen.transport.TransportProtos.CalculatedFieldStateProto;
|
||||||
import org.thingsboard.server.gen.transport.TransportProtos.ToCalculatedFieldMsg;
|
import org.thingsboard.server.gen.transport.TransportProtos.ToCalculatedFieldMsg;
|
||||||
import org.thingsboard.server.queue.TbQueueAdmin;
|
|
||||||
import org.thingsboard.server.queue.TbQueueCallback;
|
import org.thingsboard.server.queue.TbQueueCallback;
|
||||||
import org.thingsboard.server.queue.TbQueueMsgHeaders;
|
import org.thingsboard.server.queue.TbQueueMsgHeaders;
|
||||||
import org.thingsboard.server.queue.TbQueueMsgMetadata;
|
import org.thingsboard.server.queue.TbQueueMsgMetadata;
|
||||||
import org.thingsboard.server.queue.common.TbProtoQueueMsg;
|
import org.thingsboard.server.queue.common.TbProtoQueueMsg;
|
||||||
import org.thingsboard.server.queue.common.state.KafkaQueueStateService;
|
|
||||||
import org.thingsboard.server.queue.common.consumer.PartitionedQueueConsumerManager;
|
import org.thingsboard.server.queue.common.consumer.PartitionedQueueConsumerManager;
|
||||||
|
import org.thingsboard.server.queue.common.state.KafkaQueueStateService;
|
||||||
import org.thingsboard.server.queue.discovery.PartitionService;
|
import org.thingsboard.server.queue.discovery.PartitionService;
|
||||||
import org.thingsboard.server.queue.discovery.QueueKey;
|
import org.thingsboard.server.queue.discovery.QueueKey;
|
||||||
import org.thingsboard.server.queue.kafka.TbKafkaProducerTemplate;
|
import org.thingsboard.server.queue.kafka.TbKafkaProducerTemplate;
|
||||||
@ -59,7 +58,6 @@ public class KafkaCalculatedFieldStateService extends AbstractCalculatedFieldSta
|
|||||||
|
|
||||||
private final TbRuleEngineQueueFactory queueFactory;
|
private final TbRuleEngineQueueFactory queueFactory;
|
||||||
private final PartitionService partitionService;
|
private final PartitionService partitionService;
|
||||||
private final TbQueueAdmin queueAdmin;
|
|
||||||
|
|
||||||
@Value("${queue.calculated_fields.poll_interval:25}")
|
@Value("${queue.calculated_fields.poll_interval:25}")
|
||||||
private long pollInterval;
|
private long pollInterval;
|
||||||
@ -94,7 +92,7 @@ public class KafkaCalculatedFieldStateService extends AbstractCalculatedFieldSta
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
.consumerCreator((config, partitionId) -> queueFactory.createCalculatedFieldStateConsumer())
|
.consumerCreator((config, partitionId) -> queueFactory.createCalculatedFieldStateConsumer())
|
||||||
.queueAdmin(queueAdmin)
|
.queueAdmin(queueFactory.getCalculatedFieldQueueAdmin())
|
||||||
.consumerExecutor(eventConsumer.getConsumerExecutor())
|
.consumerExecutor(eventConsumer.getConsumerExecutor())
|
||||||
.scheduler(eventConsumer.getScheduler())
|
.scheduler(eventConsumer.getScheduler())
|
||||||
.taskExecutor(eventConsumer.getTaskExecutor())
|
.taskExecutor(eventConsumer.getTaskExecutor())
|
||||||
|
|||||||
@ -42,7 +42,6 @@ import org.thingsboard.server.gen.transport.TransportProtos.CalculatedFieldLinke
|
|||||||
import org.thingsboard.server.gen.transport.TransportProtos.CalculatedFieldTelemetryMsgProto;
|
import org.thingsboard.server.gen.transport.TransportProtos.CalculatedFieldTelemetryMsgProto;
|
||||||
import org.thingsboard.server.gen.transport.TransportProtos.ToCalculatedFieldMsg;
|
import org.thingsboard.server.gen.transport.TransportProtos.ToCalculatedFieldMsg;
|
||||||
import org.thingsboard.server.gen.transport.TransportProtos.ToCalculatedFieldNotificationMsg;
|
import org.thingsboard.server.gen.transport.TransportProtos.ToCalculatedFieldNotificationMsg;
|
||||||
import org.thingsboard.server.queue.TbQueueAdmin;
|
|
||||||
import org.thingsboard.server.queue.TbQueueConsumer;
|
import org.thingsboard.server.queue.TbQueueConsumer;
|
||||||
import org.thingsboard.server.queue.common.TbProtoQueueMsg;
|
import org.thingsboard.server.queue.common.TbProtoQueueMsg;
|
||||||
import org.thingsboard.server.queue.common.consumer.PartitionedQueueConsumerManager;
|
import org.thingsboard.server.queue.common.consumer.PartitionedQueueConsumerManager;
|
||||||
@ -81,7 +80,6 @@ public class DefaultTbCalculatedFieldConsumerService extends AbstractConsumerSer
|
|||||||
private long packProcessingTimeout;
|
private long packProcessingTimeout;
|
||||||
|
|
||||||
private final TbRuleEngineQueueFactory queueFactory;
|
private final TbRuleEngineQueueFactory queueFactory;
|
||||||
private final TbQueueAdmin queueAdmin;
|
|
||||||
private final CalculatedFieldStateService stateService;
|
private final CalculatedFieldStateService stateService;
|
||||||
|
|
||||||
public DefaultTbCalculatedFieldConsumerService(TbRuleEngineQueueFactory tbQueueFactory,
|
public DefaultTbCalculatedFieldConsumerService(TbRuleEngineQueueFactory tbQueueFactory,
|
||||||
@ -94,12 +92,10 @@ public class DefaultTbCalculatedFieldConsumerService extends AbstractConsumerSer
|
|||||||
ApplicationEventPublisher eventPublisher,
|
ApplicationEventPublisher eventPublisher,
|
||||||
JwtSettingsService jwtSettingsService,
|
JwtSettingsService jwtSettingsService,
|
||||||
CalculatedFieldCache calculatedFieldCache,
|
CalculatedFieldCache calculatedFieldCache,
|
||||||
TbQueueAdmin queueAdmin,
|
|
||||||
CalculatedFieldStateService stateService) {
|
CalculatedFieldStateService stateService) {
|
||||||
super(actorContext, tenantProfileCache, deviceProfileCache, assetProfileCache, calculatedFieldCache, apiUsageStateService, partitionService,
|
super(actorContext, tenantProfileCache, deviceProfileCache, assetProfileCache, calculatedFieldCache, apiUsageStateService, partitionService,
|
||||||
eventPublisher, jwtSettingsService);
|
eventPublisher, jwtSettingsService);
|
||||||
this.queueFactory = tbQueueFactory;
|
this.queueFactory = tbQueueFactory;
|
||||||
this.queueAdmin = queueAdmin;
|
|
||||||
this.stateService = stateService;
|
this.stateService = stateService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,7 +110,7 @@ public class DefaultTbCalculatedFieldConsumerService extends AbstractConsumerSer
|
|||||||
.pollInterval(pollInterval)
|
.pollInterval(pollInterval)
|
||||||
.msgPackProcessor(this::processMsgs)
|
.msgPackProcessor(this::processMsgs)
|
||||||
.consumerCreator((config, partitionId) -> queueFactory.createToCalculatedFieldMsgConsumer())
|
.consumerCreator((config, partitionId) -> queueFactory.createToCalculatedFieldMsgConsumer())
|
||||||
.queueAdmin(queueAdmin)
|
.queueAdmin(queueFactory.getCalculatedFieldQueueAdmin())
|
||||||
.consumerExecutor(consumersExecutor)
|
.consumerExecutor(consumersExecutor)
|
||||||
.scheduler(scheduler)
|
.scheduler(scheduler)
|
||||||
.taskExecutor(mgmtExecutor)
|
.taskExecutor(mgmtExecutor)
|
||||||
|
|||||||
@ -121,14 +121,14 @@ public class AssetProfileEdgeTest extends AbstractEdgeTest {
|
|||||||
Assert.assertNull(assetProfile.getDefaultRuleChainId());
|
Assert.assertNull(assetProfile.getDefaultRuleChainId());
|
||||||
Assert.assertEquals(edgeRuleChainId, assetProfile.getDefaultEdgeRuleChainId());
|
Assert.assertEquals(edgeRuleChainId, assetProfile.getDefaultEdgeRuleChainId());
|
||||||
|
|
||||||
// delete profile
|
// delete profile and delete relation messages
|
||||||
edgeImitator.expectMessageAmount(1);
|
edgeImitator.expectMessageAmount(2);
|
||||||
doDelete("/api/assetProfile/" + assetProfile.getUuidId())
|
doDelete("/api/assetProfile/" + assetProfile.getUuidId())
|
||||||
.andExpect(status().isOk());
|
.andExpect(status().isOk());
|
||||||
Assert.assertTrue(edgeImitator.waitForMessages());
|
Assert.assertTrue(edgeImitator.waitForMessages());
|
||||||
AbstractMessage latestMessage = edgeImitator.getLatestMessage();
|
Optional<AssetProfileUpdateMsg> assetDeleteMsgOpt = edgeImitator.findMessageByType(AssetProfileUpdateMsg.class);
|
||||||
Assert.assertTrue(latestMessage instanceof AssetProfileUpdateMsg);
|
Assert.assertTrue(assetDeleteMsgOpt.isPresent());
|
||||||
AssetProfileUpdateMsg assetProfileUpdateMsg = (AssetProfileUpdateMsg) latestMessage;
|
AssetProfileUpdateMsg assetProfileUpdateMsg = assetDeleteMsgOpt.get();
|
||||||
Assert.assertEquals(UpdateMsgType.ENTITY_DELETED_RPC_MESSAGE, assetProfileUpdateMsg.getMsgType());
|
Assert.assertEquals(UpdateMsgType.ENTITY_DELETED_RPC_MESSAGE, assetProfileUpdateMsg.getMsgType());
|
||||||
Assert.assertEquals(assetProfile.getUuidId().getMostSignificantBits(), assetProfileUpdateMsg.getIdMSB());
|
Assert.assertEquals(assetProfile.getUuidId().getMostSignificantBits(), assetProfileUpdateMsg.getIdMSB());
|
||||||
Assert.assertEquals(assetProfile.getUuidId().getLeastSignificantBits(), assetProfileUpdateMsg.getIdLSB());
|
Assert.assertEquals(assetProfile.getUuidId().getLeastSignificantBits(), assetProfileUpdateMsg.getIdLSB());
|
||||||
|
|||||||
@ -327,14 +327,14 @@ public class DeviceProfileEdgeTest extends AbstractEdgeTest {
|
|||||||
Assert.assertNotNull(deviceProfile);
|
Assert.assertNotNull(deviceProfile);
|
||||||
Assert.assertEquals("Device Profile On Edge", deviceProfile.getName());
|
Assert.assertEquals("Device Profile On Edge", deviceProfile.getName());
|
||||||
|
|
||||||
// delete profile
|
// delete profile and delete relation messages
|
||||||
edgeImitator.expectMessageAmount(1);
|
edgeImitator.expectMessageAmount(2);
|
||||||
doDelete("/api/deviceProfile/" + deviceProfile.getUuidId())
|
doDelete("/api/deviceProfile/" + deviceProfile.getUuidId())
|
||||||
.andExpect(status().isOk());
|
.andExpect(status().isOk());
|
||||||
Assert.assertTrue(edgeImitator.waitForMessages());
|
Assert.assertTrue(edgeImitator.waitForMessages());
|
||||||
AbstractMessage latestMessage = edgeImitator.getLatestMessage();
|
Optional<DeviceProfileUpdateMsg> deviceDeleteMsgOpt = edgeImitator.findMessageByType(DeviceProfileUpdateMsg.class);
|
||||||
Assert.assertTrue(latestMessage instanceof DeviceProfileUpdateMsg);
|
Assert.assertTrue(deviceDeleteMsgOpt.isPresent());
|
||||||
DeviceProfileUpdateMsg deviceProfileUpdateMsg = (DeviceProfileUpdateMsg) latestMessage;
|
DeviceProfileUpdateMsg deviceProfileUpdateMsg = deviceDeleteMsgOpt.get();
|
||||||
Assert.assertEquals(UpdateMsgType.ENTITY_DELETED_RPC_MESSAGE, deviceProfileUpdateMsg.getMsgType());
|
Assert.assertEquals(UpdateMsgType.ENTITY_DELETED_RPC_MESSAGE, deviceProfileUpdateMsg.getMsgType());
|
||||||
Assert.assertEquals(deviceProfile.getUuidId().getMostSignificantBits(), deviceProfileUpdateMsg.getIdMSB());
|
Assert.assertEquals(deviceProfile.getUuidId().getMostSignificantBits(), deviceProfileUpdateMsg.getIdMSB());
|
||||||
Assert.assertEquals(deviceProfile.getUuidId().getLeastSignificantBits(), deviceProfileUpdateMsg.getIdLSB());
|
Assert.assertEquals(deviceProfile.getUuidId().getLeastSignificantBits(), deviceProfileUpdateMsg.getIdLSB());
|
||||||
|
|||||||
@ -53,7 +53,6 @@ import org.thingsboard.server.gen.transport.TransportProtos;
|
|||||||
import org.thingsboard.server.gen.transport.TransportProtos.EdqsEventMsg;
|
import org.thingsboard.server.gen.transport.TransportProtos.EdqsEventMsg;
|
||||||
import org.thingsboard.server.gen.transport.TransportProtos.FromEdqsMsg;
|
import org.thingsboard.server.gen.transport.TransportProtos.FromEdqsMsg;
|
||||||
import org.thingsboard.server.gen.transport.TransportProtos.ToEdqsMsg;
|
import org.thingsboard.server.gen.transport.TransportProtos.ToEdqsMsg;
|
||||||
import org.thingsboard.server.queue.TbQueueAdmin;
|
|
||||||
import org.thingsboard.server.queue.TbQueueHandler;
|
import org.thingsboard.server.queue.TbQueueHandler;
|
||||||
import org.thingsboard.server.queue.TbQueueResponseTemplate;
|
import org.thingsboard.server.queue.TbQueueResponseTemplate;
|
||||||
import org.thingsboard.server.queue.common.TbProtoQueueMsg;
|
import org.thingsboard.server.queue.common.TbProtoQueueMsg;
|
||||||
@ -92,7 +91,6 @@ public class EdqsProcessor implements TbQueueHandler<TbProtoQueueMsg<ToEdqsMsg>,
|
|||||||
private final EdqsPartitionService partitionService;
|
private final EdqsPartitionService partitionService;
|
||||||
private final ConfigurableApplicationContext applicationContext;
|
private final ConfigurableApplicationContext applicationContext;
|
||||||
private final EdqsStateService stateService;
|
private final EdqsStateService stateService;
|
||||||
private final TbQueueAdmin queueAdmin;
|
|
||||||
|
|
||||||
private PartitionedQueueConsumerManager<TbProtoQueueMsg<ToEdqsMsg>> eventConsumer;
|
private PartitionedQueueConsumerManager<TbProtoQueueMsg<ToEdqsMsg>> eventConsumer;
|
||||||
private TbQueueResponseTemplate<TbProtoQueueMsg<ToEdqsMsg>, TbProtoQueueMsg<FromEdqsMsg>> responseTemplate;
|
private TbQueueResponseTemplate<TbProtoQueueMsg<ToEdqsMsg>, TbProtoQueueMsg<FromEdqsMsg>> responseTemplate;
|
||||||
@ -143,7 +141,7 @@ public class EdqsProcessor implements TbQueueHandler<TbProtoQueueMsg<ToEdqsMsg>,
|
|||||||
consumer.commit();
|
consumer.commit();
|
||||||
})
|
})
|
||||||
.consumerCreator((config, partitionId) -> queueFactory.createEdqsMsgConsumer(EdqsQueue.EVENTS))
|
.consumerCreator((config, partitionId) -> queueFactory.createEdqsMsgConsumer(EdqsQueue.EVENTS))
|
||||||
.queueAdmin(queueAdmin)
|
.queueAdmin(queueFactory.getEdqsQueueAdmin())
|
||||||
.consumerExecutor(consumersExecutor)
|
.consumerExecutor(consumersExecutor)
|
||||||
.taskExecutor(taskExecutor)
|
.taskExecutor(taskExecutor)
|
||||||
.scheduler(scheduler)
|
.scheduler(scheduler)
|
||||||
|
|||||||
@ -30,7 +30,6 @@ import org.thingsboard.server.edqs.processor.EdqsProducer;
|
|||||||
import org.thingsboard.server.edqs.util.VersionsStore;
|
import org.thingsboard.server.edqs.util.VersionsStore;
|
||||||
import org.thingsboard.server.gen.transport.TransportProtos.EdqsEventMsg;
|
import org.thingsboard.server.gen.transport.TransportProtos.EdqsEventMsg;
|
||||||
import org.thingsboard.server.gen.transport.TransportProtos.ToEdqsMsg;
|
import org.thingsboard.server.gen.transport.TransportProtos.ToEdqsMsg;
|
||||||
import org.thingsboard.server.queue.TbQueueAdmin;
|
|
||||||
import org.thingsboard.server.queue.common.TbProtoQueueMsg;
|
import org.thingsboard.server.queue.common.TbProtoQueueMsg;
|
||||||
import org.thingsboard.server.queue.common.consumer.PartitionedQueueConsumerManager;
|
import org.thingsboard.server.queue.common.consumer.PartitionedQueueConsumerManager;
|
||||||
import org.thingsboard.server.queue.common.consumer.QueueConsumerManager;
|
import org.thingsboard.server.queue.common.consumer.QueueConsumerManager;
|
||||||
@ -56,7 +55,6 @@ public class KafkaEdqsStateService implements EdqsStateService {
|
|||||||
private final EdqsConfig config;
|
private final EdqsConfig config;
|
||||||
private final EdqsPartitionService partitionService;
|
private final EdqsPartitionService partitionService;
|
||||||
private final EdqsQueueFactory queueFactory;
|
private final EdqsQueueFactory queueFactory;
|
||||||
private final TbQueueAdmin queueAdmin;
|
|
||||||
private final TopicService topicService;
|
private final TopicService topicService;
|
||||||
@Autowired @Lazy
|
@Autowired @Lazy
|
||||||
private EdqsProcessor edqsProcessor;
|
private EdqsProcessor edqsProcessor;
|
||||||
@ -92,7 +90,7 @@ public class KafkaEdqsStateService implements EdqsStateService {
|
|||||||
consumer.commit();
|
consumer.commit();
|
||||||
})
|
})
|
||||||
.consumerCreator((config, partitionId) -> queueFactory.createEdqsMsgConsumer(EdqsQueue.STATE))
|
.consumerCreator((config, partitionId) -> queueFactory.createEdqsMsgConsumer(EdqsQueue.STATE))
|
||||||
.queueAdmin(queueAdmin)
|
.queueAdmin(queueFactory.getEdqsQueueAdmin())
|
||||||
.consumerExecutor(eventConsumer.getConsumerExecutor())
|
.consumerExecutor(eventConsumer.getConsumerExecutor())
|
||||||
.taskExecutor(eventConsumer.getTaskExecutor())
|
.taskExecutor(eventConsumer.getTaskExecutor())
|
||||||
.scheduler(eventConsumer.getScheduler())
|
.scheduler(eventConsumer.getScheduler())
|
||||||
|
|||||||
@ -17,6 +17,7 @@ package org.thingsboard.server.queue.edqs;
|
|||||||
|
|
||||||
import org.thingsboard.server.gen.transport.TransportProtos.FromEdqsMsg;
|
import org.thingsboard.server.gen.transport.TransportProtos.FromEdqsMsg;
|
||||||
import org.thingsboard.server.gen.transport.TransportProtos.ToEdqsMsg;
|
import org.thingsboard.server.gen.transport.TransportProtos.ToEdqsMsg;
|
||||||
|
import org.thingsboard.server.queue.TbQueueAdmin;
|
||||||
import org.thingsboard.server.queue.TbQueueConsumer;
|
import org.thingsboard.server.queue.TbQueueConsumer;
|
||||||
import org.thingsboard.server.queue.TbQueueProducer;
|
import org.thingsboard.server.queue.TbQueueProducer;
|
||||||
import org.thingsboard.server.queue.TbQueueResponseTemplate;
|
import org.thingsboard.server.queue.TbQueueResponseTemplate;
|
||||||
@ -32,4 +33,6 @@ public interface EdqsQueueFactory {
|
|||||||
|
|
||||||
TbQueueResponseTemplate<TbProtoQueueMsg<ToEdqsMsg>, TbProtoQueueMsg<FromEdqsMsg>> createEdqsResponseTemplate();
|
TbQueueResponseTemplate<TbProtoQueueMsg<ToEdqsMsg>, TbProtoQueueMsg<FromEdqsMsg>> createEdqsResponseTemplate();
|
||||||
|
|
||||||
|
TbQueueAdmin getEdqsQueueAdmin();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,6 +22,7 @@ import org.thingsboard.server.common.stats.StatsFactory;
|
|||||||
import org.thingsboard.server.common.stats.StatsType;
|
import org.thingsboard.server.common.stats.StatsType;
|
||||||
import org.thingsboard.server.gen.transport.TransportProtos.FromEdqsMsg;
|
import org.thingsboard.server.gen.transport.TransportProtos.FromEdqsMsg;
|
||||||
import org.thingsboard.server.gen.transport.TransportProtos.ToEdqsMsg;
|
import org.thingsboard.server.gen.transport.TransportProtos.ToEdqsMsg;
|
||||||
|
import org.thingsboard.server.queue.TbQueueAdmin;
|
||||||
import org.thingsboard.server.queue.TbQueueConsumer;
|
import org.thingsboard.server.queue.TbQueueConsumer;
|
||||||
import org.thingsboard.server.queue.TbQueueProducer;
|
import org.thingsboard.server.queue.TbQueueProducer;
|
||||||
import org.thingsboard.server.queue.TbQueueResponseTemplate;
|
import org.thingsboard.server.queue.TbQueueResponseTemplate;
|
||||||
@ -39,6 +40,7 @@ public class InMemoryEdqsQueueFactory implements EdqsQueueFactory {
|
|||||||
private final InMemoryStorage storage;
|
private final InMemoryStorage storage;
|
||||||
private final EdqsConfig edqsConfig;
|
private final EdqsConfig edqsConfig;
|
||||||
private final StatsFactory statsFactory;
|
private final StatsFactory statsFactory;
|
||||||
|
private final TbQueueAdmin queueAdmin;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TbQueueConsumer<TbProtoQueueMsg<ToEdqsMsg>> createEdqsMsgConsumer(EdqsQueue queue) {
|
public TbQueueConsumer<TbProtoQueueMsg<ToEdqsMsg>> createEdqsMsgConsumer(EdqsQueue queue) {
|
||||||
@ -76,4 +78,9 @@ public class InMemoryEdqsQueueFactory implements EdqsQueueFactory {
|
|||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TbQueueAdmin getEdqsQueueAdmin() {
|
||||||
|
return queueAdmin;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,6 +22,7 @@ import org.thingsboard.server.common.stats.StatsType;
|
|||||||
import org.thingsboard.server.gen.transport.TransportProtos;
|
import org.thingsboard.server.gen.transport.TransportProtos;
|
||||||
import org.thingsboard.server.gen.transport.TransportProtos.FromEdqsMsg;
|
import org.thingsboard.server.gen.transport.TransportProtos.FromEdqsMsg;
|
||||||
import org.thingsboard.server.gen.transport.TransportProtos.ToEdqsMsg;
|
import org.thingsboard.server.gen.transport.TransportProtos.ToEdqsMsg;
|
||||||
|
import org.thingsboard.server.queue.TbQueueAdmin;
|
||||||
import org.thingsboard.server.queue.TbQueueConsumer;
|
import org.thingsboard.server.queue.TbQueueConsumer;
|
||||||
import org.thingsboard.server.queue.TbQueueProducer;
|
import org.thingsboard.server.queue.TbQueueProducer;
|
||||||
import org.thingsboard.server.queue.TbQueueResponseTemplate;
|
import org.thingsboard.server.queue.TbQueueResponseTemplate;
|
||||||
@ -126,4 +127,9 @@ public class KafkaEdqsQueueFactory implements EdqsQueueFactory {
|
|||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TbQueueAdmin getEdqsQueueAdmin() {
|
||||||
|
return edqsEventsAdmin;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -160,7 +160,7 @@ public class TbKafkaConsumerTemplate<T extends TbQueueMsg> extends AbstractTbQue
|
|||||||
int partition = record.partition();
|
int partition = record.partition();
|
||||||
Long endOffset = endOffsets.get(partition);
|
Long endOffset = endOffsets.get(partition);
|
||||||
if (endOffset == null) {
|
if (endOffset == null) {
|
||||||
log.warn("End offset not found for {} [{}]", record.topic(), partition);
|
log.debug("End offset not found for {} [{}]", record.topic(), partition);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
log.trace("[{}-{}] Got record offset {}, expected end offset: {}", record.topic(), partition, record.offset(), endOffset - 1);
|
log.trace("[{}-{}] Got record offset {}, expected end offset: {}", record.topic(), partition, record.offset(), endOffset - 1);
|
||||||
|
|||||||
@ -138,6 +138,11 @@ public class InMemoryMonolithQueueFactory implements TbCoreQueueFactory, TbRuleE
|
|||||||
return new InMemoryTbQueueConsumer<>(storage, topicService.buildTopicName(calculatedFieldSettings.getEventTopic()));
|
return new InMemoryTbQueueConsumer<>(storage, topicService.buildTopicName(calculatedFieldSettings.getEventTopic()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TbQueueAdmin getCalculatedFieldQueueAdmin() {
|
||||||
|
return queueAdmin;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TbQueueProducer<TbProtoQueueMsg<TransportProtos.ToCalculatedFieldMsg>> createToCalculatedFieldMsgProducer() {
|
public TbQueueProducer<TbProtoQueueMsg<TransportProtos.ToCalculatedFieldMsg>> createToCalculatedFieldMsgProducer() {
|
||||||
return new InMemoryTbQueueProducer<>(storage, topicService.buildTopicName(calculatedFieldSettings.getEventTopic()));
|
return new InMemoryTbQueueProducer<>(storage, topicService.buildTopicName(calculatedFieldSettings.getEventTopic()));
|
||||||
|
|||||||
@ -526,6 +526,11 @@ public class KafkaMonolithQueueFactory implements TbCoreQueueFactory, TbRuleEngi
|
|||||||
return consumerBuilder.build();
|
return consumerBuilder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TbQueueAdmin getCalculatedFieldQueueAdmin() {
|
||||||
|
return cfAdmin;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TbQueueProducer<TbProtoQueueMsg<ToCalculatedFieldMsg>> createToCalculatedFieldMsgProducer() {
|
public TbQueueProducer<TbProtoQueueMsg<ToCalculatedFieldMsg>> createToCalculatedFieldMsgProducer() {
|
||||||
TbKafkaProducerTemplate.TbKafkaProducerTemplateBuilder<TbProtoQueueMsg<ToCalculatedFieldMsg>> requestBuilder = TbKafkaProducerTemplate.builder();
|
TbKafkaProducerTemplate.TbKafkaProducerTemplateBuilder<TbProtoQueueMsg<ToCalculatedFieldMsg>> requestBuilder = TbKafkaProducerTemplate.builder();
|
||||||
|
|||||||
@ -321,6 +321,11 @@ public class KafkaTbRuleEngineQueueFactory implements TbRuleEngineQueueFactory {
|
|||||||
return consumerBuilder.build();
|
return consumerBuilder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TbQueueAdmin getCalculatedFieldQueueAdmin() {
|
||||||
|
return cfAdmin;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TbQueueProducer<TbProtoQueueMsg<ToCalculatedFieldMsg>> createToCalculatedFieldMsgProducer() {
|
public TbQueueProducer<TbProtoQueueMsg<ToCalculatedFieldMsg>> createToCalculatedFieldMsgProducer() {
|
||||||
TbKafkaProducerTemplate.TbKafkaProducerTemplateBuilder<TbProtoQueueMsg<ToCalculatedFieldMsg>> requestBuilder = TbKafkaProducerTemplate.builder();
|
TbKafkaProducerTemplate.TbKafkaProducerTemplateBuilder<TbProtoQueueMsg<ToCalculatedFieldMsg>> requestBuilder = TbKafkaProducerTemplate.builder();
|
||||||
|
|||||||
@ -29,6 +29,7 @@ import org.thingsboard.server.gen.transport.TransportProtos.ToOtaPackageStateSer
|
|||||||
import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg;
|
import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineMsg;
|
||||||
import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineNotificationMsg;
|
import org.thingsboard.server.gen.transport.TransportProtos.ToRuleEngineNotificationMsg;
|
||||||
import org.thingsboard.server.gen.transport.TransportProtos.ToTransportMsg;
|
import org.thingsboard.server.gen.transport.TransportProtos.ToTransportMsg;
|
||||||
|
import org.thingsboard.server.queue.TbQueueAdmin;
|
||||||
import org.thingsboard.server.queue.TbQueueConsumer;
|
import org.thingsboard.server.queue.TbQueueConsumer;
|
||||||
import org.thingsboard.server.queue.TbQueueProducer;
|
import org.thingsboard.server.queue.TbQueueProducer;
|
||||||
import org.thingsboard.server.queue.TbQueueRequestTemplate;
|
import org.thingsboard.server.queue.TbQueueRequestTemplate;
|
||||||
@ -122,6 +123,8 @@ public interface TbRuleEngineQueueFactory extends TbUsageStatsClientQueueFactory
|
|||||||
|
|
||||||
TbQueueConsumer<TbProtoQueueMsg<ToCalculatedFieldMsg>> createToCalculatedFieldMsgConsumer();
|
TbQueueConsumer<TbProtoQueueMsg<ToCalculatedFieldMsg>> createToCalculatedFieldMsgConsumer();
|
||||||
|
|
||||||
|
TbQueueAdmin getCalculatedFieldQueueAdmin();
|
||||||
|
|
||||||
TbQueueProducer<TbProtoQueueMsg<ToCalculatedFieldMsg>> createToCalculatedFieldMsgProducer();
|
TbQueueProducer<TbProtoQueueMsg<ToCalculatedFieldMsg>> createToCalculatedFieldMsgProducer();
|
||||||
|
|
||||||
TbQueueConsumer<TbProtoQueueMsg<ToCalculatedFieldNotificationMsg>> createToCalculatedFieldNotificationMsgConsumer();
|
TbQueueConsumer<TbProtoQueueMsg<ToCalculatedFieldNotificationMsg>> createToCalculatedFieldNotificationMsgConsumer();
|
||||||
|
|||||||
@ -195,7 +195,9 @@ public class BaseTimeseriesService implements TimeseriesService {
|
|||||||
}
|
}
|
||||||
if (saveLatest) {
|
if (saveLatest) {
|
||||||
latestFutures.add(Futures.transform(timeseriesLatestDao.saveLatest(tenantId, entityId, tsKvEntry), version -> {
|
latestFutures.add(Futures.transform(timeseriesLatestDao.saveLatest(tenantId, entityId, tsKvEntry), version -> {
|
||||||
edqsService.onUpdate(tenantId, ObjectType.LATEST_TS_KV, new LatestTsKv(entityId, tsKvEntry, version));
|
if (version != null) {
|
||||||
|
edqsService.onUpdate(tenantId, ObjectType.LATEST_TS_KV, new LatestTsKv(entityId, tsKvEntry, version));
|
||||||
|
}
|
||||||
return version;
|
return version;
|
||||||
}, MoreExecutors.directExecutor()));
|
}, MoreExecutors.directExecutor()));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,17 +15,15 @@
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
|
|
||||||
-->
|
-->
|
||||||
<div class="flex max-w-sm flex-col gap-3 p-2">
|
<div class="flex w-96 flex-col gap-3 p-2">
|
||||||
<div class="tb-form-panel-title" translate>debug-settings.label</div>
|
<div class="tb-form-panel-title" translate>debug-settings.label</div>
|
||||||
<div class="hint-container">
|
@if (debugLimitsConfiguration) {
|
||||||
<div class="tb-form-hint tb-primary-fill tb-flex center">
|
<div class="hint-container">
|
||||||
@if (debugLimitsConfiguration) {
|
<div class="tb-form-hint tb-primary-fill tb-flex center">
|
||||||
{{ 'debug-settings.hint.main-limited' | translate: { entity: entityLabel ?? ('debug-settings.entity' | translate), msg: maxMessagesCount, time: (maxTimeFrameDuration | milliSecondsToTimeString: true : true) } }}
|
{{ 'debug-settings.hint.main-limited' | translate: { entity: entityLabel ?? ('debug-settings.entity' | translate), msg: maxMessagesCount, time: (maxTimeFrameDuration | milliSecondsToTimeString: true : true) } }}
|
||||||
} @else {
|
</div>
|
||||||
{{ 'debug-settings.hint.main' | translate }}
|
|
||||||
}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
}
|
||||||
<div class="flex flex-col gap-3">
|
<div class="flex flex-col gap-3">
|
||||||
<mat-slide-toggle class="mat-slide" [formControl]="onFailuresControl">
|
<mat-slide-toggle class="mat-slide" [formControl]="onFailuresControl">
|
||||||
<div tb-hint-tooltip-icon="{{ 'debug-settings.hint.on-failure' | translate }}">
|
<div tb-hint-tooltip-icon="{{ 'debug-settings.hint.on-failure' | translate }}">
|
||||||
@ -33,12 +31,12 @@
|
|||||||
</div>
|
</div>
|
||||||
</mat-slide-toggle>
|
</mat-slide-toggle>
|
||||||
<div class="align-center flex justify-between">
|
<div class="align-center flex justify-between">
|
||||||
<mat-slide-toggle class="mat-slide" [formControl]="debugAllControl">
|
<mat-slide-toggle class="mat-slide" [formControl]="debugAllControl" (change)="debugAllControl.markAsTouched()">
|
||||||
<div tb-hint-tooltip-icon="{{ 'debug-settings.hint.all-messages' | translate }}">
|
<div tb-hint-tooltip-icon="{{ 'debug-settings.hint.all-messages' | translate }}">
|
||||||
{{ 'debug-settings.all-messages' | translate: { time: (isDebugAllActive$ | async) && !allEnabled ? (allEnabledUntil | durationLeft) : (maxDebugModeDuration | milliSecondsToTimeString: true : true) } }}
|
{{ 'debug-settings.all-messages' | translate: { time: (isDebugAllActive$ | async) && !allEnabled && debugAllControl.untouched ? (allEnabledUntil | durationLeft) : (maxDebugModeDuration | milliSecondsToTimeString: true : true) } }}
|
||||||
</div>
|
</div>
|
||||||
</mat-slide-toggle>
|
</mat-slide-toggle>
|
||||||
<button mat-icon-button *ngIf="(isDebugAllActive$ | async) && !allEnabled"
|
<button mat-icon-button *ngIf="(isDebugAllActive$ | async) && !allEnabled && debugAllControl.untouched"
|
||||||
class="tb-mat-20"
|
class="tb-mat-20"
|
||||||
matTooltip="{{ 'action.reset' | translate }}"
|
matTooltip="{{ 'action.reset' | translate }}"
|
||||||
matTooltipPosition="above"
|
matTooltipPosition="above"
|
||||||
|
|||||||
@ -127,19 +127,23 @@ export class WidgetActionDialogComponent extends DialogComponent<WidgetActionDia
|
|||||||
actionSourceId: [this.action.actionSourceId, Validators.required],
|
actionSourceId: [this.action.actionSourceId, Validators.required],
|
||||||
columnIndex: [{value: this.checkColumnIndex(this.action.columnIndex), disabled: true}, Validators.required],
|
columnIndex: [{value: this.checkColumnIndex(this.action.columnIndex), disabled: true}, Validators.required],
|
||||||
name: [this.action.name, [this.validateActionName(), Validators.required]],
|
name: [this.action.name, [this.validateActionName(), Validators.required]],
|
||||||
buttonType: [isDefinedAndNotNull(this.action.buttonType) ? this.action.buttonType : WidgetHeaderActionButtonType.icon, []],
|
buttonType: [{ value: this.action.buttonType ?? WidgetHeaderActionButtonType.icon, disabled: true}, []],
|
||||||
showIcon: [isDefinedAndNotNull(this.action.showIcon) ? this.action.showIcon : true, []],
|
showIcon: [{ value: this.action.showIcon ?? true, disabled: true}, []],
|
||||||
icon: [this.action.icon, Validators.required],
|
icon: [this.action.icon, Validators.required],
|
||||||
buttonColor: [isDefinedAndNotNull(this.action.buttonColor) ? this.action.buttonColor : 'rgba(0, 0, 0, 0.87)', []],
|
buttonColor: [{ value: this.action.buttonColor ?? 'rgba(0, 0, 0, 0.87)', disabled: true}, []],
|
||||||
buttonFillColor: [isDefinedAndNotNull(this.action.buttonFillColor) ? this.action.buttonFillColor : '#3F52DD', []],
|
buttonFillColor: [{ value: this.action.buttonFillColor ?? '#3F52DD', disabled: true}, []],
|
||||||
buttonBorderColor: [isDefinedAndNotNull(this.action.buttonBorderColor) ? this.action.buttonBorderColor : '#3F52DD', []],
|
buttonBorderColor: [{ value: this.action.buttonBorderColor ?? '#3F52DD', disabled: true}, []],
|
||||||
customButtonStyle: [isDefinedAndNotNull(this.action.customButtonStyle) ? this.action.customButtonStyle : null, []],
|
customButtonStyle: [{ value: this.action.customButtonStyle ?? {}, disabled: true}, []],
|
||||||
useShowWidgetActionFunction: [this.action.useShowWidgetActionFunction],
|
useShowWidgetActionFunction: [this.action.useShowWidgetActionFunction],
|
||||||
showWidgetActionFunction: [this.action.showWidgetActionFunction || 'return true;'],
|
showWidgetActionFunction: [this.action.showWidgetActionFunction || 'return true;'],
|
||||||
widgetAction: [actionDescriptorToAction(toWidgetActionDescriptor(this.action)), Validators.required]
|
widgetAction: [actionDescriptorToAction(toWidgetActionDescriptor(this.action)), Validators.required]
|
||||||
});
|
});
|
||||||
this.updateShowWidgetActionForm();
|
this.updateShowWidgetActionForm();
|
||||||
this.widgetHeaderButtonValidators();
|
if (this.widgetActionFormGroup.get('actionSourceId').value === 'headerButton') {
|
||||||
|
this.widgetActionFormGroup.get('buttonType').enable({emitEvent: false});
|
||||||
|
this.widgetActionFormGroup.get('buttonColor').enable({emitEvent: false});
|
||||||
|
this.widgetHeaderButtonValidators();
|
||||||
|
}
|
||||||
this.widgetActionFormGroup.get('actionSourceId').valueChanges.pipe(
|
this.widgetActionFormGroup.get('actionSourceId').valueChanges.pipe(
|
||||||
takeUntilDestroyed(this.destroyRef)
|
takeUntilDestroyed(this.destroyRef)
|
||||||
).subscribe((value) => {
|
).subscribe((value) => {
|
||||||
@ -151,6 +155,17 @@ export class WidgetActionDialogComponent extends DialogComponent<WidgetActionDia
|
|||||||
} else {
|
} else {
|
||||||
this.widgetActionFormGroup.get('columnIndex').disable();
|
this.widgetActionFormGroup.get('columnIndex').disable();
|
||||||
}
|
}
|
||||||
|
if (value === 'headerButton') {
|
||||||
|
this.widgetActionFormGroup.get('buttonType').enable({emitEvent: false});
|
||||||
|
this.widgetActionFormGroup.get('buttonColor').enable({emitEvent: false});
|
||||||
|
this.widgetHeaderButtonValidators();
|
||||||
|
} else {
|
||||||
|
this.widgetActionFormGroup.get('buttonType').disable({emitEvent: false});
|
||||||
|
this.widgetActionFormGroup.get('showIcon').disable({emitEvent: false});
|
||||||
|
this.widgetActionFormGroup.get('buttonColor').disable({emitEvent: false});
|
||||||
|
this.widgetActionFormGroup.get('buttonFillColor').disable({emitEvent: false});
|
||||||
|
this.widgetActionFormGroup.get('buttonBorderColor').disable({emitEvent: false});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
this.widgetActionFormGroup.get('useShowWidgetActionFunction').valueChanges.pipe(
|
this.widgetActionFormGroup.get('useShowWidgetActionFunction').valueChanges.pipe(
|
||||||
takeUntilDestroyed(this.destroyRef)
|
takeUntilDestroyed(this.destroyRef)
|
||||||
@ -185,10 +200,12 @@ export class WidgetActionDialogComponent extends DialogComponent<WidgetActionDia
|
|||||||
this.widgetActionFormGroup.get('buttonFillColor').enable({emitEvent: false});
|
this.widgetActionFormGroup.get('buttonFillColor').enable({emitEvent: false});
|
||||||
break;
|
break;
|
||||||
case WidgetHeaderActionButtonType.stroked:
|
case WidgetHeaderActionButtonType.stroked:
|
||||||
|
this.widgetActionFormGroup.get('showIcon').enable({emitEvent: false});
|
||||||
|
this.widgetActionFormGroup.get('buttonBorderColor').enable({emitEvent: false});
|
||||||
|
break;
|
||||||
case WidgetHeaderActionButtonType.flat:
|
case WidgetHeaderActionButtonType.flat:
|
||||||
this.widgetActionFormGroup.get('showIcon').enable({emitEvent: false});
|
this.widgetActionFormGroup.get('showIcon').enable({emitEvent: false});
|
||||||
this.widgetActionFormGroup.get('buttonFillColor').enable({emitEvent: false});
|
this.widgetActionFormGroup.get('buttonFillColor').enable({emitEvent: false});
|
||||||
this.widgetActionFormGroup.get('buttonBorderColor').enable({emitEvent: false});
|
|
||||||
break;
|
break;
|
||||||
case WidgetHeaderActionButtonType.miniFab:
|
case WidgetHeaderActionButtonType.miniFab:
|
||||||
this.widgetActionFormGroup.get('buttonFillColor').enable({emitEvent: false});
|
this.widgetActionFormGroup.get('buttonFillColor').enable({emitEvent: false});
|
||||||
|
|||||||
@ -109,11 +109,10 @@
|
|||||||
[style]="action.customButtonStyle"
|
[style]="action.customButtonStyle"
|
||||||
[class.!hidden]="isEdit"
|
[class.!hidden]="isEdit"
|
||||||
[class.mr-2]="!last"
|
[class.mr-2]="!last"
|
||||||
[style.background-color]="action.buttonFillColor"
|
|
||||||
(click)="action.onAction($event)"
|
(click)="action.onAction($event)"
|
||||||
matTooltip="{{ action.displayName }}"
|
matTooltip="{{ action.displayName }}"
|
||||||
matTooltipPosition="above">
|
matTooltipPosition="above">
|
||||||
<tb-icon [style.color]="action.buttonColor">{{ action.icon }}</tb-icon>
|
<tb-icon>{{ action.icon }}</tb-icon>
|
||||||
</button>
|
</button>
|
||||||
}
|
}
|
||||||
@case (widgetHeaderActionButtonType.basic) {
|
@case (widgetHeaderActionButtonType.basic) {
|
||||||
@ -123,46 +122,41 @@
|
|||||||
(click)="action.onAction($event)"
|
(click)="action.onAction($event)"
|
||||||
matTooltip="{{ action.displayName }}"
|
matTooltip="{{ action.displayName }}"
|
||||||
matTooltipPosition="above">
|
matTooltipPosition="above">
|
||||||
<tb-icon matButtonIcon *ngIf="action.showIcon" [style.color]="action.buttonColor">{{ action.icon }}</tb-icon>
|
<tb-icon matButtonIcon *ngIf="action.showIcon">{{ action.icon }}</tb-icon>
|
||||||
<span [style.color]="action.buttonColor">{{ action.displayName }}</span>
|
<span>{{ action.displayName }}</span>
|
||||||
</button>
|
</button>
|
||||||
}
|
}
|
||||||
@case (widgetHeaderActionButtonType.raised) {
|
@case (widgetHeaderActionButtonType.raised) {
|
||||||
<button [class.!hidden]="isEdit" mat-raised-button
|
<button [class.!hidden]="isEdit" mat-raised-button
|
||||||
[class.mr-2]="!last"
|
[class.mr-2]="!last"
|
||||||
[style]="action.customButtonStyle"
|
[style]="action.customButtonStyle"
|
||||||
[style.background-color]="action.buttonFillColor"
|
|
||||||
(click)="action.onAction($event)"
|
(click)="action.onAction($event)"
|
||||||
matTooltip="{{ action.displayName }}"
|
matTooltip="{{ action.displayName }}"
|
||||||
matTooltipPosition="above">
|
matTooltipPosition="above">
|
||||||
<tb-icon matButtonIcon *ngIf="action.showIcon" [style.color]="action.buttonColor">{{ action.icon }}</tb-icon>
|
<tb-icon matButtonIcon *ngIf="action.showIcon">{{ action.icon }}</tb-icon>
|
||||||
<span [style.color]="action.buttonColor">{{ action.displayName }}</span>
|
<span>{{ action.displayName }}</span>
|
||||||
</button>
|
</button>
|
||||||
}
|
}
|
||||||
@case (widgetHeaderActionButtonType.stroked) {
|
@case (widgetHeaderActionButtonType.stroked) {
|
||||||
<button [class.!hidden]="isEdit" mat-stroked-button
|
<button [class.!hidden]="isEdit" mat-stroked-button
|
||||||
[class.mr-2]="!last"
|
[class.mr-2]="!last"
|
||||||
[style]="action.customButtonStyle"
|
[style]="action.customButtonStyle"
|
||||||
[style.border-color]="action.buttonBorderColor"
|
|
||||||
[style.background-color]="action.buttonFillColor"
|
|
||||||
(click)="action.onAction($event)"
|
(click)="action.onAction($event)"
|
||||||
matTooltip="{{ action.displayName }}"
|
matTooltip="{{ action.displayName }}"
|
||||||
matTooltipPosition="above">
|
matTooltipPosition="above">
|
||||||
<tb-icon matButtonIcon *ngIf="action.showIcon" [style.color]="action.buttonColor">{{ action.icon }}</tb-icon>
|
<tb-icon matButtonIcon *ngIf="action.showIcon">{{ action.icon }}</tb-icon>
|
||||||
<span [style.color]="action.buttonColor">{{ action.displayName }}</span>
|
<span>{{ action.displayName }}</span>
|
||||||
</button>
|
</button>
|
||||||
}
|
}
|
||||||
@case (widgetHeaderActionButtonType.flat) {
|
@case (widgetHeaderActionButtonType.flat) {
|
||||||
<button [class.!hidden]="isEdit" mat-flat-button
|
<button [class.!hidden]="isEdit" mat-flat-button
|
||||||
[class.mr-2]="!last"
|
[class.mr-2]="!last"
|
||||||
[style]="action.customButtonStyle"
|
[style]="action.customButtonStyle"
|
||||||
[style.background-color]="action.buttonFillColor"
|
|
||||||
[style.border-color]="action.buttonBorderColor"
|
|
||||||
(click)="action.onAction($event)"
|
(click)="action.onAction($event)"
|
||||||
matTooltip="{{ action.displayName }}"
|
matTooltip="{{ action.displayName }}"
|
||||||
matTooltipPosition="above">
|
matTooltipPosition="above">
|
||||||
<tb-icon matButtonIcon *ngIf="action.showIcon" [style.color]="action.buttonColor">{{ action.icon }}</tb-icon>
|
<tb-icon matButtonIcon *ngIf="action.showIcon">{{ action.icon }}</tb-icon>
|
||||||
<span [style.color]="action.buttonColor">{{ action.displayName }}</span>
|
<span>{{ action.displayName }}</span>
|
||||||
</button>
|
</button>
|
||||||
}
|
}
|
||||||
@default {
|
@default {
|
||||||
@ -172,7 +166,7 @@
|
|||||||
(click)="action.onAction($event)"
|
(click)="action.onAction($event)"
|
||||||
matTooltip="{{ action.displayName }}"
|
matTooltip="{{ action.displayName }}"
|
||||||
matTooltipPosition="above">
|
matTooltipPosition="above">
|
||||||
<tb-icon [style.color]="action.buttonColor">{{ action.icon }}</tb-icon>
|
<tb-icon>{{ action.icon }}</tb-icon>
|
||||||
</button>
|
</button>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -44,6 +44,7 @@ import {
|
|||||||
widgetActionSources,
|
widgetActionSources,
|
||||||
WidgetActionType,
|
WidgetActionType,
|
||||||
WidgetComparisonSettings,
|
WidgetComparisonSettings,
|
||||||
|
WidgetHeaderActionButtonType,
|
||||||
WidgetMobileActionDescriptor,
|
WidgetMobileActionDescriptor,
|
||||||
WidgetMobileActionType,
|
WidgetMobileActionType,
|
||||||
WidgetResource,
|
WidgetResource,
|
||||||
@ -301,10 +302,13 @@ export class WidgetComponent extends PageComponent implements OnInit, OnChanges,
|
|||||||
buttonType: descriptor.buttonType,
|
buttonType: descriptor.buttonType,
|
||||||
showIcon: descriptor.showIcon,
|
showIcon: descriptor.showIcon,
|
||||||
icon: descriptor.icon,
|
icon: descriptor.icon,
|
||||||
buttonColor: descriptor.buttonColor,
|
customButtonStyle: this.headerButtonStyle(
|
||||||
buttonFillColor: descriptor.buttonFillColor,
|
descriptor.buttonType,
|
||||||
buttonBorderColor: descriptor.buttonBorderColor,
|
descriptor.customButtonStyle,
|
||||||
customButtonStyle: descriptor.customButtonStyle,
|
descriptor.buttonColor,
|
||||||
|
descriptor.buttonFillColor,
|
||||||
|
descriptor.buttonBorderColor
|
||||||
|
),
|
||||||
descriptor,
|
descriptor,
|
||||||
useShowWidgetHeaderActionFunction,
|
useShowWidgetHeaderActionFunction,
|
||||||
showWidgetHeaderActionFunction,
|
showWidgetHeaderActionFunction,
|
||||||
@ -359,6 +363,39 @@ export class WidgetComponent extends PageComponent implements OnInit, OnChanges,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
headerButtonStyle(buttonType: WidgetHeaderActionButtonType = WidgetHeaderActionButtonType.icon,
|
||||||
|
customButtonStyle:{[key: string]: string},
|
||||||
|
buttonColor: string = 'rgba(0,0,0,0.87)',
|
||||||
|
backgroundColor: string,
|
||||||
|
borderColor: string) {
|
||||||
|
const buttonStyle = {};
|
||||||
|
switch (buttonType) {
|
||||||
|
case WidgetHeaderActionButtonType.basic:
|
||||||
|
buttonStyle['--mdc-text-button-label-text-color'] = buttonColor;
|
||||||
|
break;
|
||||||
|
case WidgetHeaderActionButtonType.raised:
|
||||||
|
buttonStyle['--mdc-protected-button-label-text-color'] = buttonColor;
|
||||||
|
buttonStyle['--mdc-protected-button-container-color'] = backgroundColor;
|
||||||
|
break;
|
||||||
|
case WidgetHeaderActionButtonType.stroked:
|
||||||
|
buttonStyle['--mdc-outlined-button-label-text-color'] = buttonColor;
|
||||||
|
buttonStyle['--mdc-outlined-button-outline-color'] = borderColor;
|
||||||
|
break;
|
||||||
|
case WidgetHeaderActionButtonType.flat:
|
||||||
|
buttonStyle['--mdc-filled-button-label-text-color'] = buttonColor;
|
||||||
|
buttonStyle['--mdc-filled-button-container-color'] = backgroundColor;
|
||||||
|
break;
|
||||||
|
case WidgetHeaderActionButtonType.miniFab:
|
||||||
|
buttonStyle['--mat-fab-small-foreground-color'] = buttonColor;
|
||||||
|
buttonStyle['--mdc-fab-small-container-color'] = backgroundColor;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
buttonStyle['--mat-icon-color'] = buttonColor;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return {...buttonStyle, ...customButtonStyle};
|
||||||
|
}
|
||||||
|
|
||||||
ngOnChanges(changes: SimpleChanges): void {
|
ngOnChanges(changes: SimpleChanges): void {
|
||||||
for (const propName of Object.keys(changes)) {
|
for (const propName of Object.keys(changes)) {
|
||||||
const change = changes[propName];
|
const change = changes[propName];
|
||||||
|
|||||||
@ -132,7 +132,7 @@ export interface WidgetHeaderAction extends IWidgetAction {
|
|||||||
buttonColor?: string;
|
buttonColor?: string;
|
||||||
buttonFillColor?: string;
|
buttonFillColor?: string;
|
||||||
buttonBorderColor?: string;
|
buttonBorderColor?: string;
|
||||||
customButtonStyle?: string;
|
customButtonStyle?: {[key: string]: string};
|
||||||
useShowWidgetHeaderActionFunction: boolean;
|
useShowWidgetHeaderActionFunction: boolean;
|
||||||
showWidgetHeaderActionFunction: CompiledTbFunction<ShowWidgetHeaderActionFunction>;
|
showWidgetHeaderActionFunction: CompiledTbFunction<ShowWidgetHeaderActionFunction>;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -45,9 +45,9 @@
|
|||||||
<tb-calculated-fields-table [active]="calculatedFieldsTab.isActive" [entityId]="entity.id" [entityName]="entity.name"/>
|
<tb-calculated-fields-table [active]="calculatedFieldsTab.isActive" [entityId]="entity.id" [entityName]="entity.name"/>
|
||||||
</mat-tab>
|
</mat-tab>
|
||||||
<mat-tab *ngIf="entity" #alarmRules="matTab"
|
<mat-tab *ngIf="entity" #alarmRules="matTab"
|
||||||
label="{{'device-profile.alarm-rules-with-count' | translate:
|
label="{{ this.detailsForm.get('profileData.alarms').value?.length
|
||||||
{count: this.detailsForm.get('profileData.alarms').value?.length ? this.detailsForm.get('profileData.alarms').value.length : 0}
|
? ('device-profile.alarm-rules-with-count' | translate: { count: this.detailsForm.get('profileData.alarms').value.length })
|
||||||
}}">
|
: 'device-profile.alarm-rules' | translate }}">
|
||||||
<div class="mat-padding" [formGroup]="detailsForm" *ngIf="alarmRules.isActive">
|
<div class="mat-padding" [formGroup]="detailsForm" *ngIf="alarmRules.isActive">
|
||||||
<div formGroupName="profileData">
|
<div formGroupName="profileData">
|
||||||
<tb-device-profile-alarms formControlName="alarms" [deviceProfileId]="entity.id"></tb-device-profile-alarms>
|
<tb-device-profile-alarms formControlName="alarms" [deviceProfileId]="entity.id"></tb-device-profile-alarms>
|
||||||
|
|||||||
@ -780,7 +780,7 @@ export interface WidgetActionDescriptor extends WidgetAction {
|
|||||||
buttonColor?: string;
|
buttonColor?: string;
|
||||||
buttonFillColor?: string;
|
buttonFillColor?: string;
|
||||||
buttonBorderColor?: string;
|
buttonBorderColor?: string;
|
||||||
customButtonStyle?: string;
|
customButtonStyle?: {[key: string]: string};
|
||||||
displayName?: string;
|
displayName?: string;
|
||||||
useShowWidgetActionFunction?: boolean;
|
useShowWidgetActionFunction?: boolean;
|
||||||
showWidgetActionFunction?: TbFunction;
|
showWidgetActionFunction?: TbFunction;
|
||||||
|
|||||||
@ -991,7 +991,7 @@
|
|||||||
"type-sms-sent": "SMS sent"
|
"type-sms-sent": "SMS sent"
|
||||||
},
|
},
|
||||||
"debug-settings": {
|
"debug-settings": {
|
||||||
"label": "Debug configuration",
|
"label": "Debug Configuration",
|
||||||
"on-failure": "Failures only (24/7)",
|
"on-failure": "Failures only (24/7)",
|
||||||
"all-messages": "All messages ({{time}})",
|
"all-messages": "All messages ({{time}})",
|
||||||
"failures": "Failures",
|
"failures": "Failures",
|
||||||
@ -999,10 +999,9 @@
|
|||||||
"rule-node": "rule node",
|
"rule-node": "rule node",
|
||||||
"calculated-field": "calculated field",
|
"calculated-field": "calculated field",
|
||||||
"hint": {
|
"hint": {
|
||||||
"main": "All node debug messages rate limited with:",
|
"main-limited": "No more than {{msg}} {{entity}} debug messages per {{time}} will be recorded.",
|
||||||
"main-limited": "All {{entity}} debug messages will be rate-limited, with a maximum of {{msg}} messages allowed per {{time}}.",
|
"on-failure": "Log all debug messages.",
|
||||||
"on-failure": "Save all failure debug events without time limit.",
|
"all-messages": "Log error messages only. "
|
||||||
"all-messages": "Save all debug events during time limit."
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"calculated-fields": {
|
"calculated-fields": {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user