Merge branch 'master' into develop/2.2
This commit is contained in:
commit
d92b06584a
File diff suppressed because one or more lines are too long
@ -35,7 +35,7 @@
|
||||
"resources": [],
|
||||
"templateHtml": "",
|
||||
"templateCss": ".legend {\n font-size: 13px;\n line-height: 10px;\n}\n\n.legend table { \n border-spacing: 0px;\n border-collapse: separate;\n}\n\n.mouse-events .flot-overlay {\n cursor: crosshair; \n}\n\n",
|
||||
"controllerScript": "self.onInit = function() {\n self.ctx.flot = new TbFlot(self.ctx); \n}\n\nself.onDataUpdated = function() {\n self.ctx.flot.update();\n}\n\nself.onResize = function() {\n self.ctx.flot.resize();\n}\n\nself.onEditModeChanged = function() {\n self.ctx.flot.checkMouseEvents();\n}\n\nself.onMobileModeChanged = function() {\n self.ctx.flot.checkMouseEvents();\n}\n\nself.getSettingsSchema = function() {\n return TbFlot.settingsSchema;\n}\n\nself.getDataKeySettingsSchema = function() {\n return TbFlot.datakeySettingsSchema(true);\n}\n\nself.onDestroy = function() {\n self.ctx.flot.destroy();\n}\n",
|
||||
"controllerScript": "self.onInit = function() {\n self.ctx.flot = new TbFlot(self.ctx); \n}\n\nself.onDataUpdated = function() {\n self.ctx.flot.update();\n}\n\nself.onResize = function() {\n self.ctx.flot.resize();\n}\n\nself.onEditModeChanged = function() {\n self.ctx.flot.checkMouseEvents();\n}\n\nself.onMobileModeChanged = function() {\n self.ctx.flot.checkMouseEvents();\n}\n\nself.getSettingsSchema = function() {\n return TbFlot.settingsSchema('graph');\n}\n\nself.getDataKeySettingsSchema = function() {\n return TbFlot.datakeySettingsSchema(true);\n}\n\nself.onDestroy = function() {\n self.ctx.flot.destroy();\n}\n",
|
||||
"settingsSchema": "{}",
|
||||
"dataKeySettingsSchema": "{}",
|
||||
"defaultConfig": "{\"datasources\":[{\"type\":\"function\",\"name\":\"function\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"First\",\"color\":\"#2196f3\",\"settings\":{\"showLines\":true,\"fillLines\":true,\"showPoints\":false},\"_hash\":0.8587686344902596,\"funcBody\":\"var value = prevValue + Math.random() * 100 - 50;\\nvar multiplier = Math.pow(10, 2 || 0);\\nvar value = Math.round(value * multiplier) / multiplier;\\nif (value < -1000) {\\n\\tvalue = -1000;\\n} else if (value > 1000) {\\n\\tvalue = 1000;\\n}\\nreturn value;\"},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Second\",\"color\":\"#ffc107\",\"settings\":{\"showLines\":true,\"fillLines\":false,\"showPoints\":false},\"_hash\":0.12775350966079668,\"funcBody\":\"var value = prevValue + Math.random() * 100 - 50;\\nvar multiplier = Math.pow(10, 2 || 0);\\nvar value = Math.round(value * multiplier) / multiplier;\\nif (value < -1000) {\\n\\tvalue = -1000;\\n} else if (value > 1000) {\\n\\tvalue = 1000;\\n}\\nreturn value;\"}]}],\"timewindow\":{\"realtime\":{\"timewindowMs\":60000}},\"showTitle\":true,\"backgroundColor\":\"#fff\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"8px\",\"settings\":{\"shadowSize\":4,\"fontColor\":\"#545454\",\"fontSize\":10,\"xaxis\":{\"showLabels\":true,\"color\":\"#545454\"},\"yaxis\":{\"showLabels\":true,\"color\":\"#545454\"},\"grid\":{\"color\":\"#545454\",\"tickColor\":\"#DDDDDD\",\"verticalLines\":true,\"horizontalLines\":true,\"outlineWidth\":1},\"legend\":{\"show\":true,\"position\":\"nw\",\"backgroundColor\":\"#f0f0f0\",\"backgroundOpacity\":0.85,\"labelBoxBorderColor\":\"rgba(1, 1, 1, 0.45)\"},\"decimals\":1,\"stack\":false,\"tooltipIndividual\":false},\"title\":\"Timeseries - Flot\",\"dropShadow\":true,\"enableFullscreen\":true,\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"mobileHeight\":null}"
|
||||
@ -147,10 +147,10 @@
|
||||
"resources": [],
|
||||
"templateHtml": "",
|
||||
"templateCss": ".legend {\n font-size: 13px;\n line-height: 10px;\n}\n\n.legend table { \n border-spacing: 0px;\n border-collapse: separate;\n}\n\n.mouse-events .flot-overlay {\n cursor: crosshair; \n}\n\n",
|
||||
"controllerScript": "self.onInit = function() {\n self.ctx.flot = new TbFlot(self.ctx, 'bar'); \n}\n\nself.onDataUpdated = function() {\n self.ctx.flot.update();\n}\n\nself.onResize = function() {\n self.ctx.flot.resize();\n}\n\nself.onEditModeChanged = function() {\n self.ctx.flot.checkMouseEvents();\n}\n\nself.onMobileModeChanged = function() {\n self.ctx.flot.checkMouseEvents();\n}\n\nself.getSettingsSchema = function() {\n return TbFlot.settingsSchema;\n}\n\nself.getDataKeySettingsSchema = function() {\n return TbFlot.datakeySettingsSchema(false);\n}\n\nself.onDestroy = function() {\n self.ctx.flot.destroy();\n}\n",
|
||||
"controllerScript": "self.onInit = function() {\n self.ctx.flot = new TbFlot(self.ctx, 'bar'); \n}\n\nself.onDataUpdated = function() {\n self.ctx.flot.update();\n}\n\nself.onResize = function() {\n self.ctx.flot.resize();\n}\n\nself.onEditModeChanged = function() {\n self.ctx.flot.checkMouseEvents();\n}\n\nself.onMobileModeChanged = function() {\n self.ctx.flot.checkMouseEvents();\n}\n\nself.getSettingsSchema = function() {\n return TbFlot.settingsSchema('bar');\n}\n\nself.getDataKeySettingsSchema = function() {\n return TbFlot.datakeySettingsSchema(false);\n}\n\nself.onDestroy = function() {\n self.ctx.flot.destroy();\n}\n",
|
||||
"settingsSchema": "{}",
|
||||
"dataKeySettingsSchema": "{}",
|
||||
"defaultConfig": "{\"datasources\":[{\"type\":\"function\",\"name\":\"function\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"First\",\"color\":\"#2196f3\",\"settings\":{\"showLines\":false,\"fillLines\":false,\"showPoints\":false},\"_hash\":0.8587686344902596,\"funcBody\":\"var value = prevValue + Math.random() * 100 - 50;\\nvar multiplier = Math.pow(10, 2 || 0);\\nvar value = Math.round(value * multiplier) / multiplier;\\nif (value < 0) {\\n\\tvalue = 0;\\n} else if (value > 1000) {\\n\\tvalue = 1000;\\n}\\nreturn value;\"},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Second\",\"color\":\"#ffc107\",\"settings\":{\"showLines\":false,\"fillLines\":false,\"showPoints\":false},\"_hash\":0.12775350966079668,\"funcBody\":\"var value = prevValue + Math.random() * 100 - 50;\\nvar multiplier = Math.pow(10, 2 || 0);\\nvar value = Math.round(value * multiplier) / multiplier;\\nif (value < 0) {\\n\\tvalue = 0;\\n} else if (value > 1000) {\\n\\tvalue = 1000;\\n}\\nreturn value;\"}]}],\"timewindow\":{\"realtime\":{\"timewindowMs\":60000},\"aggregation\":{\"limit\":200,\"type\":\"AVG\"}},\"showTitle\":true,\"backgroundColor\":\"#fff\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"8px\",\"settings\":{\"shadowSize\":4,\"fontColor\":\"#545454\",\"fontSize\":10,\"xaxis\":{\"showLabels\":true,\"color\":\"#545454\"},\"yaxis\":{\"showLabels\":true,\"color\":\"#545454\"},\"grid\":{\"color\":\"#545454\",\"tickColor\":\"#DDDDDD\",\"verticalLines\":true,\"horizontalLines\":true,\"outlineWidth\":1},\"legend\":{\"show\":true,\"position\":\"nw\",\"backgroundColor\":\"#f0f0f0\",\"backgroundOpacity\":0.85,\"labelBoxBorderColor\":\"rgba(1, 1, 1, 0.45)\"},\"decimals\":1,\"stack\":true,\"tooltipIndividual\":false},\"title\":\"Timeseries Bars - Flot\",\"dropShadow\":true,\"enableFullscreen\":true,\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"mobileHeight\":null}"
|
||||
"defaultConfig": "{\"datasources\":[{\"type\":\"function\",\"name\":\"function\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"First\",\"color\":\"#2196f3\",\"settings\":{\"showLines\":false,\"fillLines\":false,\"showPoints\":false},\"_hash\":0.8587686344902596,\"funcBody\":\"var value = prevValue + Math.random() * 100 - 50;\\nvar multiplier = Math.pow(10, 2 || 0);\\nvar value = Math.round(value * multiplier) / multiplier;\\nif (value < 0) {\\n\\tvalue = 0;\\n} else if (value > 1000) {\\n\\tvalue = 1000;\\n}\\nreturn value;\"},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Second\",\"color\":\"#ffc107\",\"settings\":{\"showLines\":false,\"fillLines\":false,\"showPoints\":false},\"_hash\":0.12775350966079668,\"funcBody\":\"var value = prevValue + Math.random() * 100 - 50;\\nvar multiplier = Math.pow(10, 2 || 0);\\nvar value = Math.round(value * multiplier) / multiplier;\\nif (value < 0) {\\n\\tvalue = 0;\\n} else if (value > 1000) {\\n\\tvalue = 1000;\\n}\\nreturn value;\"}]}],\"timewindow\":{\"realtime\":{\"timewindowMs\":60000},\"aggregation\":{\"limit\":200,\"type\":\"AVG\"}},\"showTitle\":true,\"backgroundColor\":\"#fff\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"8px\",\"settings\":{\"shadowSize\":4,\"fontColor\":\"#545454\",\"fontSize\":10,\"xaxis\":{\"showLabels\":true,\"color\":\"#545454\"},\"yaxis\":{\"showLabels\":true,\"color\":\"#545454\"},\"grid\":{\"color\":\"#545454\",\"tickColor\":\"#DDDDDD\",\"verticalLines\":true,\"horizontalLines\":true,\"outlineWidth\":1},\"stack\":true,\"tooltipIndividual\":false,\"defaultBarWidth\":600},\"title\":\"Timeseries Bars - Flot\",\"dropShadow\":true,\"enableFullscreen\":true,\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"mobileHeight\":null,\"widgetStyle\":{},\"useDashboardTimewindow\":true,\"showLegend\":true,\"actions\":{}}"
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -163,7 +163,7 @@
|
||||
"resources": [],
|
||||
"templateHtml": "",
|
||||
"templateCss": ".legend {\n font-size: 13px;\n line-height: 10px;\n}\n\n.legend table { \n border-spacing: 0px;\n border-collapse: separate;\n}\n\n.mouse-events .flot-overlay {\n cursor: crosshair; \n}\n\n",
|
||||
"controllerScript": "self.onInit = function() {\n self.ctx.flot = new TbFlot(self.ctx, 'state'); \n}\n\nself.onDataUpdated = function() {\n self.ctx.flot.update();\n}\n\nself.onResize = function() {\n self.ctx.flot.resize();\n}\n\nself.typeParameters = function() {\n return {\n stateData: true\n };\n}\n\nself.onEditModeChanged = function() {\n self.ctx.flot.checkMouseEvents();\n}\n\nself.onMobileModeChanged = function() {\n self.ctx.flot.checkMouseEvents();\n}\n\nself.getSettingsSchema = function() {\n return TbFlot.settingsSchema;\n}\n\nself.getDataKeySettingsSchema = function() {\n return TbFlot.datakeySettingsSchema(true);\n}\n\nself.onDestroy = function() {\n self.ctx.flot.destroy();\n}\n",
|
||||
"controllerScript": "self.onInit = function() {\n self.ctx.flot = new TbFlot(self.ctx, 'state'); \n}\n\nself.onDataUpdated = function() {\n self.ctx.flot.update();\n}\n\nself.onResize = function() {\n self.ctx.flot.resize();\n}\n\nself.typeParameters = function() {\n return {\n stateData: true\n };\n}\n\nself.onEditModeChanged = function() {\n self.ctx.flot.checkMouseEvents();\n}\n\nself.onMobileModeChanged = function() {\n self.ctx.flot.checkMouseEvents();\n}\n\nself.getSettingsSchema = function() {\n return TbFlot.settingsSchema('graph');\n}\n\nself.getDataKeySettingsSchema = function() {\n return TbFlot.datakeySettingsSchema(true);\n}\n\nself.onDestroy = function() {\n self.ctx.flot.destroy();\n}\n",
|
||||
"settingsSchema": "{}",
|
||||
"dataKeySettingsSchema": "{}",
|
||||
"defaultConfig": "{\"datasources\":[{\"type\":\"function\",\"name\":\"function\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Switch 1\",\"color\":\"#2196f3\",\"settings\":{\"showLines\":true,\"fillLines\":true,\"showPoints\":false,\"axisPosition\":\"left\",\"showSeparateAxis\":false},\"_hash\":0.8587686344902596,\"funcBody\":\"return Math.random() > 0.5 ? 1 : 0;\"},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Switch 2\",\"color\":\"#ffc107\",\"settings\":{\"showLines\":true,\"fillLines\":false,\"showPoints\":false,\"axisPosition\":\"left\"},\"_hash\":0.12775350966079668,\"funcBody\":\"return Math.random() <= 0.5 ? 1 : 0;\"}]}],\"timewindow\":{\"realtime\":{\"timewindowMs\":60000}},\"showTitle\":true,\"backgroundColor\":\"#fff\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"8px\",\"settings\":{\"shadowSize\":4,\"fontColor\":\"#545454\",\"fontSize\":10,\"xaxis\":{\"showLabels\":true,\"color\":\"#545454\"},\"yaxis\":{\"showLabels\":true,\"color\":\"#545454\",\"ticksFormatter\":\"if (value > 0 && value <= 1) {\\n return 'On';\\n} else if (value === 0) {\\n return 'Off';\\n} else {\\n return '';\\n}\"},\"grid\":{\"color\":\"#545454\",\"tickColor\":\"#DDDDDD\",\"verticalLines\":true,\"horizontalLines\":true,\"outlineWidth\":1},\"stack\":false,\"tooltipIndividual\":false,\"tooltipValueFormatter\":\"if (value > 0 && value <= 1) {\\n return 'On';\\n} else if (value === 0) {\\n return 'Off';\\n} else {\\n return '';\\n}\",\"smoothLines\":false},\"title\":\"State Chart\",\"dropShadow\":true,\"enableFullscreen\":true,\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"mobileHeight\":null,\"widgetStyle\":{},\"useDashboardTimewindow\":true,\"showLegend\":true,\"actions\":{},\"legendConfig\":{\"position\":\"bottom\",\"showMin\":false,\"showMax\":false,\"showAvg\":false,\"showTotal\":false}}"
|
||||
|
||||
@ -20,7 +20,7 @@ DROP MATERIALIZED VIEW IF EXISTS thingsboard.entity_view_by_tenant_and_customer;
|
||||
DROP MATERIALIZED VIEW IF EXISTS thingsboard.entity_view_by_tenant_and_entity_id;
|
||||
|
||||
DROP TABLE IF EXISTS thingsboard.entity_views;
|
||||
ControllerSqlTestSuite
|
||||
|
||||
CREATE TABLE IF NOT EXISTS thingsboard.entity_views (
|
||||
id timeuuid,
|
||||
entity_id timeuuid,
|
||||
|
||||
@ -391,6 +391,7 @@ audit_log:
|
||||
"user": "${AUDIT_LOG_MASK_USER:W}"
|
||||
"rule_chain": "${AUDIT_LOG_MASK_RULE_CHAIN:W}"
|
||||
"alarm": "${AUDIT_LOG_MASK_ALARM:W}"
|
||||
"entity_view": "${AUDIT_LOG_MASK_RULE_CHAIN:W}"
|
||||
sink:
|
||||
# Type of external sink. possible options: none, elasticsearch
|
||||
type: "${AUDIT_LOG_SINK_TYPE:none}"
|
||||
|
||||
@ -73,4 +73,6 @@ public abstract class DeviceAwareSessionContext implements SessionContext {
|
||||
public Device getDevice() {
|
||||
return device;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -54,6 +54,7 @@ import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.thingsboard.server.common.data.CacheConstants.ASSET_CACHE;
|
||||
@ -141,7 +142,7 @@ public class BaseAssetService extends AbstractEntityService implements AssetServ
|
||||
if (entityViews != null && !entityViews.isEmpty()) {
|
||||
throw new DataValidationException("Can't delete asset that is assigned to entity views!");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
} catch (ExecutionException | InterruptedException e) {
|
||||
log.error("Exception while finding entity views for assetId [{}]", assetId, e);
|
||||
throw new RuntimeException("Exception while finding entity views for assetId [" + assetId + "]", e);
|
||||
}
|
||||
|
||||
@ -58,6 +58,7 @@ import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.thingsboard.server.common.data.CacheConstants.DEVICE_CACHE;
|
||||
@ -158,7 +159,7 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe
|
||||
if (entityViews != null && !entityViews.isEmpty()) {
|
||||
throw new DataValidationException("Can't delete device that is assigned to entity views!");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
} catch (ExecutionException | InterruptedException e) {
|
||||
log.error("Exception while finding entity views for deviceId [{}]", deviceId, e);
|
||||
throw new RuntimeException("Exception while finding entity views for deviceId [" + deviceId + "]", e);
|
||||
}
|
||||
|
||||
@ -51,6 +51,9 @@ import javax.security.cert.X509Certificate;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
import static io.netty.handler.codec.mqtt.MqttConnectReturnCode.*;
|
||||
import static io.netty.handler.codec.mqtt.MqttMessageType.*;
|
||||
@ -75,6 +78,8 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement
|
||||
private final RelationService relationService;
|
||||
private final QuotaService quotaService;
|
||||
private final SslHandler sslHandler;
|
||||
private final ConcurrentMap<String, Integer> mqttQoSMap;
|
||||
|
||||
private volatile boolean connected;
|
||||
private volatile InetSocketAddress address;
|
||||
private volatile GatewaySessionCtx gatewaySessionCtx;
|
||||
@ -86,7 +91,8 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement
|
||||
this.relationService = relationService;
|
||||
this.authService = authService;
|
||||
this.adaptor = adaptor;
|
||||
this.deviceSessionCtx = new DeviceSessionCtx(processor, authService, adaptor);
|
||||
this.mqttQoSMap = new ConcurrentHashMap<>();
|
||||
this.deviceSessionCtx = new DeviceSessionCtx(processor, authService, adaptor, mqttQoSMap);
|
||||
this.sessionId = deviceSessionCtx.getSessionId().toUidStr();
|
||||
this.sslHandler = sslHandler;
|
||||
this.quotaService = quotaService;
|
||||
@ -166,18 +172,25 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement
|
||||
|
||||
private void handleMqttPublishMsg(String topicName, int msgId, MqttPublishMessage mqttMsg) {
|
||||
try {
|
||||
if (topicName.equals(GATEWAY_TELEMETRY_TOPIC)) {
|
||||
gatewaySessionCtx.onDeviceTelemetry(mqttMsg);
|
||||
} else if (topicName.equals(GATEWAY_ATTRIBUTES_TOPIC)) {
|
||||
gatewaySessionCtx.onDeviceAttributes(mqttMsg);
|
||||
} else if (topicName.equals(GATEWAY_ATTRIBUTES_REQUEST_TOPIC)) {
|
||||
gatewaySessionCtx.onDeviceAttributesRequest(mqttMsg);
|
||||
} else if (topicName.equals(GATEWAY_RPC_TOPIC)) {
|
||||
gatewaySessionCtx.onDeviceRpcResponse(mqttMsg);
|
||||
} else if (topicName.equals(GATEWAY_CONNECT_TOPIC)) {
|
||||
gatewaySessionCtx.onDeviceConnect(mqttMsg);
|
||||
} else if (topicName.equals(GATEWAY_DISCONNECT_TOPIC)) {
|
||||
gatewaySessionCtx.onDeviceDisconnect(mqttMsg);
|
||||
switch (topicName) {
|
||||
case GATEWAY_TELEMETRY_TOPIC:
|
||||
gatewaySessionCtx.onDeviceTelemetry(mqttMsg);
|
||||
break;
|
||||
case GATEWAY_ATTRIBUTES_TOPIC:
|
||||
gatewaySessionCtx.onDeviceAttributes(mqttMsg);
|
||||
break;
|
||||
case GATEWAY_ATTRIBUTES_REQUEST_TOPIC:
|
||||
gatewaySessionCtx.onDeviceAttributesRequest(mqttMsg);
|
||||
break;
|
||||
case GATEWAY_RPC_TOPIC:
|
||||
gatewaySessionCtx.onDeviceRpcResponse(mqttMsg);
|
||||
break;
|
||||
case GATEWAY_CONNECT_TOPIC:
|
||||
gatewaySessionCtx.onDeviceConnect(mqttMsg);
|
||||
break;
|
||||
case GATEWAY_DISCONNECT_TOPIC:
|
||||
gatewaySessionCtx.onDeviceDisconnect(mqttMsg);
|
||||
break;
|
||||
}
|
||||
} catch (RuntimeException | AdaptorException e) {
|
||||
log.warn("[{}] Failed to process publish msg [{}][{}]", sessionId, topicName, msgId, e);
|
||||
@ -225,52 +238,71 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement
|
||||
log.trace("[{}] Processing subscription [{}]!", sessionId, mqttMsg.variableHeader().messageId());
|
||||
List<Integer> grantedQoSList = new ArrayList<>();
|
||||
for (MqttTopicSubscription subscription : mqttMsg.payload().topicSubscriptions()) {
|
||||
String topicName = subscription.topicName();
|
||||
//TODO: handle this qos level.
|
||||
String topic = subscription.topicName();
|
||||
MqttQoS reqQoS = subscription.qualityOfService();
|
||||
try {
|
||||
if (topicName.equals(DEVICE_ATTRIBUTES_TOPIC)) {
|
||||
AdaptorToSessionActorMsg msg = adaptor.convertToActorMsg(deviceSessionCtx, SUBSCRIBE_ATTRIBUTES_REQUEST, mqttMsg);
|
||||
processor.process(new BasicTransportToDeviceSessionActorMsg(deviceSessionCtx.getDevice(), msg));
|
||||
grantedQoSList.add(getMinSupportedQos(reqQoS));
|
||||
} else if (topicName.equals(DEVICE_RPC_REQUESTS_SUB_TOPIC)) {
|
||||
AdaptorToSessionActorMsg msg = adaptor.convertToActorMsg(deviceSessionCtx, SUBSCRIBE_RPC_COMMANDS_REQUEST, mqttMsg);
|
||||
processor.process(new BasicTransportToDeviceSessionActorMsg(deviceSessionCtx.getDevice(), msg));
|
||||
grantedQoSList.add(getMinSupportedQos(reqQoS));
|
||||
} else if (topicName.equals(DEVICE_RPC_RESPONSE_SUB_TOPIC)) {
|
||||
grantedQoSList.add(getMinSupportedQos(reqQoS));
|
||||
} else if (topicName.equals(DEVICE_ATTRIBUTES_RESPONSES_TOPIC)) {
|
||||
deviceSessionCtx.setAllowAttributeResponses();
|
||||
grantedQoSList.add(getMinSupportedQos(reqQoS));
|
||||
} else if (topicName.equals(GATEWAY_ATTRIBUTES_TOPIC)) {
|
||||
grantedQoSList.add(getMinSupportedQos(reqQoS));
|
||||
} else {
|
||||
log.warn("[{}] Failed to subscribe to [{}][{}]", sessionId, topicName, reqQoS);
|
||||
grantedQoSList.add(FAILURE.value());
|
||||
switch (topic) {
|
||||
case DEVICE_ATTRIBUTES_TOPIC: {
|
||||
AdaptorToSessionActorMsg msg = adaptor.convertToActorMsg(deviceSessionCtx, SUBSCRIBE_ATTRIBUTES_REQUEST, mqttMsg);
|
||||
processor.process(new BasicTransportToDeviceSessionActorMsg(deviceSessionCtx.getDevice(), msg));
|
||||
registerSubQoS(topic, grantedQoSList, reqQoS);
|
||||
break;
|
||||
}
|
||||
case DEVICE_RPC_REQUESTS_SUB_TOPIC: {
|
||||
AdaptorToSessionActorMsg msg = adaptor.convertToActorMsg(deviceSessionCtx, SUBSCRIBE_RPC_COMMANDS_REQUEST, mqttMsg);
|
||||
processor.process(new BasicTransportToDeviceSessionActorMsg(deviceSessionCtx.getDevice(), msg));
|
||||
registerSubQoS(topic, grantedQoSList, reqQoS);
|
||||
break;
|
||||
}
|
||||
case DEVICE_RPC_RESPONSE_SUB_TOPIC:
|
||||
case GATEWAY_ATTRIBUTES_TOPIC:
|
||||
case GATEWAY_RPC_TOPIC:
|
||||
registerSubQoS(topic, grantedQoSList, reqQoS);
|
||||
break;
|
||||
case DEVICE_ATTRIBUTES_RESPONSES_TOPIC:
|
||||
deviceSessionCtx.setAllowAttributeResponses();
|
||||
registerSubQoS(topic, grantedQoSList, reqQoS);
|
||||
break;
|
||||
default:
|
||||
log.warn("[{}] Failed to subscribe to [{}][{}]", sessionId, topic, reqQoS);
|
||||
grantedQoSList.add(FAILURE.value());
|
||||
break;
|
||||
}
|
||||
} catch (AdaptorException e) {
|
||||
log.warn("[{}] Failed to subscribe to [{}][{}]", sessionId, topicName, reqQoS);
|
||||
log.warn("[{}] Failed to subscribe to [{}][{}]", sessionId, topic, reqQoS);
|
||||
grantedQoSList.add(FAILURE.value());
|
||||
}
|
||||
}
|
||||
ctx.writeAndFlush(createSubAckMessage(mqttMsg.variableHeader().messageId(), grantedQoSList));
|
||||
}
|
||||
|
||||
private void registerSubQoS(String topic, List<Integer> grantedQoSList, MqttQoS reqQoS) {
|
||||
grantedQoSList.add(getMinSupportedQos(reqQoS));
|
||||
mqttQoSMap.put(topic, getMinSupportedQos(reqQoS));
|
||||
}
|
||||
|
||||
private void processUnsubscribe(ChannelHandlerContext ctx, MqttUnsubscribeMessage mqttMsg) {
|
||||
if (!checkConnected(ctx)) {
|
||||
return;
|
||||
}
|
||||
log.trace("[{}] Processing subscription [{}]!", sessionId, mqttMsg.variableHeader().messageId());
|
||||
for (String topicName : mqttMsg.payload().topics()) {
|
||||
mqttQoSMap.remove(topicName);
|
||||
try {
|
||||
if (topicName.equals(DEVICE_ATTRIBUTES_TOPIC)) {
|
||||
AdaptorToSessionActorMsg msg = adaptor.convertToActorMsg(deviceSessionCtx, UNSUBSCRIBE_ATTRIBUTES_REQUEST, mqttMsg);
|
||||
processor.process(new BasicTransportToDeviceSessionActorMsg(deviceSessionCtx.getDevice(), msg));
|
||||
} else if (topicName.equals(DEVICE_RPC_REQUESTS_SUB_TOPIC)) {
|
||||
AdaptorToSessionActorMsg msg = adaptor.convertToActorMsg(deviceSessionCtx, UNSUBSCRIBE_RPC_COMMANDS_REQUEST, mqttMsg);
|
||||
processor.process(new BasicTransportToDeviceSessionActorMsg(deviceSessionCtx.getDevice(), msg));
|
||||
} else if (topicName.equals(DEVICE_ATTRIBUTES_RESPONSES_TOPIC)) {
|
||||
deviceSessionCtx.setDisallowAttributeResponses();
|
||||
switch (topicName) {
|
||||
case DEVICE_ATTRIBUTES_TOPIC: {
|
||||
AdaptorToSessionActorMsg msg = adaptor.convertToActorMsg(deviceSessionCtx, UNSUBSCRIBE_ATTRIBUTES_REQUEST, mqttMsg);
|
||||
processor.process(new BasicTransportToDeviceSessionActorMsg(deviceSessionCtx.getDevice(), msg));
|
||||
break;
|
||||
}
|
||||
case DEVICE_RPC_REQUESTS_SUB_TOPIC: {
|
||||
AdaptorToSessionActorMsg msg = adaptor.convertToActorMsg(deviceSessionCtx, UNSUBSCRIBE_RPC_COMMANDS_REQUEST, mqttMsg);
|
||||
processor.process(new BasicTransportToDeviceSessionActorMsg(deviceSessionCtx.getDevice(), msg));
|
||||
break;
|
||||
}
|
||||
case DEVICE_ATTRIBUTES_RESPONSES_TOPIC:
|
||||
deviceSessionCtx.setDisallowAttributeResponses();
|
||||
break;
|
||||
}
|
||||
} catch (AdaptorException e) {
|
||||
log.warn("[{}] Failed to process unsubscription [{}] to [{}]", sessionId, mqttMsg.variableHeader().messageId(), topicName);
|
||||
|
||||
@ -170,7 +170,7 @@ public class JsonMqttAdaptor implements MqttTransportAdaptor {
|
||||
|
||||
private MqttPublishMessage createMqttPublishMsg(DeviceSessionCtx ctx, String topic, JsonElement json) {
|
||||
MqttFixedHeader mqttFixedHeader =
|
||||
new MqttFixedHeader(MqttMessageType.PUBLISH, false, MqttQoS.AT_LEAST_ONCE, false, 0);
|
||||
new MqttFixedHeader(MqttMessageType.PUBLISH, false, ctx.getQoSForTopic(topic), false, 0);
|
||||
MqttPublishVariableHeader header = new MqttPublishVariableHeader(topic, ctx.nextMsgId());
|
||||
ByteBuf payload = ALLOCATOR.buffer();
|
||||
payload.writeBytes(GSON.toJson(json).getBytes(UTF8));
|
||||
|
||||
@ -30,13 +30,15 @@ import org.thingsboard.server.common.transport.auth.DeviceAuthService;
|
||||
import org.thingsboard.server.common.transport.session.DeviceAwareSessionContext;
|
||||
import org.thingsboard.server.transport.mqtt.adaptors.MqttTransportAdaptor;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
* @author Andrew Shvayka
|
||||
*/
|
||||
@Slf4j
|
||||
public class DeviceSessionCtx extends DeviceAwareSessionContext {
|
||||
public class DeviceSessionCtx extends MqttDeviceAwareSessionContext {
|
||||
|
||||
private final MqttTransportAdaptor adaptor;
|
||||
private final MqttSessionId sessionId;
|
||||
@ -44,8 +46,8 @@ public class DeviceSessionCtx extends DeviceAwareSessionContext {
|
||||
private volatile boolean allowAttributeResponses;
|
||||
private AtomicInteger msgIdSeq = new AtomicInteger(0);
|
||||
|
||||
public DeviceSessionCtx(SessionMsgProcessor processor, DeviceAuthService authService, MqttTransportAdaptor adaptor) {
|
||||
super(processor, authService);
|
||||
public DeviceSessionCtx(SessionMsgProcessor processor, DeviceAuthService authService, MqttTransportAdaptor adaptor, ConcurrentMap<String, Integer> mqttQoSMap) {
|
||||
super(processor, authService, mqttQoSMap);
|
||||
this.adaptor = adaptor;
|
||||
this.sessionId = new MqttSessionId();
|
||||
}
|
||||
|
||||
@ -38,13 +38,15 @@ import org.thingsboard.server.transport.mqtt.MqttTransportHandler;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
* Created by ashvayka on 19.01.17.
|
||||
*/
|
||||
public class GatewayDeviceSessionCtx extends DeviceAwareSessionContext {
|
||||
public class GatewayDeviceSessionCtx extends MqttDeviceAwareSessionContext {
|
||||
|
||||
private static final Gson GSON = new Gson();
|
||||
private static final Charset UTF8 = Charset.forName("UTF-8");
|
||||
@ -56,8 +58,8 @@ public class GatewayDeviceSessionCtx extends DeviceAwareSessionContext {
|
||||
private volatile boolean closed;
|
||||
private AtomicInteger msgIdSeq = new AtomicInteger(0);
|
||||
|
||||
public GatewayDeviceSessionCtx(GatewaySessionCtx parent, Device device) {
|
||||
super(parent.getProcessor(), parent.getAuthService(), device);
|
||||
public GatewayDeviceSessionCtx(GatewaySessionCtx parent, Device device, ConcurrentMap<String, Integer> mqttQoSMap) {
|
||||
super(parent.getProcessor(), parent.getAuthService(), device, mqttQoSMap);
|
||||
this.parent = parent;
|
||||
this.sessionId = new MqttSessionId();
|
||||
}
|
||||
@ -195,7 +197,7 @@ public class GatewayDeviceSessionCtx extends DeviceAwareSessionContext {
|
||||
|
||||
private MqttPublishMessage createMqttPublishMsg(String topic, JsonElement json) {
|
||||
MqttFixedHeader mqttFixedHeader =
|
||||
new MqttFixedHeader(MqttMessageType.PUBLISH, false, MqttQoS.AT_LEAST_ONCE, false, 0);
|
||||
new MqttFixedHeader(MqttMessageType.PUBLISH, false, getQoSForTopic(topic), false, 0);
|
||||
MqttPublishVariableHeader header = new MqttPublishVariableHeader(topic, msgIdSeq.incrementAndGet());
|
||||
ByteBuf payload = ALLOCATOR.buffer();
|
||||
payload.writeBytes(GSON.toJson(json).getBytes(UTF8));
|
||||
|
||||
@ -43,6 +43,7 @@ import org.thingsboard.server.transport.mqtt.MqttTransportHandler;
|
||||
import org.thingsboard.server.transport.mqtt.adaptors.JsonMqttAdaptor;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.thingsboard.server.transport.mqtt.adaptors.JsonMqttAdaptor.validateJsonPayload;
|
||||
@ -63,6 +64,7 @@ public class GatewaySessionCtx {
|
||||
private final DeviceAuthService authService;
|
||||
private final RelationService relationService;
|
||||
private final Map<String, GatewayDeviceSessionCtx> devices;
|
||||
private final ConcurrentMap<String, Integer> mqttQoSMap;
|
||||
private ChannelHandlerContext channel;
|
||||
|
||||
public GatewaySessionCtx(SessionMsgProcessor processor, DeviceService deviceService, DeviceAuthService authService, RelationService relationService, DeviceSessionCtx gatewaySessionCtx) {
|
||||
@ -73,6 +75,7 @@ public class GatewaySessionCtx {
|
||||
this.gateway = gatewaySessionCtx.getDevice();
|
||||
this.gatewaySessionId = gatewaySessionCtx.getSessionId();
|
||||
this.devices = new HashMap<>();
|
||||
this.mqttQoSMap = gatewaySessionCtx.getMqttQoSMap();
|
||||
}
|
||||
|
||||
public void onDeviceConnect(MqttPublishMessage msg) throws AdaptorException {
|
||||
@ -96,7 +99,7 @@ public class GatewaySessionCtx {
|
||||
relationService.saveRelationAsync(new EntityRelation(gateway.getId(), device.getId(), "Created"));
|
||||
processor.onDeviceAdded(device);
|
||||
}
|
||||
GatewayDeviceSessionCtx ctx = new GatewayDeviceSessionCtx(this, device);
|
||||
GatewayDeviceSessionCtx ctx = new GatewayDeviceSessionCtx(this, device, mqttQoSMap);
|
||||
devices.put(deviceName, ctx);
|
||||
log.debug("[{}] Added device [{}] to the gateway session", gatewaySessionId, deviceName);
|
||||
processor.process(new BasicTransportToDeviceSessionActorMsg(device, new BasicAdaptorToSessionActorMsg(ctx, new AttributesSubscribeMsg())));
|
||||
|
||||
@ -0,0 +1,57 @@
|
||||
/**
|
||||
* Copyright © 2016-2018 The Thingsboard Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.thingsboard.server.transport.mqtt.session;
|
||||
|
||||
import io.netty.handler.codec.mqtt.MqttQoS;
|
||||
import org.thingsboard.server.common.data.Device;
|
||||
import org.thingsboard.server.common.transport.SessionMsgProcessor;
|
||||
import org.thingsboard.server.common.transport.auth.DeviceAuthService;
|
||||
import org.thingsboard.server.common.transport.session.DeviceAwareSessionContext;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
/**
|
||||
* Created by ashvayka on 30.08.18.
|
||||
*/
|
||||
public abstract class MqttDeviceAwareSessionContext extends DeviceAwareSessionContext {
|
||||
|
||||
private final ConcurrentMap<String, Integer> mqttQoSMap;
|
||||
|
||||
public MqttDeviceAwareSessionContext(SessionMsgProcessor processor, DeviceAuthService authService, ConcurrentMap<String, Integer> mqttQoSMap) {
|
||||
super(processor, authService);
|
||||
this.mqttQoSMap = mqttQoSMap;
|
||||
}
|
||||
|
||||
public MqttDeviceAwareSessionContext(SessionMsgProcessor processor, DeviceAuthService authService, Device device, ConcurrentMap<String, Integer> mqttQoSMap) {
|
||||
super(processor, authService, device);
|
||||
this.mqttQoSMap = mqttQoSMap;
|
||||
}
|
||||
|
||||
public ConcurrentMap<String, Integer> getMqttQoSMap() {
|
||||
return mqttQoSMap;
|
||||
}
|
||||
|
||||
public MqttQoS getQoSForTopic(String topic) {
|
||||
Integer qos = mqttQoSMap.get(topic);
|
||||
if (qos != null) {
|
||||
return MqttQoS.valueOf(qos);
|
||||
} else {
|
||||
return MqttQoS.AT_LEAST_ONCE;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -251,7 +251,7 @@
|
||||
"fill",
|
||||
"stroke"
|
||||
],
|
||||
"property-no-vendor-prefix": null,
|
||||
"property-no-vendor-prefix": true,
|
||||
"rule-empty-line-before": ["always", {
|
||||
"except": ["first-nested"],
|
||||
"ignore": ["after-comment"]
|
||||
@ -272,7 +272,7 @@
|
||||
"selector-max-type": 5,
|
||||
"selector-max-universal": 1,
|
||||
"selector-no-qualifying-type": null,
|
||||
"selector-no-vendor-prefix": null,
|
||||
"selector-no-vendor-prefix": true,
|
||||
"selector-type-no-unknown": [true, {
|
||||
"ignoreTypes": [
|
||||
"/^md-/",
|
||||
@ -287,6 +287,6 @@
|
||||
"value-list-comma-newline-after": "always-multi-line",
|
||||
"value-list-comma-newline-before": "never-multi-line",
|
||||
"value-list-comma-space-after": "always-single-line",
|
||||
"value-no-vendor-prefix": null
|
||||
"value-no-vendor-prefix": true
|
||||
}
|
||||
}
|
||||
|
||||
@ -119,7 +119,7 @@
|
||||
"ng-annotate-loader": "^0.1.1",
|
||||
"ngtemplate-loader": "^1.3.1",
|
||||
"node-sass": "^4.5.3",
|
||||
"postcss-loader": "^0.13.0",
|
||||
"postcss-loader": "^3.0.0",
|
||||
"raw-loader": "^0.5.1",
|
||||
"react-hot-loader": "^3.0.0-beta.6",
|
||||
"sass-loader": "^4.0.2",
|
||||
@ -145,5 +145,19 @@
|
||||
"node_modules",
|
||||
"target"
|
||||
]
|
||||
},
|
||||
"browserslist": [
|
||||
"> 0.5%",
|
||||
"last 2 versions",
|
||||
"Firefox ESR",
|
||||
"not ie <= 10",
|
||||
"not ie_mob <= 10",
|
||||
"not bb <= 10",
|
||||
"not op_mob <= 12.1"
|
||||
],
|
||||
"postcss": {
|
||||
"plugins": {
|
||||
"autoprefixer": true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -22,7 +22,7 @@ div.tb-widget {
|
||||
overflow: hidden;
|
||||
outline: none;
|
||||
|
||||
@include transition(all .2s ease-in-out);
|
||||
transition: all .2s ease-in-out;
|
||||
|
||||
.tb-widget-title {
|
||||
max-height: 60px;
|
||||
@ -99,7 +99,7 @@ md-content.tb-dashboard-content {
|
||||
outline: none;
|
||||
|
||||
.gridster-item {
|
||||
@include transition(none);
|
||||
transition: none;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -20,7 +20,7 @@
|
||||
}
|
||||
|
||||
.tb-card-item {
|
||||
@include transition(all .2s ease-in-out);
|
||||
transition: all .2s ease-in-out;
|
||||
|
||||
md-card-content {
|
||||
max-height: 53px;
|
||||
@ -46,7 +46,7 @@
|
||||
.tb-current-item {
|
||||
opacity: .5;
|
||||
|
||||
@include transform(scale(1.05));
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
#tb-vertical-container {
|
||||
|
||||
@ -16,7 +16,7 @@
|
||||
@import "~compass-sass-mixins/lib/compass";
|
||||
|
||||
.md-button-toggle .md-toggle-icon.tb-toggled {
|
||||
@include transform(rotateZ(180deg));
|
||||
transform: rotateZ(180deg);
|
||||
}
|
||||
|
||||
.tb-menu-toggle-list.ng-hide {
|
||||
@ -28,7 +28,7 @@
|
||||
z-index: 1;
|
||||
overflow: hidden;
|
||||
|
||||
@include transition(.75s cubic-bezier(.35, 0, .25, 1));
|
||||
transition: .75s cubic-bezier(.35, 0, .25, 1);
|
||||
|
||||
@include transition-property(height);
|
||||
transition-property: height;
|
||||
}
|
||||
|
||||
@ -28,7 +28,7 @@ $input-label-float-scale: .75 !default;
|
||||
line-height: 12px;
|
||||
color: rgb(244, 67, 54);
|
||||
|
||||
@include transition(all 450ms cubic-bezier(.23, 1, .32, 1) 0ms);
|
||||
transition: all 450ms cubic-bezier(.23, 1, .32, 1) 0ms;
|
||||
}
|
||||
|
||||
.tb-container {
|
||||
@ -77,14 +77,13 @@ label.tb-label {
|
||||
bottom: 100%;
|
||||
left: 0;
|
||||
color: rgba(0, 0, 0, .54);
|
||||
|
||||
transition: transform $swift-ease-out-timing-function $swift-ease-out-duration, width $swift-ease-out-timing-function $swift-ease-out-duration;
|
||||
|
||||
transform: translate3d(0, $input-label-float-offset, 0) scale($input-label-float-scale);
|
||||
transform-origin: left top;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
|
||||
@include transform(translate3d(0, $input-label-float-offset, 0) scale($input-label-float-scale));
|
||||
|
||||
@include transition(transform $swift-ease-out-timing-function $swift-ease-out-duration,
|
||||
width $swift-ease-out-timing-function $swift-ease-out-duration);
|
||||
|
||||
&.tb-focused {
|
||||
color: rgb(96, 125, 139);
|
||||
}
|
||||
|
||||
@ -53,7 +53,7 @@
|
||||
margin: auto 0 auto auto;
|
||||
background-size: 100% auto;
|
||||
|
||||
@include transition(transform .3s, ease-in-out);
|
||||
transition: transform .3s, ease-in-out;
|
||||
}
|
||||
|
||||
.tb-side-menu .md-button {
|
||||
|
||||
@ -244,13 +244,18 @@ function ManageWidgetActionsController($rootScope, $scope, $document, $mdDialog,
|
||||
vm.widgetActions[actionSourceId] = targetActions;
|
||||
}
|
||||
if (prevActionId) {
|
||||
var index = getActionIndex(prevActionId, vm.allActions);
|
||||
if (index > -1) {
|
||||
vm.allActions[index] = action;
|
||||
const indexInTarget = getActionIndex(prevActionId, targetActions);
|
||||
const indexInAllActions = getActionIndex(prevActionId, vm.allActions);
|
||||
if (indexInTarget > -1) {
|
||||
targetActions[indexInTarget] = widgetAction;
|
||||
} else if (indexInAllActions > -1) {
|
||||
const prevActionSourceId = vm.allActions[indexInAllActions].actionSourceId;
|
||||
const index = getActionIndex(prevActionId,vm.widgetActions[prevActionSourceId]);
|
||||
vm.widgetActions[prevActionSourceId].splice(index,1);
|
||||
targetActions.push(widgetAction);
|
||||
}
|
||||
index = getActionIndex(prevActionId, targetActions);
|
||||
if (index > -1) {
|
||||
targetActions[index] = widgetAction;
|
||||
if (indexInAllActions > -1) {
|
||||
vm.allActions[indexInAllActions] = action;
|
||||
}
|
||||
} else {
|
||||
vm.allActions.push(action);
|
||||
|
||||
@ -16,12 +16,12 @@
|
||||
|
||||
.tb-dashboard-assigned-customers {
|
||||
display: block;
|
||||
display: -webkit-box;
|
||||
display: -webkit-box; /* stylelint-disable-line value-no-vendor-prefix */
|
||||
height: 34px;
|
||||
margin-bottom: 4px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-box-orient: vertical; /* stylelint-disable-line property-no-vendor-prefix */
|
||||
}
|
||||
|
||||
|
||||
@ -31,7 +31,7 @@ tb-dashboard-toolbar {
|
||||
&.md-fab {
|
||||
opacity: 1;
|
||||
|
||||
@include transition(opacity .3s cubic-bezier(.55,0,.55,.2));
|
||||
transition: opacity .3s cubic-bezier(.55, 0, .55, .2);
|
||||
|
||||
.md-fab-toolbar-background {
|
||||
background-color: $primary-default !important;
|
||||
@ -50,7 +50,7 @@ tb-dashboard-toolbar {
|
||||
line-height: 36px;
|
||||
opacity: .5;
|
||||
|
||||
@include transition(opacity .3s cubic-bezier(.55,0,.55,.2) .2s);
|
||||
transition: opacity .3s cubic-bezier(.55, 0, .55, .2) .2s;
|
||||
|
||||
md-icon {
|
||||
position: absolute;
|
||||
|
||||
@ -75,13 +75,13 @@ section.tb-dashboard-toolbar {
|
||||
|
||||
&.tb-dashboard-toolbar-opened {
|
||||
right: 0;
|
||||
// @include transition(right .3s cubic-bezier(.55,0,.55,.2));
|
||||
// transition: right .3s cubic-bezier(.55, 0, .55, .2);
|
||||
}
|
||||
|
||||
&.tb-dashboard-toolbar-closed {
|
||||
right: 18px;
|
||||
|
||||
@include transition(right .3s cubic-bezier(.55,0,.55,.2) .2s);
|
||||
transition: right .3s cubic-bezier(.55, 0, .55, .2) .2s;
|
||||
}
|
||||
}
|
||||
|
||||
@ -102,14 +102,14 @@ section.tb-dashboard-toolbar {
|
||||
margin-top: $toolbar-height;
|
||||
}
|
||||
|
||||
@include transition(margin-top .3s cubic-bezier(.55,0,.55,.2));
|
||||
transition: margin-top .3s cubic-bezier(.55, 0, .55, .2);
|
||||
}
|
||||
}
|
||||
|
||||
&.tb-dashboard-toolbar-closed {
|
||||
margin-top: 0;
|
||||
|
||||
@include transition(margin-top .3s cubic-bezier(.55,0,.55,.2) .2s);
|
||||
transition: margin-top .3s cubic-bezier(.55, 0, .55, .2) .2s;
|
||||
}
|
||||
|
||||
.tb-dashboard-layouts {
|
||||
@ -133,7 +133,7 @@ section.tb-powered-by-footer {
|
||||
position: absolute;
|
||||
right: 25px;
|
||||
bottom: 5px;
|
||||
z-index: 3;
|
||||
z-index: 30;
|
||||
pointer-events: none;
|
||||
|
||||
span {
|
||||
|
||||
@ -146,7 +146,7 @@
|
||||
ng-style="{minWidth: vm.rightLayoutWidth(),
|
||||
maxWidth: vm.rightLayoutWidth(),
|
||||
height: vm.rightLayoutHeight(),
|
||||
zIndex: 12}"
|
||||
zIndex: 25}"
|
||||
md-component-id="right-dashboard-layout"
|
||||
aria-label="Right dashboard layout"
|
||||
md-is-open="vm.rightLayoutOpened"
|
||||
|
||||
@ -42,7 +42,7 @@
|
||||
border: none;
|
||||
opacity: .75;
|
||||
|
||||
@include transition(opacity .35s);
|
||||
transition: opacity .35s;
|
||||
}
|
||||
|
||||
a:hover,
|
||||
|
||||
@ -84,9 +84,6 @@
|
||||
|
||||
.tb-panel-title {
|
||||
min-width: 150px;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
@ -163,10 +160,6 @@
|
||||
.fc-canvas {
|
||||
min-width: 100%;
|
||||
min-height: 100%;
|
||||
-webkit-user-select: none;
|
||||
-khtml-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
outline: none;
|
||||
-webkit-touch-callout: none;
|
||||
@ -441,13 +434,7 @@
|
||||
}
|
||||
|
||||
.fc-noselect {
|
||||
-webkit-touch-callout: none; /* iOS Safari */
|
||||
-webkit-user-select: none; /* Safari */
|
||||
-khtml-user-select: none; /* Konqueror HTML */
|
||||
-moz-user-select: none; /* Firefox */
|
||||
-ms-user-select: none; /* Internet Explorer/Edge */
|
||||
user-select: none; /* Non-prefixed version, currently
|
||||
supported by Chrome and Opera */
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.fc-edge-label {
|
||||
@ -495,7 +482,6 @@
|
||||
font-weight: 600;
|
||||
text-align: center;
|
||||
white-space: nowrap;
|
||||
-webkit-transform: translate(-50%, -50%);
|
||||
transform: translate(-50%, -50%);
|
||||
|
||||
span {
|
||||
|
||||
@ -29,7 +29,7 @@ md-dialog.tb-node-script-test-dialog {
|
||||
}
|
||||
|
||||
.tb-split {
|
||||
@include box-sizing(border-box);
|
||||
box-sizing: border-box;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
@ -371,7 +371,9 @@ function EntitiesTableWidgetController($element, $scope, $filter, $mdMedia, $mdP
|
||||
content = strContent;
|
||||
}
|
||||
} else {
|
||||
content = defaultContent(key, value);
|
||||
var decimals = (contentInfo.decimals || contentInfo.decimals === 0) ? contentInfo.decimals : vm.widgetConfig.decimals;
|
||||
var units = contentInfo.units || vm.widgetConfig.units;
|
||||
content = vm.ctx.utils.formatValue(value, decimals, units, true);
|
||||
}
|
||||
return content;
|
||||
} else {
|
||||
@ -379,14 +381,6 @@ function EntitiesTableWidgetController($element, $scope, $filter, $mdMedia, $mdP
|
||||
}
|
||||
}
|
||||
|
||||
function defaultContent(key, value) {
|
||||
if (angular.isDefined(value)) {
|
||||
return value;
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
function defaultStyle(/*key, value*/) {
|
||||
return {};
|
||||
}
|
||||
@ -542,7 +536,9 @@ function EntitiesTableWidgetController($element, $scope, $filter, $mdMedia, $mdP
|
||||
|
||||
vm.contentsInfo[dataKey.label] = {
|
||||
useCellContentFunction: useCellContentFunction,
|
||||
cellContentFunction: cellContentFunction
|
||||
cellContentFunction: cellContentFunction,
|
||||
units: dataKey.units,
|
||||
decimals: dataKey.decimals
|
||||
};
|
||||
|
||||
var columnWidth = angular.isDefined(keySettings.columnWidth) ? keySettings.columnWidth : '0px';
|
||||
|
||||
@ -333,6 +333,7 @@ export default class TbFlot {
|
||||
lineWidth: 0,
|
||||
fill: 0.9
|
||||
}
|
||||
ctx.defaultBarWidth = settings.defaultBarWidth || 600;
|
||||
}
|
||||
|
||||
if (this.chartType === 'state') {
|
||||
@ -476,7 +477,11 @@ export default class TbFlot {
|
||||
this.options.yaxes = angular.copy(this.yaxes);
|
||||
if (this.chartType === 'line' || this.chartType === 'bar' || this.chartType === 'state') {
|
||||
if (this.chartType === 'bar') {
|
||||
this.options.series.bars.barWidth = this.subscription.timeWindow.interval * 0.6;
|
||||
if (this.subscription.timeWindowConfig.aggregation && this.subscription.timeWindowConfig.aggregation.type === 'NONE') {
|
||||
this.options.series.bars.barWidth = this.ctx.defaultBarWidth;
|
||||
} else {
|
||||
this.options.series.bars.barWidth = this.subscription.timeWindow.interval * 0.6;
|
||||
}
|
||||
}
|
||||
this.options.xaxis.min = this.subscription.timeWindow.minTime;
|
||||
this.options.xaxis.max = this.subscription.timeWindow.maxTime;
|
||||
@ -594,7 +599,11 @@ export default class TbFlot {
|
||||
this.options.xaxis.min = this.subscription.timeWindow.minTime;
|
||||
this.options.xaxis.max = this.subscription.timeWindow.maxTime;
|
||||
if (this.chartType === 'bar') {
|
||||
this.options.series.bars.barWidth = this.subscription.timeWindow.interval * 0.6;
|
||||
if (this.subscription.timeWindowConfig.aggregation && this.subscription.timeWindowConfig.aggregation.type === 'NONE') {
|
||||
this.options.series.bars.barWidth = this.ctx.defaultBarWidth;
|
||||
} else {
|
||||
this.options.series.bars.barWidth = this.subscription.timeWindow.interval * 0.6;
|
||||
}
|
||||
}
|
||||
|
||||
if (axisVisibilityChanged) {
|
||||
@ -603,7 +612,11 @@ export default class TbFlot {
|
||||
this.ctx.plot.getOptions().xaxes[0].min = this.subscription.timeWindow.minTime;
|
||||
this.ctx.plot.getOptions().xaxes[0].max = this.subscription.timeWindow.maxTime;
|
||||
if (this.chartType === 'bar') {
|
||||
this.ctx.plot.getOptions().series.bars.barWidth = this.subscription.timeWindow.interval * 0.6;
|
||||
if (this.subscription.timeWindowConfig.aggregation && this.subscription.timeWindowConfig.aggregation.type === 'NONE') {
|
||||
this.ctx.plot.getOptions().series.bars.barWidth = this.ctx.defaultBarWidth;
|
||||
} else {
|
||||
this.ctx.plot.getOptions().series.bars.barWidth = this.subscription.timeWindow.interval * 0.6;
|
||||
}
|
||||
}
|
||||
this.updateData();
|
||||
}
|
||||
@ -810,238 +823,257 @@ export default class TbFlot {
|
||||
}
|
||||
}
|
||||
|
||||
static get settingsSchema() {
|
||||
return {
|
||||
static settingsSchema(chartType) {
|
||||
|
||||
var schema = {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"title": "Settings",
|
||||
"properties": {
|
||||
"stack": {
|
||||
"title": "Stacking",
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"smoothLines": {
|
||||
"title": "Display smooth (curved) lines",
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"shadowSize": {
|
||||
"title": "Shadow size",
|
||||
"type": "number",
|
||||
"default": 4
|
||||
},
|
||||
"fontColor": {
|
||||
"title": "Font color",
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var properties = schema["schema"]["properties"];
|
||||
properties["stack"] = {
|
||||
"title": "Stacking",
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
};
|
||||
if (chartType === 'graph') {
|
||||
properties["smoothLines"] = {
|
||||
"title": "Display smooth (curved) lines",
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
};
|
||||
}
|
||||
if (chartType === 'bar') {
|
||||
properties["defaultBarWidth"] = {
|
||||
"title": "Default bar width for non-aggregated data (milliseconds)",
|
||||
"type": "number",
|
||||
"default": 600
|
||||
};
|
||||
}
|
||||
properties["shadowSize"] = {
|
||||
"title": "Shadow size",
|
||||
"type": "number",
|
||||
"default": 4
|
||||
};
|
||||
properties["fontColor"] = {
|
||||
"title": "Font color",
|
||||
"type": "string",
|
||||
"default": "#545454"
|
||||
};
|
||||
properties["fontSize"] = {
|
||||
"title": "Font size",
|
||||
"type": "number",
|
||||
"default": 10
|
||||
};
|
||||
properties["tooltipIndividual"] = {
|
||||
"title": "Hover individual points",
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
};
|
||||
properties["tooltipCumulative"] = {
|
||||
"title": "Show cumulative values in stacking mode",
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
};
|
||||
properties["tooltipValueFormatter"] = {
|
||||
"title": "Tooltip value format function, f(value)",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
};
|
||||
|
||||
properties["grid"] = {
|
||||
"title": "Grid settings",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"color": {
|
||||
"title": "Primary color",
|
||||
"type": "string",
|
||||
"default": "#545454"
|
||||
},
|
||||
"fontSize": {
|
||||
"title": "Font size",
|
||||
"type": "number",
|
||||
"default": 10
|
||||
},
|
||||
"tooltipIndividual": {
|
||||
"title": "Hover individual points",
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"tooltipCumulative": {
|
||||
"title": "Show cumulative values in stacking mode",
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"tooltipValueFormatter": {
|
||||
"title": "Tooltip value format function, f(value)",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"grid": {
|
||||
"title": "Grid settings",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"color": {
|
||||
"title": "Primary color",
|
||||
"type": "string",
|
||||
"default": "#545454"
|
||||
},
|
||||
"backgroundColor": {
|
||||
"title": "Background color",
|
||||
"type": "string",
|
||||
"default": null
|
||||
},
|
||||
"tickColor": {
|
||||
"title": "Ticks color",
|
||||
"type": "string",
|
||||
"default": "#DDDDDD"
|
||||
},
|
||||
"outlineWidth": {
|
||||
"title": "Grid outline/border width (px)",
|
||||
"type": "number",
|
||||
"default": 1
|
||||
},
|
||||
"verticalLines": {
|
||||
"title": "Show vertical lines",
|
||||
"type": "boolean",
|
||||
"default": true
|
||||
},
|
||||
"horizontalLines": {
|
||||
"title": "Show horizontal lines",
|
||||
"type": "boolean",
|
||||
"default": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"xaxis": {
|
||||
"title": "X axis settings",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"showLabels": {
|
||||
"title": "Show labels",
|
||||
"type": "boolean",
|
||||
"default": true
|
||||
},
|
||||
"title": {
|
||||
"title": "Axis title",
|
||||
"type": "string",
|
||||
"default": null
|
||||
},
|
||||
"titleAngle": {
|
||||
"title": "Axis title's angle in degrees",
|
||||
"type": "number",
|
||||
"default": 0
|
||||
},
|
||||
"color": {
|
||||
"title": "Ticks color",
|
||||
"type": "string",
|
||||
"default": null
|
||||
}
|
||||
}
|
||||
},
|
||||
"yaxis": {
|
||||
"title": "Y axis settings",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"min": {
|
||||
"title": "Minimum value on the scale",
|
||||
"type": "number",
|
||||
"default": null
|
||||
},
|
||||
"max": {
|
||||
"title": "Maximum value on the scale",
|
||||
"type": "number",
|
||||
"default": null
|
||||
},
|
||||
"showLabels": {
|
||||
"title": "Show labels",
|
||||
"type": "boolean",
|
||||
"default": true
|
||||
},
|
||||
"title": {
|
||||
"title": "Axis title",
|
||||
"type": "string",
|
||||
"default": null
|
||||
},
|
||||
"titleAngle": {
|
||||
"title": "Axis title's angle in degrees",
|
||||
"type": "number",
|
||||
"default": 0
|
||||
},
|
||||
"color": {
|
||||
"title": "Ticks color",
|
||||
"type": "string",
|
||||
"default": null
|
||||
},
|
||||
"ticksFormatter": {
|
||||
"title": "Ticks formatter function, f(value)",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"tickDecimals": {
|
||||
"title": "The number of decimals to display",
|
||||
"type": "number",
|
||||
"default": 0
|
||||
},
|
||||
"tickSize": {
|
||||
"title": "Step size between ticks",
|
||||
"type": "number",
|
||||
"default": null
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
},
|
||||
"form": [
|
||||
"stack",
|
||||
"smoothLines",
|
||||
"shadowSize",
|
||||
"backgroundColor": {
|
||||
"title": "Background color",
|
||||
"type": "string",
|
||||
"default": null
|
||||
},
|
||||
"tickColor": {
|
||||
"title": "Ticks color",
|
||||
"type": "string",
|
||||
"default": "#DDDDDD"
|
||||
},
|
||||
"outlineWidth": {
|
||||
"title": "Grid outline/border width (px)",
|
||||
"type": "number",
|
||||
"default": 1
|
||||
},
|
||||
"verticalLines": {
|
||||
"title": "Show vertical lines",
|
||||
"type": "boolean",
|
||||
"default": true
|
||||
},
|
||||
"horizontalLines": {
|
||||
"title": "Show horizontal lines",
|
||||
"type": "boolean",
|
||||
"default": true
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
properties["xaxis"] = {
|
||||
"title": "X axis settings",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"showLabels": {
|
||||
"title": "Show labels",
|
||||
"type": "boolean",
|
||||
"default": true
|
||||
},
|
||||
"title": {
|
||||
"title": "Axis title",
|
||||
"type": "string",
|
||||
"default": null
|
||||
},
|
||||
"titleAngle": {
|
||||
"title": "Axis title's angle in degrees",
|
||||
"type": "number",
|
||||
"default": 0
|
||||
},
|
||||
"color": {
|
||||
"title": "Ticks color",
|
||||
"type": "string",
|
||||
"default": null
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
properties["yaxis"] = {
|
||||
"title": "Y axis settings",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"min": {
|
||||
"title": "Minimum value on the scale",
|
||||
"type": "number",
|
||||
"default": null
|
||||
},
|
||||
"max": {
|
||||
"title": "Maximum value on the scale",
|
||||
"type": "number",
|
||||
"default": null
|
||||
},
|
||||
"showLabels": {
|
||||
"title": "Show labels",
|
||||
"type": "boolean",
|
||||
"default": true
|
||||
},
|
||||
"title": {
|
||||
"title": "Axis title",
|
||||
"type": "string",
|
||||
"default": null
|
||||
},
|
||||
"titleAngle": {
|
||||
"title": "Axis title's angle in degrees",
|
||||
"type": "number",
|
||||
"default": 0
|
||||
},
|
||||
"color": {
|
||||
"title": "Ticks color",
|
||||
"type": "string",
|
||||
"default": null
|
||||
},
|
||||
"ticksFormatter": {
|
||||
"title": "Ticks formatter function, f(value)",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"tickDecimals": {
|
||||
"title": "The number of decimals to display",
|
||||
"type": "number",
|
||||
"default": 0
|
||||
},
|
||||
"tickSize": {
|
||||
"title": "Step size between ticks",
|
||||
"type": "number",
|
||||
"default": null
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
schema["schema"]["required"] = [];
|
||||
schema["form"] = ["stack"];
|
||||
if (chartType === 'graph') {
|
||||
schema["form"].push("smoothLines");
|
||||
}
|
||||
if (chartType === 'bar') {
|
||||
schema["form"].push("defaultBarWidth");
|
||||
}
|
||||
schema["form"].push("shadowSize");
|
||||
schema["form"].push({
|
||||
"key": "fontColor",
|
||||
"type": "color"
|
||||
});
|
||||
schema["form"].push("fontSize");
|
||||
schema["form"].push("tooltipIndividual");
|
||||
schema["form"].push("tooltipCumulative");
|
||||
schema["form"].push({
|
||||
"key": "tooltipValueFormatter",
|
||||
"type": "javascript"
|
||||
});
|
||||
schema["form"].push({
|
||||
"key": "grid",
|
||||
"items": [
|
||||
{
|
||||
"key": "fontColor",
|
||||
"key": "grid.color",
|
||||
"type": "color"
|
||||
},
|
||||
"fontSize",
|
||||
"tooltipIndividual",
|
||||
"tooltipCumulative",
|
||||
{
|
||||
"key": "tooltipValueFormatter",
|
||||
"type": "javascript"
|
||||
"key": "grid.backgroundColor",
|
||||
"type": "color"
|
||||
},
|
||||
{
|
||||
"key": "grid",
|
||||
"items": [
|
||||
{
|
||||
"key": "grid.color",
|
||||
"type": "color"
|
||||
},
|
||||
{
|
||||
"key": "grid.backgroundColor",
|
||||
"type": "color"
|
||||
},
|
||||
{
|
||||
"key": "grid.tickColor",
|
||||
"type": "color"
|
||||
},
|
||||
"grid.outlineWidth",
|
||||
"grid.verticalLines",
|
||||
"grid.horizontalLines"
|
||||
]
|
||||
"key": "grid.tickColor",
|
||||
"type": "color"
|
||||
},
|
||||
{
|
||||
"key": "xaxis",
|
||||
"items": [
|
||||
"xaxis.showLabels",
|
||||
"xaxis.title",
|
||||
"xaxis.titleAngle",
|
||||
{
|
||||
"key": "xaxis.color",
|
||||
"type": "color"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "yaxis",
|
||||
"items": [
|
||||
"yaxis.min",
|
||||
"yaxis.max",
|
||||
"yaxis.tickDecimals",
|
||||
"yaxis.tickSize",
|
||||
"yaxis.showLabels",
|
||||
"yaxis.title",
|
||||
"yaxis.titleAngle",
|
||||
{
|
||||
"key": "yaxis.color",
|
||||
"type": "color"
|
||||
},
|
||||
{
|
||||
"key": "yaxis.ticksFormatter",
|
||||
"type": "javascript"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
"grid.outlineWidth",
|
||||
"grid.verticalLines",
|
||||
"grid.horizontalLines"
|
||||
]
|
||||
}
|
||||
});
|
||||
schema["form"].push({
|
||||
"key": "xaxis",
|
||||
"items": [
|
||||
"xaxis.showLabels",
|
||||
"xaxis.title",
|
||||
"xaxis.titleAngle",
|
||||
{
|
||||
"key": "xaxis.color",
|
||||
"type": "color"
|
||||
}
|
||||
]
|
||||
});
|
||||
schema["form"].push({
|
||||
"key": "yaxis",
|
||||
"items": [
|
||||
"yaxis.min",
|
||||
"yaxis.max",
|
||||
"yaxis.tickDecimals",
|
||||
"yaxis.tickSize",
|
||||
"yaxis.showLabels",
|
||||
"yaxis.title",
|
||||
"yaxis.titleAngle",
|
||||
{
|
||||
"key": "yaxis.color",
|
||||
"type": "color"
|
||||
},
|
||||
{
|
||||
"key": "yaxis.ticksFormatter",
|
||||
"type": "javascript"
|
||||
}
|
||||
]
|
||||
});
|
||||
return schema;
|
||||
}
|
||||
|
||||
static get pieDatakeySettingsSchema() {
|
||||
|
||||
@ -37,8 +37,6 @@ $background-color: #e6e7e8 !default;
|
||||
position: relative;
|
||||
|
||||
&[draggable] {
|
||||
-moz-user-select: none;
|
||||
-webkit-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
|
||||
@ -60,19 +60,11 @@ $background-color: #e6e7e8 !default;
|
||||
.led {
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
background-image: -owg-radial-gradient(50% 50%, circle closest-corner, transparent, rgba(0, 0, 0, .25));
|
||||
background-image: -webkit-radial-gradient(50% 50%, circle closest-corner, transparent, rgba(0, 0, 0, .25));
|
||||
background-image: -moz-radial-gradient(50% 50%, circle closest-corner, transparent, rgba(0, 0, 0, .25));
|
||||
background-image: -o-radial-gradient(50% 50%, circle closest-corner, transparent, rgba(0, 0, 0, .25));
|
||||
background-image: radial-gradient(50% 50%, circle closest-corner, transparent, rgba(0, 0, 0, .25));
|
||||
border-radius: 50%;
|
||||
transition: background-color .5s, box-shadow .5s;
|
||||
|
||||
&.disabled {
|
||||
background-image: -owg-radial-gradient(50% 50%, circle closest-corner, rgba(255, 255, 255, .5), rgba(0, 0, 0, .1));
|
||||
background-image: -webkit-radial-gradient(50% 50%, circle closest-corner, rgba(255, 255, 255, .5), rgba(0, 0, 0, .1));
|
||||
background-image: -moz-radial-gradient(50% 50%, circle closest-corner, rgba(255, 255, 255, .5), rgba(0, 0, 0, .1));
|
||||
background-image: -o-radial-gradient(50% 50%, circle closest-corner, rgba(255, 255, 255, .5), rgba(0, 0, 0, .1));
|
||||
background-image: radial-gradient(50% 50%, circle closest-corner, rgba(255, 255, 255, .5), rgba(0, 0, 0, .1));
|
||||
}
|
||||
}
|
||||
|
||||
@ -59,6 +59,8 @@ $background-color: #e6e7e8 !default;
|
||||
|
||||
.switch {
|
||||
position: relative;
|
||||
|
||||
box-sizing: border-box;
|
||||
width: 260px;
|
||||
min-width: 260px;
|
||||
height: 260px;
|
||||
@ -69,21 +71,14 @@ $background-color: #e6e7e8 !default;
|
||||
|
||||
color: #424242;
|
||||
cursor: pointer;
|
||||
-pie-background: -pie-linear-gradient(270deg, #bbb, #ddd);
|
||||
background: #ddd;
|
||||
background: -owg-linear-gradient(270deg, #bbb, #ddd);
|
||||
background: -webkit-linear-gradient(270deg, #bbb, #ddd);
|
||||
background: -moz-linear-gradient(270deg, #bbb, #ddd);
|
||||
background: -o-linear-gradient(270deg, #bbb, #ddd);
|
||||
background: linear-gradient(180deg, #bbb, #ddd);
|
||||
border-radius: 130px;
|
||||
|
||||
@include box-sizing(border-box);
|
||||
|
||||
@include box-shadow(
|
||||
0 0 0 8px rgba(0,0,0,.1)
|
||||
,0 0 3px 1px rgba(0,0,0,.1)
|
||||
,inset 0 8px 3px -8px rgba(255,255,255,.4));
|
||||
box-shadow:
|
||||
0 0 0 8px rgba(0, 0, 0, .1),
|
||||
0 0 3px 1px rgba(0, 0, 0, .1),
|
||||
inset 0 8px 3px -8px rgba(255, 255, 255, .4);
|
||||
|
||||
input {
|
||||
display: none;
|
||||
@ -95,7 +90,7 @@ $background-color: #e6e7e8 !default;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
|
||||
@include text-shadow(1px 1px 4px #4a4a4a);
|
||||
text-shadow: 1px 1px 4px #4a4a4a;
|
||||
}
|
||||
|
||||
.on {
|
||||
@ -103,15 +98,15 @@ $background-color: #e6e7e8 !default;
|
||||
font-family: sans-serif;
|
||||
color: #444;
|
||||
|
||||
@include transition(all .1s);
|
||||
transition: all .1s;
|
||||
}
|
||||
|
||||
.off {
|
||||
bottom: 5px;
|
||||
|
||||
@include transition(all .1s);
|
||||
transition: all .1s;
|
||||
|
||||
@include transform(scaleY(.85));
|
||||
transform: scaleY(.85);
|
||||
}
|
||||
|
||||
.but {
|
||||
@ -125,90 +120,82 @@ $background-color: #e6e7e8 !default;
|
||||
border-bottom-width: 0;
|
||||
border-radius: 400px 400px 400px 400px / 400px 400px 300px 300px;
|
||||
|
||||
@include box-shadow(inset 8px 6px 5px -7px #a2a2a2,
|
||||
inset -8px 6px 5px -7px #a2a2a2,
|
||||
inset 0 -3px 2px -2px rgba(200, 200, 200, .5),
|
||||
0 3px 3px -2px #fff,
|
||||
inset 0 -230px 60px -200px rgba(255, 255, 255, .2),
|
||||
inset 0 220px 40px -200px rgba(0, 0, 0, .3));
|
||||
box-shadow:
|
||||
inset 8px 6px 5px -7px #a2a2a2,
|
||||
inset -8px 6px 5px -7px #a2a2a2,
|
||||
inset 0 -3px 2px -2px rgba(200, 200, 200, .5),
|
||||
0 3px 3px -2px #fff,
|
||||
inset 0 -230px 60px -200px rgba(255, 255, 255, .2),
|
||||
inset 0 220px 40px -200px rgba(0, 0, 0, .3);
|
||||
|
||||
@include transition(all .2s);
|
||||
transition: all .2s;
|
||||
}
|
||||
|
||||
.back {
|
||||
|
||||
box-sizing: border-box;
|
||||
width: 210px;
|
||||
height: 210px;
|
||||
padding: 4px 4px;
|
||||
cursor: pointer;
|
||||
background-color: #888787;
|
||||
background-image: -owg-linear-gradient(0deg, transparent 30%, transparent 70%), -owg-linear-gradient(90deg, rgba(150, 150, 150, 0) 30%, rgba(150, 150, 150, .2) 50%, rgba(150, 150, 150, 0) 70%);
|
||||
background-image: -webkit-linear-gradient(0deg, transparent 30%, transparent 70%), -webkit-linear-gradient(90deg, rgba(150, 150, 150, 0) 30%, rgba(150, 150, 150, .2) 50%, rgba(150, 150, 150, 0) 70%);
|
||||
background-image: -moz-linear-gradient(0deg, transparent 30%, transparent 70%), -moz-linear-gradient(90deg, rgba(150, 150, 150, 0) 30%, rgba(150, 150, 150, .2) 50%, rgba(150, 150, 150, 0) 70%);
|
||||
background-image: -o-linear-gradient(0deg, transparent 30%, transparent 70%), -o-linear-gradient(90deg, rgba(150, 150, 150, 0) 30%, rgba(150, 150, 150, .2) 50%, rgba(150, 150, 150, 0) 70%);
|
||||
background-image: linear-gradient(-90deg, transparent 30%, transparent 70%), linear-gradient(0deg, rgba(150, 150, 150, 0) 30%, rgba(150, 150, 150, .2) 50%, rgba(150, 150, 150, 0) 70%);
|
||||
border-radius: 105px;
|
||||
|
||||
@include box-shadow(30px 30px 30px -20px rgba(58, 58, 58, .3),
|
||||
-30px 30px 30px -20px rgba(58, 58, 58, .3),
|
||||
0 30px 30px 0 rgba(16, 16, 16, .3),
|
||||
inset 0 -1px 0 0 #484848);
|
||||
box-shadow:
|
||||
30px 30px 30px -20px rgba(58, 58, 58, .3),
|
||||
-30px 30px 30px -20px rgba(58, 58, 58, .3),
|
||||
0 30px 30px 0 rgba(16, 16, 16, .3),
|
||||
inset 0 -1px 0 0 #484848;
|
||||
|
||||
@include box-sizing(border-box);
|
||||
|
||||
@include transition(all .2s);
|
||||
transition: all .2s;
|
||||
}
|
||||
|
||||
|
||||
input:checked + .back .on,
|
||||
input:checked + .back .off{
|
||||
@include text-shadow(1px 1px 4px #4a4a4a);
|
||||
text-shadow: 1px 1px 4px #4a4a4a;
|
||||
}
|
||||
|
||||
input:checked + .back .on{
|
||||
top: 10px;
|
||||
color: #4c4c4c;
|
||||
|
||||
@include transform(scaleY(.85));
|
||||
transform: scaleY(.85);
|
||||
}
|
||||
|
||||
input:checked + .back .off{
|
||||
bottom: 5px;
|
||||
color: #444;
|
||||
|
||||
@include transform(scaleY(1));
|
||||
transform: scaleY(1);
|
||||
}
|
||||
|
||||
input:checked + .back .but{
|
||||
margin-top: 20px;
|
||||
background: #dcdcdc;
|
||||
background-image: -owg-radial-gradient(50% 15%, circle closest-corner, rgba(0, 0, 0, .3), transparent);
|
||||
background-image: -webkit-radial-gradient(50% 15%, circle closest-corner, rgba(0, 0, 0, .3), transparent);
|
||||
background-image: -moz-radial-gradient(50% 15%, circle closest-corner, rgba(0, 0, 0, .3), transparent);
|
||||
background-image: -o-radial-gradient(50% 15%, circle closest-corner, rgba(0, 0, 0, .3), transparent);
|
||||
background-image: radial-gradient(50% 15%, circle closest-corner, rgba(0, 0, 0, .3), transparent);
|
||||
border-radius: 400px 400px 400px 400px / 300px 300px 400px 400px;
|
||||
|
||||
@include box-shadow(inset 8px -4px 5px -7px #a9a9a9,
|
||||
inset -8px -4px 5px -7px #808080,
|
||||
0 -3px 8px -4px rgba(50, 50, 50, .4),
|
||||
inset 0 3px 4px -2px #9c9c9c,
|
||||
inset 0 280px 40px -200px rgba(0, 0, 0, .2),
|
||||
inset 0 -200px 40px -200px rgba(180, 180, 180, .2));
|
||||
box-shadow:
|
||||
inset 8px -4px 5px -7px #a9a9a9,
|
||||
inset -8px -4px 5px -7px #808080,
|
||||
0 -3px 8px -4px rgba(50, 50, 50, .4),
|
||||
inset 0 3px 4px -2px #9c9c9c,
|
||||
inset 0 280px 40px -200px rgba(0, 0, 0, .2),
|
||||
inset 0 -200px 40px -200px rgba(180, 180, 180, .2);
|
||||
}
|
||||
|
||||
input:checked + .back{
|
||||
padding: 2px 4px;
|
||||
|
||||
background-image: -owg-linear-gradient(90deg, #868686 30%, transparent 70%), -owg-linear-gradient(180deg, rgba(115, 115, 115, 0) 0%, rgba(255, 255, 255, .74) 50%, rgba(105, 105, 105, 0) 100%);
|
||||
background-image: -webkit-linear-gradient(90deg, #868686 30%, transparent 70%), -webkit-linear-gradient(180deg, rgba(115, 115, 115, 0) 0%, rgba(255, 255, 255, .74) 50%, rgba(105, 105, 105, 0) 100%);
|
||||
background-image: -moz-linear-gradient(90deg, #868686 30%, transparent 70%), -moz-linear-gradient(180deg, rgba(115, 115, 115, 0) 0%, rgba(255, 255, 255, .74) 50%, rgba(105, 105, 105, 0) 100%);
|
||||
background-image: -o-linear-gradient(90deg, #868686 30%, transparent 70%), -o-linear-gradient(180deg, rgba(115, 115, 115, 0) 0%, rgba(255, 255, 255, .74) 50%, rgba(105, 105, 105, 0) 100%);
|
||||
background-image: linear-gradient(0deg, #868686 30%, transparent 70%), linear-gradient(90deg, rgba(115, 115, 115, 0) 0%, rgba(255, 255, 255, .74) 50%, rgba(105, 105, 105, 0) 100%);
|
||||
|
||||
@include box-shadow(30px 30px 30px -20px rgba(49, 49, 49, .1),
|
||||
-30px 30px 30px -20px rgba(111, 111, 111, .1),
|
||||
0 30px 30px 0 rgba(0, 0, 0, .2),
|
||||
inset 0 1px 2px 0 rgba(167, 167, 167, .6));
|
||||
box-shadow:
|
||||
30px 30px 30px -20px rgba(49, 49, 49, .1),
|
||||
-30px 30px 30px -20px rgba(111, 111, 111, .1),
|
||||
0 30px 30px 0 rgba(0, 0, 0, .2),
|
||||
inset 0 1px 2px 0 rgba(167, 167, 167, .6);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -217,7 +217,9 @@ function TimeseriesTableWidgetController($element, $scope, $filter, $timeout) {
|
||||
content = strContent;
|
||||
}
|
||||
} else {
|
||||
content = vm.ctx.utils.formatValue(value, contentInfo.decimals, contentInfo.units);
|
||||
var decimals = (contentInfo.decimals || contentInfo.decimals === 0) ? contentInfo.decimals : vm.widgetConfig.decimals;
|
||||
var units = contentInfo.units || vm.widgetConfig.units;
|
||||
content = vm.ctx.utils.formatValue(value, decimals, units, true);
|
||||
}
|
||||
return content;
|
||||
}
|
||||
|
||||
@ -19,7 +19,7 @@ $edit-toolbar-height: 40px !default;
|
||||
|
||||
.tb-editor {
|
||||
.tb-split {
|
||||
@include box-sizing(border-box);
|
||||
box-sizing: border-box;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
@ -15,34 +15,34 @@
|
||||
*/
|
||||
@import "~compass-sass-mixins/lib/animate";
|
||||
|
||||
@include keyframes(tbMoveFromTopFade) {
|
||||
@keyframes tbMoveFromTopFade {
|
||||
from {
|
||||
opacity: 0;
|
||||
|
||||
@include transform(translate(0, -100%));
|
||||
transform: translate(0, -100%);
|
||||
}
|
||||
}
|
||||
|
||||
@include keyframes(tbMoveToTopFade) {
|
||||
@keyframes tbMoveToTopFade {
|
||||
to {
|
||||
opacity: 0;
|
||||
|
||||
@include transform(translate(0, -100%));
|
||||
transform: translate(0, -100%);
|
||||
}
|
||||
}
|
||||
|
||||
@include keyframes(tbMoveFromBottomFade) {
|
||||
@keyframes tbMoveFromBottomFade {
|
||||
from {
|
||||
opacity: 0;
|
||||
|
||||
@include transform(translate(0, 100%));
|
||||
transform: translate(0, 100%);
|
||||
}
|
||||
}
|
||||
|
||||
@include keyframes(tbMoveToBottomFade) {
|
||||
@keyframes tbMoveToBottomFade {
|
||||
to {
|
||||
opacity: 0;
|
||||
|
||||
@include transform(translate(0, 150%));
|
||||
transform: translate(0, 150%);
|
||||
}
|
||||
}
|
||||
|
||||
@ -42,7 +42,7 @@ textarea {
|
||||
word-wrap: normal;
|
||||
white-space: nowrap;
|
||||
direction: ltr;
|
||||
-webkit-font-feature-settings: "liga";
|
||||
-webkit-font-feature-settings: "liga"; /* stylelint-disable-line property-no-vendor-prefix */
|
||||
}
|
||||
|
||||
a {
|
||||
@ -51,7 +51,7 @@ a {
|
||||
text-decoration: none;
|
||||
border-bottom: 1px solid rgba(64, 84, 178, .25);
|
||||
|
||||
@include transition(border-bottom .35s);
|
||||
transition: border-bottom .35s;
|
||||
}
|
||||
|
||||
a:hover,
|
||||
@ -258,13 +258,7 @@ label {
|
||||
}
|
||||
|
||||
.tb-noselect {
|
||||
-webkit-touch-callout: none; /* iOS Safari */
|
||||
-webkit-user-select: none; /* Safari */
|
||||
-khtml-user-select: none; /* Konqueror HTML */
|
||||
-moz-user-select: none; /* Firefox */
|
||||
-ms-user-select: none; /* Internet Explorer/Edge */
|
||||
user-select: none; /* Non-prefixed version, currently
|
||||
supported by Chrome and Opera */
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.tb-readonly-label {
|
||||
@ -556,7 +550,7 @@ $previewSize: 100px !default;
|
||||
}
|
||||
|
||||
.tb-error-message.ng-animate {
|
||||
@include transition(all .3s cubic-bezier(.55, 0, .55, .2));
|
||||
transition: all .3s cubic-bezier(.55, 0, .55, .2);
|
||||
}
|
||||
|
||||
.tb-error-message.ng-enter-prepare,
|
||||
@ -652,13 +646,13 @@ section.tb-top-header-buttons {
|
||||
}
|
||||
|
||||
.tb-header-buttons .tb-btn-header {
|
||||
@include animation(tbMoveFromTopFade .3s ease both);
|
||||
position: relative !important;
|
||||
display: inline-block !important;
|
||||
animation: tbMoveFromTopFade .3s ease both;
|
||||
}
|
||||
|
||||
.tb-header-buttons .tb-btn-header.ng-hide {
|
||||
@include animation(tbMoveToTopFade .3s ease both);
|
||||
animation: tbMoveToTopFade .3s ease both;
|
||||
}
|
||||
|
||||
/***********************
|
||||
@ -669,24 +663,24 @@ section.tb-footer-buttons {
|
||||
position: fixed;
|
||||
right: 20px;
|
||||
bottom: 20px;
|
||||
z-index: 13;
|
||||
z-index: 30;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.tb-footer-buttons .tb-btn-footer {
|
||||
@include animation(tbMoveFromBottomFade .3s ease both);
|
||||
position: relative !important;
|
||||
display: inline-block !important;
|
||||
animation: tbMoveFromBottomFade .3s ease both;
|
||||
}
|
||||
|
||||
.tb-footer-buttons .tb-btn-footer.ng-hide {
|
||||
@include animation(tbMoveToBottomFade .3s ease both);
|
||||
animation: tbMoveToBottomFade .3s ease both;
|
||||
}
|
||||
|
||||
._md-toast-open-bottom .tb-footer-buttons {
|
||||
@include transition(all .4s cubic-bezier(.25, .8, .25, 1));
|
||||
transition: all .4s cubic-bezier(.25, .8, .25, 1);
|
||||
|
||||
@include transform(translate3d(0, -42px, 0));
|
||||
transform: translate3d(0, -42px, 0);
|
||||
}
|
||||
|
||||
/***********************
|
||||
|
||||
@ -15,6 +15,7 @@
|
||||
*/
|
||||
@import "~compass-sass-mixins/lib/compass";
|
||||
|
||||
/* stylelint-disable selector-no-vendor-prefix */
|
||||
@mixin input-placeholder {
|
||||
// replaces compass/css/user-interface/input-placeholder()
|
||||
|
||||
@ -36,6 +37,7 @@
|
||||
@content;
|
||||
}
|
||||
}
|
||||
/* stylelint-enable selector-no-vendor-prefix */
|
||||
|
||||
@mixin line-clamp($numLines: 1, $lineHeight: 1.412) {
|
||||
position: relative;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user