latest = ctx.getAlarmService().findAlarmByIdAsync(ctx.getTenantId(), alarm.getId());
Futures.addCallback(latest, new FutureCallback<>() {
@@ -78,7 +79,11 @@ public class TbCheckAlarmStatusNode implements TbNode {
}
}, ctx.getDbCallbackExecutor());
} catch (Exception e) {
- log.error("Failed to parse alarm: [{}]", msg.getData());
+ if (e instanceof IllegalArgumentException || e instanceof NullPointerException) {
+ log.debug("[{}][{}] Failed to parse alarm: [{}] error [{}]", ctx.getTenantId(), ctx.getRuleChainName(), msg.getData(), e.getMessage());
+ } else {
+ log.error("[{}][{}] Failed to parse alarm: [{}]", ctx.getTenantId(), ctx.getRuleChainName(), msg.getData(), e);
+ }
throw new TbNodeException(e);
}
}
diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/filter/TbCheckAlarmStatusNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/filter/TbCheckAlarmStatusNodeTest.java
index c79f962818..5b71db5dfb 100644
--- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/filter/TbCheckAlarmStatusNodeTest.java
+++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/filter/TbCheckAlarmStatusNodeTest.java
@@ -38,8 +38,10 @@ import org.thingsboard.server.common.msg.TbMsgMetaData;
import java.util.UUID;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.BDDMockito.willReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
@@ -158,6 +160,19 @@ class TbCheckAlarmStatusNodeTest {
assertThat(value).isInstanceOf(TbNodeException.class).hasMessage("No such alarm found.");
}
+ @Test
+ void givenUnparseableAlarm_whenOnMsg_then_Failure() {
+ String msgData = "{\"Number\":1113718,\"id\":8.1}";
+ TbMsg msg = getTbMsg(msgData);
+ willReturn("Default Rule Chain").given(ctx).getRuleChainName();
+
+ assertThatThrownBy(() -> node.onMsg(ctx, msg))
+ .as("onMsg")
+ .isInstanceOf(TbNodeException.class)
+ .hasCauseInstanceOf(IllegalArgumentException.class)
+ .hasMessage("java.lang.IllegalArgumentException: The given string value cannot be transformed to Json object: {\"Number\":1113718,\"id\":8.1}");
+ }
+
private TbMsg getTbMsg(String msgData) {
return TbMsg.newMsg(TbMsgType.POST_ATTRIBUTES_REQUEST, DEVICE_ID, TbMsgMetaData.EMPTY, msgData);
}
diff --git a/rule-engine/rule-engine-components/src/test/resources/logback-test.xml b/rule-engine/rule-engine-components/src/test/resources/logback-test.xml
new file mode 100644
index 0000000000..0695fe1e1a
--- /dev/null
+++ b/rule-engine/rule-engine-components/src/test/resources/logback-test.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+ %d{ISO8601} [%thread] %-5level %logger{36} - %msg%n
+
+
+
+
+
+
+
+
+
+
diff --git a/ui-ngx/.eslintrc.json b/ui-ngx/.eslintrc.json
index cf9f0e8238..764733e4d7 100644
--- a/ui-ngx/.eslintrc.json
+++ b/ui-ngx/.eslintrc.json
@@ -51,7 +51,8 @@
"import/order": "off",
"@typescript-eslint/member-ordering": "off",
"no-underscore-dangle": "off",
- "@typescript-eslint/naming-convention": "off"
+ "@typescript-eslint/naming-convention": "off",
+ "jsdoc/newline-after-description": 0
}
},
{
diff --git a/ui-ngx/package.json b/ui-ngx/package.json
index af2092e933..a5304207f5 100644
--- a/ui-ngx/package.json
+++ b/ui-ngx/package.json
@@ -30,7 +30,7 @@
"@date-io/date-fns": "1.3.7",
"@flowjs/flow.js": "^2.14.1",
"@flowjs/ngx-flow": "~0.6.0",
- "@geoman-io/leaflet-geoman-free": "^2.13.0",
+ "@geoman-io/leaflet-geoman-free": "2.14.2",
"@iplab/ngx-color-picker": "^15.0.2",
"@juggle/resize-observer": "^3.4.0",
"@mat-datetimepicker/core": "~11.0.3",
@@ -55,7 +55,7 @@
"core-js": "^3.29.1",
"date-fns": "2.0.0-alpha.27",
"dayjs": "1.11.4",
- "echarts": "^5.5.0",
+ "echarts": "https://github.com/thingsboard/echarts/archive/5.5.0-TB.tar.gz",
"flot": "https://github.com/thingsboard/flot.git#0.9-work",
"flot.curvedlines": "https://github.com/MichaelZinsmaier/CurvedLines.git#master",
"font-awesome": "^4.7.0",
@@ -67,11 +67,11 @@
"jstree": "^3.3.15",
"jstree-bootstrap-theme": "^1.0.1",
"jszip": "^3.10.1",
- "leaflet": "~1.8.0",
- "leaflet-polylinedecorator": "^1.6.0",
- "leaflet-providers": "^1.13.0",
- "leaflet.gridlayer.googlemutant": "^0.13.5",
- "leaflet.markercluster": "^1.5.3",
+ "leaflet": "1.8.0",
+ "leaflet-polylinedecorator": "1.6.0",
+ "leaflet-providers": "1.13.0",
+ "leaflet.gridlayer.googlemutant": "0.14.1",
+ "leaflet.markercluster": "1.5.3",
"libphonenumber-js": "^1.10.4",
"marked": "^4.0.17",
"moment": "^2.29.4",
@@ -130,11 +130,11 @@
"@types/jasminewd2": "^2.0.10",
"@types/jquery": "^3.5.16",
"@types/js-beautify": "^1.13.3",
- "@types/leaflet": "~1.8.0",
- "@types/leaflet-polylinedecorator": "^1.6.1",
- "@types/leaflet-providers": "^1.2.1",
- "@types/leaflet.gridlayer.googlemutant": "^0.4.6",
- "@types/leaflet.markercluster": "^1.5.1",
+ "@types/leaflet": "1.8.0",
+ "@types/leaflet-polylinedecorator": "1.6.4",
+ "@types/leaflet-providers": "1.2.4",
+ "@types/leaflet.gridlayer.googlemutant": "0.4.9",
+ "@types/leaflet.markercluster": "1.5.4",
"@types/lodash": "^4.14.192",
"@types/marked": "^4.0.8",
"@types/node": "~18.15.11",
diff --git a/ui-ngx/patches/echarts+5.5.0.patch b/ui-ngx/patches/echarts+5.5.0.patch
deleted file mode 100644
index 4f1ebed81a..0000000000
--- a/ui-ngx/patches/echarts+5.5.0.patch
+++ /dev/null
@@ -1,426 +0,0 @@
-diff --git a/node_modules/echarts/lib/component/dataZoom/DataZoomModel.js b/node_modules/echarts/lib/component/dataZoom/DataZoomModel.js
-index d6c05f3..aafb0b8 100644
---- a/node_modules/echarts/lib/component/dataZoom/DataZoomModel.js
-+++ b/node_modules/echarts/lib/component/dataZoom/DataZoomModel.js
-@@ -362,7 +362,10 @@ var DataZoomModel = /** @class */function (_super) {
- return axisProxy.getDataValueWindow();
- }
- } else {
-- return this.getAxisProxy(axisDim, axisIndex).getDataValueWindow();
-+ var axisProxy = this.getAxisProxy(axisDim, axisIndex);
-+ if (axisProxy) {
-+ return axisProxy.getDataValueWindow();
-+ }
- }
- };
- /**
-@@ -381,10 +384,10 @@ var DataZoomModel = /** @class */function (_super) {
- var axisInfo = this._targetAxisInfoMap.get(axisDim);
- for (var j = 0; j < axisInfo.indexList.length; j++) {
- var proxy = this.getAxisProxy(axisDim, axisInfo.indexList[j]);
-- if (proxy.hostedBy(this)) {
-+ if (proxy && proxy.hostedBy(this)) {
- return proxy;
- }
-- if (!firstProxy) {
-+ if (proxy && !firstProxy) {
- firstProxy = proxy;
- }
- }
-diff --git a/node_modules/echarts/lib/component/dataZoom/InsideZoomView.js b/node_modules/echarts/lib/component/dataZoom/InsideZoomView.js
-index 06469b2..cf0b2ea 100644
---- a/node_modules/echarts/lib/component/dataZoom/InsideZoomView.js
-+++ b/node_modules/echarts/lib/component/dataZoom/InsideZoomView.js
-@@ -96,11 +96,14 @@ var getRangeHandlers = {
- range[0] = (range[0] - percentPoint) * scale + percentPoint;
- range[1] = (range[1] - percentPoint) * scale + percentPoint;
- // Restrict range.
-- var minMaxSpan = this.dataZoomModel.findRepresentativeAxisProxy().getMinMaxSpan();
-- sliderMove(0, range, [0, 100], 0, minMaxSpan.minSpan, minMaxSpan.maxSpan);
-- this.range = range;
-- if (lastRange[0] !== range[0] || lastRange[1] !== range[1]) {
-- return range;
-+ var proxy = this.dataZoomModel.findRepresentativeAxisProxy();
-+ if (proxy) {
-+ var minMaxSpan = proxy.getMinMaxSpan();
-+ sliderMove(0, range, [0, 100], 0, minMaxSpan.minSpan, minMaxSpan.maxSpan);
-+ this.range = range;
-+ if (lastRange[0] !== range[0] || lastRange[1] !== range[1]) {
-+ return range;
-+ }
- }
- },
- pan: makeMover(function (range, axisModel, coordSysInfo, coordSysMainType, controller, e) {
-diff --git a/node_modules/echarts/lib/component/dataZoom/SliderZoomView.js b/node_modules/echarts/lib/component/dataZoom/SliderZoomView.js
-index 98912e0..0cda6be 100644
---- a/node_modules/echarts/lib/component/dataZoom/SliderZoomView.js
-+++ b/node_modules/echarts/lib/component/dataZoom/SliderZoomView.js
-@@ -64,7 +64,7 @@ var DEFAULT_MOVE_HANDLE_SIZE = 7;
- var HORIZONTAL = 'horizontal';
- var VERTICAL = 'vertical';
- var LABEL_GAP = 5;
--var SHOW_DATA_SHADOW_SERIES_TYPE = ['line', 'bar', 'candlestick', 'scatter'];
-+var SHOW_DATA_SHADOW_SERIES_TYPE = ['line', 'bar', 'candlestick', 'scatter', 'custom'];
- var REALTIME_ANIMATION_CONFIG = {
- easing: 'cubicOut',
- duration: 100,
-@@ -359,30 +359,33 @@ var SliderZoomView = /** @class */function (_super) {
- var result;
- var ecModel = this.ecModel;
- dataZoomModel.eachTargetAxis(function (axisDim, axisIndex) {
-- var seriesModels = dataZoomModel.getAxisProxy(axisDim, axisIndex).getTargetSeriesModels();
-- each(seriesModels, function (seriesModel) {
-- if (result) {
-- return;
-- }
-- if (showDataShadow !== true && indexOf(SHOW_DATA_SHADOW_SERIES_TYPE, seriesModel.get('type')) < 0) {
-- return;
-- }
-- var thisAxis = ecModel.getComponent(getAxisMainType(axisDim), axisIndex).axis;
-- var otherDim = getOtherDim(axisDim);
-- var otherAxisInverse;
-- var coordSys = seriesModel.coordinateSystem;
-- if (otherDim != null && coordSys.getOtherAxis) {
-- otherAxisInverse = coordSys.getOtherAxis(thisAxis).inverse;
-- }
-- otherDim = seriesModel.getData().mapDimension(otherDim);
-- result = {
-- thisAxis: thisAxis,
-- series: seriesModel,
-- thisDim: axisDim,
-- otherDim: otherDim,
-- otherAxisInverse: otherAxisInverse
-- };
-- }, this);
-+ var axisProxy = dataZoomModel.getAxisProxy(axisDim, axisIndex);
-+ if (axisProxy) {
-+ var seriesModels = axisProxy.getTargetSeriesModels();
-+ each(seriesModels, function (seriesModel) {
-+ if (result) {
-+ return;
-+ }
-+ if (showDataShadow !== true && indexOf(SHOW_DATA_SHADOW_SERIES_TYPE, seriesModel.get('type')) < 0) {
-+ return;
-+ }
-+ var thisAxis = ecModel.getComponent(getAxisMainType(axisDim), axisIndex).axis;
-+ var otherDim = getOtherDim(axisDim);
-+ var otherAxisInverse;
-+ var coordSys = seriesModel.coordinateSystem;
-+ if (otherDim != null && coordSys.getOtherAxis) {
-+ otherAxisInverse = coordSys.getOtherAxis(thisAxis).inverse;
-+ }
-+ otherDim = seriesModel.getData().mapDimension(otherDim);
-+ result = {
-+ thisAxis: thisAxis,
-+ series: seriesModel,
-+ thisDim: axisDim,
-+ otherDim: otherDim,
-+ otherAxisInverse: otherAxisInverse
-+ };
-+ }, this);
-+ }
- }, this);
- return result;
- };
-@@ -530,12 +533,17 @@ var SliderZoomView = /** @class */function (_super) {
- var dataZoomModel = this.dataZoomModel;
- var handleEnds = this._handleEnds;
- var viewExtend = this._getViewExtent();
-- var minMaxSpan = dataZoomModel.findRepresentativeAxisProxy().getMinMaxSpan();
-- var percentExtent = [0, 100];
-- sliderMove(delta, handleEnds, viewExtend, dataZoomModel.get('zoomLock') ? 'all' : handleIndex, minMaxSpan.minSpan != null ? linearMap(minMaxSpan.minSpan, percentExtent, viewExtend, true) : null, minMaxSpan.maxSpan != null ? linearMap(minMaxSpan.maxSpan, percentExtent, viewExtend, true) : null);
-- var lastRange = this._range;
-- var range = this._range = asc([linearMap(handleEnds[0], viewExtend, percentExtent, true), linearMap(handleEnds[1], viewExtend, percentExtent, true)]);
-- return !lastRange || lastRange[0] !== range[0] || lastRange[1] !== range[1];
-+ var proxy = dataZoomModel.findRepresentativeAxisProxy();
-+ if (proxy) {
-+ var minMaxSpan = proxy.getMinMaxSpan();
-+ var percentExtent = [0, 100];
-+ sliderMove(delta, handleEnds, viewExtend, dataZoomModel.get('zoomLock') ? 'all' : handleIndex, minMaxSpan.minSpan != null ? linearMap(minMaxSpan.minSpan, percentExtent, viewExtend, true) : null, minMaxSpan.maxSpan != null ? linearMap(minMaxSpan.maxSpan, percentExtent, viewExtend, true) : null);
-+ var lastRange = this._range;
-+ var range = this._range = asc([linearMap(handleEnds[0], viewExtend, percentExtent, true), linearMap(handleEnds[1], viewExtend, percentExtent, true)]);
-+ return !lastRange || lastRange[0] !== range[0] || lastRange[1] !== range[1];
-+ } else {
-+ return false;
-+ }
- };
- SliderZoomView.prototype._updateView = function (nonRealtime) {
- var displaybles = this._displayables;
-diff --git a/node_modules/echarts/lib/component/dataZoom/dataZoomProcessor.js b/node_modules/echarts/lib/component/dataZoom/dataZoomProcessor.js
-index ce98fed..e154118 100644
---- a/node_modules/echarts/lib/component/dataZoom/dataZoomProcessor.js
-+++ b/node_modules/echarts/lib/component/dataZoom/dataZoomProcessor.js
-@@ -90,7 +90,10 @@ var dataZoomProcessor = {
- // init stage and not after action dispatch handler, because
- // reset should be called after seriesData.restoreData.
- dataZoomModel.eachTargetAxis(function (axisDim, axisIndex) {
-- dataZoomModel.getAxisProxy(axisDim, axisIndex).reset(dataZoomModel);
-+ var axisProxy = dataZoomModel.getAxisProxy(axisDim, axisIndex);
-+ if (axisProxy) {
-+ axisProxy.reset(dataZoomModel);
-+ }
- });
- // Caution: data zoom filtering is order sensitive when using
- // percent range and no min/max/scale set on axis.
-@@ -107,7 +110,10 @@ var dataZoomProcessor = {
- // So we should filter x-axis after reset x-axis immediately,
- // and then reset y-axis and filter y-axis.
- dataZoomModel.eachTargetAxis(function (axisDim, axisIndex) {
-- dataZoomModel.getAxisProxy(axisDim, axisIndex).filterData(dataZoomModel, api);
-+ var axisProxy = dataZoomModel.getAxisProxy(axisDim, axisIndex);
-+ if (axisProxy) {
-+ axisProxy.filterData(dataZoomModel, api);
-+ }
- });
- });
- ecModel.eachComponent('dataZoom', function (dataZoomModel) {
-diff --git a/node_modules/echarts/lib/component/toolbox/feature/DataZoom.js b/node_modules/echarts/lib/component/toolbox/feature/DataZoom.js
-index cf8d6bc..f9b9f90 100644
---- a/node_modules/echarts/lib/component/toolbox/feature/DataZoom.js
-+++ b/node_modules/echarts/lib/component/toolbox/feature/DataZoom.js
-@@ -109,9 +109,12 @@ var DataZoomFeature = /** @class */function (_super) {
- var axisModel = axis.model;
- var dataZoomModel = findDataZoom(dimName, axisModel, ecModel);
- // Restrict range.
-- var minMaxSpan = dataZoomModel.findRepresentativeAxisProxy(axisModel).getMinMaxSpan();
-- if (minMaxSpan.minValueSpan != null || minMaxSpan.maxValueSpan != null) {
-- minMax = sliderMove(0, minMax.slice(), axis.scale.getExtent(), 0, minMaxSpan.minValueSpan, minMaxSpan.maxValueSpan);
-+ var proxy = dataZoomModel.findRepresentativeAxisProxy(axisModel);
-+ if (proxy) {
-+ var minMaxSpan = proxy.getMinMaxSpan();
-+ if (minMaxSpan.minValueSpan != null || minMaxSpan.maxValueSpan != null) {
-+ minMax = sliderMove(0, minMax.slice(), axis.scale.getExtent(), 0, minMaxSpan.minValueSpan, minMaxSpan.maxValueSpan);
-+ }
- }
- dataZoomModel && (snapshot[dataZoomModel.id] = {
- dataZoomId: dataZoomModel.id,
-diff --git a/node_modules/echarts/lib/component/tooltip/TooltipView.js b/node_modules/echarts/lib/component/tooltip/TooltipView.js
-index b8a9b95..11e49c0 100644
---- a/node_modules/echarts/lib/component/tooltip/TooltipView.js
-+++ b/node_modules/echarts/lib/component/tooltip/TooltipView.js
-@@ -360,7 +360,7 @@ var TooltipView = /** @class */function (_super) {
- each(itemCoordSys.dataByAxis, function (axisItem) {
- var axisModel = ecModel.getComponent(axisItem.axisDim + 'Axis', axisItem.axisIndex);
- var axisValue = axisItem.value;
-- if (!axisModel || axisValue == null) {
-+ if (!axisModel || !axisModel.axis || axisValue == null) {
- return;
- }
- var axisValueLabel = axisPointerViewHelper.getValueLabel(axisValue, axisModel.axis, ecModel, axisItem.seriesDataIndices, axisItem.valueLabelOpt);
-diff --git a/node_modules/echarts/lib/coord/axisHelper.js b/node_modules/echarts/lib/coord/axisHelper.js
-index a76c66b..e5b7ee5 100644
---- a/node_modules/echarts/lib/coord/axisHelper.js
-+++ b/node_modules/echarts/lib/coord/axisHelper.js
-@@ -187,7 +187,9 @@ export function createScaleByModel(model, axisType) {
- });
- default:
- // case 'value'/'interval', 'log', or others.
-- return new (Scale.getClass(axisType) || IntervalScale)();
-+ return new (Scale.getClass(axisType) || IntervalScale)({
-+ ticksGenerator: model.get('ticksGenerator')
-+ });
- }
- }
- }
-diff --git a/node_modules/echarts/lib/coord/cartesian/Grid.js b/node_modules/echarts/lib/coord/cartesian/Grid.js
-index 5b18f02..39a57f8 100644
---- a/node_modules/echarts/lib/coord/cartesian/Grid.js
-+++ b/node_modules/echarts/lib/coord/cartesian/Grid.js
-@@ -91,11 +91,11 @@ var Grid = /** @class */function () {
- var scale = axis.scale;
- if (
- // Only value and log axis without interval support alignTicks.
-- isIntervalOrLogScale(scale) && model.get('alignTicks') && model.get('interval') == null) {
-+ isIntervalOrLogScale(scale) && model.get('alignTicks') && model.get('interval') == null && model.get('ticksGenerator') == null) {
- axisNeedsAlign.push(axis);
- } else {
- niceScaleExtent(scale, model);
-- if (isIntervalOrLogScale(scale)) {
-+ if (isIntervalOrLogScale(scale) && !scale.isBlank()) {
- // Can only align to interval or log axis.
- alignTo = axis;
- }
-@@ -105,10 +105,15 @@ var Grid = /** @class */function () {
- // All axes has set alignTicks. Pick the first one.
- // PENDING. Should we find the axis that both set interval, min, max and align to this one?
- if (axisNeedsAlign.length) {
-- if (!alignTo) {
-- alignTo = axisNeedsAlign.pop();
-- niceScaleExtent(alignTo.scale, alignTo.model);
-+ while (!alignTo && axisNeedsAlign.length) {
-+ var axis = axisNeedsAlign.pop();
-+ niceScaleExtent(axis.scale, axis.model);
-+ if (!axis.scale.isBlank()) {
-+ alignTo = axis;
-+ }
- }
-+ }
-+ if (axisNeedsAlign.length && alignTo) {
- each(axisNeedsAlign, function (axis) {
- alignScaleTicks(axis.scale, axis.model, alignTo.scale);
- });
-diff --git a/node_modules/echarts/lib/data/SeriesData.js b/node_modules/echarts/lib/data/SeriesData.js
-index 98d5ce8..1c293a6 100644
---- a/node_modules/echarts/lib/data/SeriesData.js
-+++ b/node_modules/echarts/lib/data/SeriesData.js
-@@ -900,13 +900,16 @@ var SeriesData = /** @class */function () {
- var dimInfo = data._dimInfos[dim];
- // Currently, only dimensions that has ordinalMeta can create inverted indices.
- var ordinalMeta = dimInfo.ordinalMeta;
-+ var stack = dimInfo.stack;
- var store = data._store;
-- if (ordinalMeta) {
-- invertedIndices = invertedIndicesMap[dim] = new CtorInt32Array(ordinalMeta.categories.length);
-- // The default value of TypedArray is 0. To avoid miss
-- // mapping to 0, we should set it as INDEX_NOT_FOUND.
-- for (var i = 0; i < invertedIndices.length; i++) {
-- invertedIndices[i] = INDEX_NOT_FOUND;
-+ if (ordinalMeta || stack) {
-+ invertedIndices = invertedIndicesMap[dim] = stack ? new Array(store.count()) : new CtorInt32Array(ordinalMeta.categories.length);
-+ if (ordinalMeta) {
-+ // The default value of TypedArray is 0. To avoid miss
-+ // mapping to 0, we should set it as INDEX_NOT_FOUND.
-+ for (var i = 0; i < invertedIndices.length; i++) {
-+ invertedIndices[i] = INDEX_NOT_FOUND;
-+ }
- }
- for (var i = 0; i < store.count(); i++) {
- // Only support the case that all values are distinct.
-diff --git a/node_modules/echarts/lib/data/Source.js b/node_modules/echarts/lib/data/Source.js
-index 7dda49b..2dd2b98 100644
---- a/node_modules/echarts/lib/data/Source.js
-+++ b/node_modules/echarts/lib/data/Source.js
-@@ -252,7 +252,8 @@ function normalizeDimensionsOption(dimensionsDefine) {
- var item = {
- name: rawItem.name,
- displayName: rawItem.displayName,
-- type: rawItem.type
-+ type: rawItem.type,
-+ stack: rawItem.stack
- };
- // User can set null in dimensions.
- // We don't auto specify name, otherwise a given name may
-diff --git a/node_modules/echarts/lib/data/helper/createDimensions.js b/node_modules/echarts/lib/data/helper/createDimensions.js
-index 00d7eb7..dd514b1 100644
---- a/node_modules/echarts/lib/data/helper/createDimensions.js
-+++ b/node_modules/echarts/lib/data/helper/createDimensions.js
-@@ -110,6 +110,9 @@ source, opt) {
- }
- dimDefItem.type != null && (resultItem.type = dimDefItem.type);
- dimDefItem.displayName != null && (resultItem.displayName = dimDefItem.displayName);
-+ if (dimDefItem.stack) {
-+ resultItem.stack = true;
-+ }
- var newIdx = resultList.length;
- indicesMap[dimIdx] = newIdx;
- resultItem.storeDimIndex = dimIdx;
-diff --git a/node_modules/echarts/lib/data/helper/dataStackHelper.js b/node_modules/echarts/lib/data/helper/dataStackHelper.js
-index c25de1b..ea8300d 100644
---- a/node_modules/echarts/lib/data/helper/dataStackHelper.js
-+++ b/node_modules/echarts/lib/data/helper/dataStackHelper.js
-@@ -91,7 +91,7 @@ export function enableDataStack(seriesModel, dimensionsInput, opt) {
- }
- if (mayStack && !dimensionInfo.isExtraCoord) {
- // Find the first ordinal dimension as the stackedByDimInfo.
-- if (!byIndex && !stackedByDimInfo && dimensionInfo.ordinalMeta) {
-+ if (!byIndex && !stackedByDimInfo && (dimensionInfo.ordinalMeta || dimensionInfo.stack)) {
- stackedByDimInfo = dimensionInfo;
- }
- // Find the first stackable dimension as the stackedDimInfo.
-diff --git a/node_modules/echarts/lib/scale/Interval.js b/node_modules/echarts/lib/scale/Interval.js
-index 1094662..363c0a5 100644
---- a/node_modules/echarts/lib/scale/Interval.js
-+++ b/node_modules/echarts/lib/scale/Interval.js
-@@ -46,12 +46,17 @@ import * as numberUtil from '../util/number.js';
- import * as formatUtil from '../util/format.js';
- import Scale from './Scale.js';
- import * as helper from './helper.js';
-+import { isFunction } from 'zrender/lib/core/util.js';
- var roundNumber = numberUtil.round;
- var IntervalScale = /** @class */function (_super) {
- __extends(IntervalScale, _super);
-- function IntervalScale() {
-- var _this = _super !== null && _super.apply(this, arguments) || this;
-+ function IntervalScale(setting) {
-+ var _this = _super.call(this, setting) || this;
- _this.type = 'interval';
-+ var ticksGenerator = _this.getSetting('ticksGenerator');
-+ if (isFunction(ticksGenerator)) {
-+ _this._ticksGenerator = ticksGenerator;
-+ }
- // Step is calculated in adjustExtent.
- _this._interval = 0;
- _this._intervalPrecision = 2;
-@@ -104,7 +109,17 @@ var IntervalScale = /** @class */function (_super) {
- var extent = this._extent;
- var niceTickExtent = this._niceExtent;
- var intervalPrecision = this._intervalPrecision;
-- var ticks = [];
-+ var ticksGenerator = this._ticksGenerator;
-+ var ticks;
-+ if (ticksGenerator) {
-+ try {
-+ ticks = ticksGenerator(extent, interval, niceTickExtent, intervalPrecision);
-+ if (ticks) {
-+ return ticks;
-+ }
-+ } catch (_e) {}
-+ }
-+ ticks = [];
- // If interval is 0, return [];
- if (!interval) {
- return ticks;
-diff --git a/node_modules/echarts/types/dist/shared.d.ts b/node_modules/echarts/types/dist/shared.d.ts
-index ca74097..ef41ce2 100644
---- a/node_modules/echarts/types/dist/shared.d.ts
-+++ b/node_modules/echarts/types/dist/shared.d.ts
-@@ -2422,6 +2422,9 @@ interface AxisBaseOptionCommon extends ComponentOption, AnimationOptionMixin {
- max: number;
- }) => ScaleDataValue);
- }
-+
-+declare type NumericAxisTicksGenerator = (extent?: number[], interval?: number, niceTickExtent?: number[], intervalPrecision?: number) => {value: number}[];
-+
- interface NumericAxisBaseOptionCommon extends AxisBaseOptionCommon {
- boundaryGap?: [number | string, number | string];
- /**
-@@ -2447,6 +2450,8 @@ interface NumericAxisBaseOptionCommon extends AxisBaseOptionCommon {
- * Will be ignored if interval is set.
- */
- alignTicks?: boolean;
-+
-+ ticksGenerator?: NumericAxisTicksGenerator;
- }
- interface CategoryAxisBaseOption extends AxisBaseOptionCommon {
- type?: 'category';
-@@ -6412,6 +6417,7 @@ declare type DimensionDefinition = {
- type?: DataStoreDimensionType;
- name?: DimensionName;
- displayName?: string;
-+ stack?: boolean;
- };
- declare type DimensionDefinitionLoose = DimensionDefinition['name'] | DimensionDefinition;
- declare const SOURCE_FORMAT_ORIGINAL: "original";
-diff --git a/node_modules/echarts/types/src/coord/axisCommonTypes.d.ts b/node_modules/echarts/types/src/coord/axisCommonTypes.d.ts
-index c5c2792..d524b70 100644
---- a/node_modules/echarts/types/src/coord/axisCommonTypes.d.ts
-+++ b/node_modules/echarts/types/src/coord/axisCommonTypes.d.ts
-@@ -56,6 +56,9 @@ export interface AxisBaseOptionCommon extends ComponentOption, AnimationOptionMi
- max: number;
- }) => ScaleDataValue);
- }
-+
-+export declare type NumericAxisTicksGenerator = (extent?: number[], interval?: number, niceTickExtent?: number[], intervalPrecision?: number) => {value: number}[];
-+
- export interface NumericAxisBaseOptionCommon extends AxisBaseOptionCommon {
- boundaryGap?: [number | string, number | string];
- /**
-@@ -81,6 +84,8 @@ export interface NumericAxisBaseOptionCommon extends AxisBaseOptionCommon {
- * Will be ignored if interval is set.
- */
- alignTicks?: boolean;
-+
-+ ticksGenerator?: NumericAxisTicksGenerator;
- }
- export interface CategoryAxisBaseOption extends AxisBaseOptionCommon {
- type?: 'category';
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/chart/bar-chart-with-labels-widget.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/chart/bar-chart-with-labels-widget.component.ts
index da7f4d4e40..e2779f2821 100644
--- a/ui-ngx/src/app/modules/home/components/widget/lib/chart/bar-chart-with-labels-widget.component.ts
+++ b/ui-ngx/src/app/modules/home/components/widget/lib/chart/bar-chart-with-labels-widget.component.ts
@@ -54,7 +54,7 @@ import {
echartsModule,
EChartsOption,
EChartsSeriesItem,
- echartsTooltipFormatter,
+ echartsTooltipFormatter, timeAxisBandWidthCalculator,
toNamedData
} from '@home/components/widget/lib/chart/echarts-widget.models';
import { AggregationType, IntervalMath } from '@shared/models/time/time.models';
@@ -424,7 +424,8 @@ export class BarChartWithLabelsWidgetComponent implements OnInit, OnDestroy, Aft
onZero: false
},
min: this.ctx.defaultSubscription.timeWindow.minTime,
- max: this.ctx.defaultSubscription.timeWindow.maxTime
+ max: this.ctx.defaultSubscription.timeWindow.maxTime,
+ bandWidthCalculator: timeAxisBandWidthCalculator
},
yAxis: {
type: 'value',
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/chart/echarts-widget.models.ts b/ui-ngx/src/app/modules/home/components/widget/lib/chart/echarts-widget.models.ts
index 7fdd1fbfff..816f45a7e8 100644
--- a/ui-ngx/src/app/modules/home/components/widget/lib/chart/echarts-widget.models.ts
+++ b/ui-ngx/src/app/modules/home/components/widget/lib/chart/echarts-widget.models.ts
@@ -15,11 +15,9 @@
///
import * as echarts from 'echarts/core';
-import { Axis } from 'echarts';
import AxisModel from 'echarts/types/src/coord/cartesian/AxisModel';
import { estimateLabelUnionRect } from 'echarts/lib/coord/axisHelper';
import { formatValue, isDefinedAndNotNull } from '@core/utils';
-import TimeScale from 'echarts/types/src/scale/Time';
import {
DataZoomComponent,
DataZoomComponentOption,
@@ -51,7 +49,7 @@ import {
IntervalMath,
WidgetTimewindow
} from '@shared/models/time/time.models';
-import { CallbackDataParams } from 'echarts/types/dist/shared';
+import { CallbackDataParams, TimeAxisBandWidthCalculator } from 'echarts/types/dist/shared';
import { Renderer2 } from '@angular/core';
import { DateFormatProcessor, DateFormatSettings, Font } from '@shared/models/widget-settings.models';
import GlobalModel from 'echarts/types/src/model/Global';
@@ -63,53 +61,6 @@ class EChartsModule {
init() {
if (!this.initialized) {
- const axisGetBandWidth = Axis.prototype.getBandWidth;
-
- Axis.prototype.getBandWidth = function(){
- const model: AxisModel = this.model;
- const axisOption = model.option;
- if (this.scale.type === 'time') {
- let interval: number;
- const seriesDataIndices = axisOption.axisPointer?.seriesDataIndices;
- if (seriesDataIndices?.length) {
- const seriesDataIndex = seriesDataIndices[0];
- const series = model.ecModel.getSeriesByIndex(seriesDataIndex.seriesIndex);
- if (series) {
- const values = series.getData().getValues(seriesDataIndex.dataIndex);
- const start = values[2];
- const end = values[3];
- if (typeof start === 'number' && typeof end === 'number') {
- interval = Math.max(end - start, 1);
- }
- }
- }
- if (!interval) {
- const tbTimeWindow: WidgetTimewindow = (axisOption as any).tbTimeWindow;
- if (isDefinedAndNotNull(tbTimeWindow)) {
- if (axisOption.axisPointer?.value && typeof axisOption.axisPointer?.value === 'number') {
- const intervalArray = calculateAggIntervalWithWidgetTimeWindow(tbTimeWindow, axisOption.axisPointer.value);
- const start = intervalArray[0];
- const end = intervalArray[1];
- interval = Math.max(end - start, 1);
- } else {
- interval = IntervalMath.numberValue(tbTimeWindow.interval);
- }
- }
- }
- if (interval) {
- const timeScale: TimeScale = this.scale;
- const axisExtent: [number, number] = this._extent;
- const dataExtent = timeScale.getExtent();
- const size = Math.abs(axisExtent[1] - axisExtent[0]);
- return interval * (size / (dataExtent[1] - dataExtent[0]));
- } else {
- return axisGetBandWidth.call(this);
- }
- } else {
- return axisGetBandWidth.call(this);
- }
- };
-
echarts.use([
TooltipComponent,
GridComponent,
@@ -124,7 +75,6 @@ class EChartsModule {
CanvasRenderer,
SVGRenderer
]);
-
this.initialized = true;
}
}
@@ -160,6 +110,44 @@ export type EChartsSeriesItem = {
decimals?: number;
};
+export const timeAxisBandWidthCalculator: TimeAxisBandWidthCalculator = (model) => {
+ let interval: number;
+ const axisOption = model.option;
+ const seriesDataIndices = axisOption.axisPointer?.seriesDataIndices;
+ if (seriesDataIndices?.length) {
+ const seriesDataIndex = seriesDataIndices[0];
+ const series = model.ecModel.getSeriesByIndex(seriesDataIndex.seriesIndex);
+ if (series) {
+ const values = series.getData().getValues(seriesDataIndex.dataIndex);
+ const start = values[2];
+ const end = values[3];
+ if (typeof start === 'number' && typeof end === 'number') {
+ interval = Math.max(end - start, 1);
+ }
+ }
+ }
+ if (!interval) {
+ const tbTimeWindow: WidgetTimewindow = (axisOption as any).tbTimeWindow;
+ if (isDefinedAndNotNull(tbTimeWindow)) {
+ if (axisOption.axisPointer?.value && typeof axisOption.axisPointer?.value === 'number') {
+ const intervalArray = calculateAggIntervalWithWidgetTimeWindow(tbTimeWindow, axisOption.axisPointer.value);
+ const start = intervalArray[0];
+ const end = intervalArray[1];
+ interval = Math.max(end - start, 1);
+ } else {
+ interval = IntervalMath.numberValue(tbTimeWindow.interval);
+ }
+ }
+ }
+ if (interval) {
+ const timeScale = model.axis.scale;
+ const axisExtent = model.axis.getExtent();
+ const dataExtent = timeScale.getExtent();
+ const size = Math.abs(axisExtent[1] - axisExtent[0]);
+ return interval * (size / (dataExtent[1] - dataExtent[0]));
+ }
+};
+
export const getXAxis = (chart: ECharts): Axis2D => {
const model: GlobalModel = (chart as any).getModel();
const models = model.queryComponents({mainType: 'xAxis'});
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/chart/range-chart-widget.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/chart/range-chart-widget.component.ts
index 1705074a1e..1ef756f1f7 100644
--- a/ui-ngx/src/app/modules/home/components/widget/lib/chart/range-chart-widget.component.ts
+++ b/ui-ngx/src/app/modules/home/components/widget/lib/chart/range-chart-widget.component.ts
@@ -50,7 +50,7 @@ import {
ECharts,
echartsModule,
EChartsOption,
- echartsTooltipFormatter,
+ echartsTooltipFormatter, timeAxisBandWidthCalculator,
toNamedData
} from '@home/components/widget/lib/chart/echarts-widget.models';
import { CallbackDataParams } from 'echarts/types/dist/shared';
@@ -356,7 +356,8 @@ export class RangeChartWidgetComponent implements OnInit, OnDestroy, AfterViewIn
onZero: false
},
min: this.ctx.defaultSubscription.timeWindow.minTime,
- max: this.ctx.defaultSubscription.timeWindow.maxTime
+ max: this.ctx.defaultSubscription.timeWindow.maxTime,
+ bandWidthCalculator: timeAxisBandWidthCalculator
},
yAxis: {
type: 'value',
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/chart/time-series-chart.models.ts b/ui-ngx/src/app/modules/home/components/widget/lib/chart/time-series-chart.models.ts
index 6f985466c4..e931349bca 100644
--- a/ui-ngx/src/app/modules/home/components/widget/lib/chart/time-series-chart.models.ts
+++ b/ui-ngx/src/app/modules/home/components/widget/lib/chart/time-series-chart.models.ts
@@ -20,7 +20,7 @@ import {
EChartsSeriesItem,
EChartsTooltipTrigger,
EChartsTooltipWidgetSettings,
- measureThresholdLabelOffset
+ measureThresholdLabelOffset, timeAxisBandWidthCalculator
} from '@home/components/widget/lib/chart/echarts-widget.models';
import {
autoDateFormat,
@@ -969,7 +969,8 @@ export const createTimeSeriesXAxisOption = (settings: TimeSeriesChartXAxisSettin
}
},
min,
- max
+ max,
+ bandWidthCalculator: timeAxisBandWidthCalculator
};
};
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/chart/time-series-chart.ts b/ui-ngx/src/app/modules/home/components/widget/lib/chart/time-series-chart.ts
index 462825087e..bd9005c497 100644
--- a/ui-ngx/src/app/modules/home/components/widget/lib/chart/time-series-chart.ts
+++ b/ui-ngx/src/app/modules/home/components/widget/lib/chart/time-series-chart.ts
@@ -139,8 +139,9 @@ export class TbTimeSeriesChart {
this.settings = mergeDeep({} as TimeSeriesChartSettings,
timeSeriesChartDefaultSettings,
this.inputSettings as TimeSeriesChartSettings);
- const dashboardPageElement = this.ctx.$containerParent.parents('.tb-dashboard-page');
- this.darkMode = this.settings.darkMode || dashboardPageElement.hasClass('dark');
+ const $dashboardPageElement = this.ctx.$containerParent.parents('.tb-dashboard-page');
+ const dashboardPageElement = $dashboardPageElement.length ? $($dashboardPageElement[$dashboardPageElement.length-1]) : null;
+ this.darkMode = this.settings.darkMode || dashboardPageElement?.hasClass('dark');
this.setupYAxes();
this.setupData();
this.setupThresholds();
@@ -154,15 +155,17 @@ export class TbTimeSeriesChart {
});
this.shapeResize$.observe(this.chartElement);
}
- this.darkModeObserver = new MutationObserver(mutations => {
- for(let mutation of mutations) {
- if (mutation.type === 'attributes' && mutation.attributeName === 'class') {
- const darkMode = dashboardPageElement.hasClass('dark');
- this.setDarkMode(darkMode);
+ if (dashboardPageElement) {
+ this.darkModeObserver = new MutationObserver(mutations => {
+ for (const mutation of mutations) {
+ if (mutation.type === 'attributes' && mutation.attributeName === 'class') {
+ const darkMode = dashboardPageElement.hasClass('dark');
+ this.setDarkMode(darkMode);
+ }
}
- }
- });
- this.darkModeObserver.observe(dashboardPageElement[0], { attributes: true });
+ });
+ this.darkModeObserver.observe(dashboardPageElement[0], {attributes: true});
+ }
}
public update(): void {
@@ -269,7 +272,7 @@ export class TbTimeSeriesChart {
}
this.yMinSubject.complete();
this.yMaxSubject.complete();
- this.darkModeObserver.disconnect();
+ this.darkModeObserver?.disconnect();
}
public resize(): void {
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/device-gateway-command.component.scss b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/device-gateway-command.component.scss
index 3425065ca2..3f66b67943 100644
--- a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/device-gateway-command.component.scss
+++ b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/device-gateway-command.component.scss
@@ -63,7 +63,9 @@
height: 18px;
background: #305680;
mask-image: url(/assets/copy-code-icon.svg);
+ -webkit-mask-image: url(/assets/copy-code-icon.svg);
mask-repeat: no-repeat;
+ -webkit-mask-repeat: no-repeat;
}
}
}
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/indicator/battery-level-widget.component.scss b/ui-ngx/src/app/modules/home/components/widget/lib/indicator/battery-level-widget.component.scss
index 444417fb09..a85d7d694b 100644
--- a/ui-ngx/src/app/modules/home/components/widget/lib/indicator/battery-level-widget.component.scss
+++ b/ui-ngx/src/app/modules/home/components/widget/lib/indicator/battery-level-widget.component.scss
@@ -73,8 +73,11 @@
position: absolute;
inset: 0;
mask-repeat: no-repeat;
+ -webkit-mask-repeat: no-repeat;
mask-size: cover;
+ -webkit-mask-size: cover;
mask-position: center;
+ -webkit-mask-position: center;
}
.tb-battery-level-container {
position: absolute;
@@ -95,6 +98,7 @@
&.vertical {
.tb-battery-level-shape {
mask-image: url(/assets/widget/battery-level/battery-shape-vertical.svg);
+ -webkit-mask-image: url(/assets/widget/battery-level/battery-shape-vertical.svg);
}
.tb-battery-level-container {
flex-direction: column-reverse;
@@ -122,6 +126,7 @@
&.horizontal {
.tb-battery-level-shape {
mask-image: url(/assets/widget/battery-level/battery-shape-horizontal.svg);
+ -webkit-mask-image: url(/assets/widget/battery-level/battery-shape-horizontal.svg);
}
.tb-battery-level-container {
inset: 6.25% 8.85% 6.25% 3.54%;
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/rpc/power-button-widget.models.ts b/ui-ngx/src/app/modules/home/components/widget/lib/rpc/power-button-widget.models.ts
index 51a427d23b..656ba75fa1 100644
--- a/ui-ngx/src/app/modules/home/components/widget/lib/rpc/power-button-widget.models.ts
+++ b/ui-ngx/src/app/modules/home/components/widget/lib/rpc/power-button-widget.models.ts
@@ -444,7 +444,7 @@ class InnerShadowCircle {
add.x('-50%').y('-50%').width('200%').height('200%');
let effect: Effect = add.componentTransfer(components => {
components.funcA({ type: 'table', tableValues: '1 0' });
- }).in(add.$fill);
+ });
effect = effect.gaussianBlur(this.blur, this.blur).attr({stdDeviation: this.blur});
this.blurEffect = effect;
effect = effect.offset(this.dx, this.dy);
@@ -454,7 +454,7 @@ class InnerShadowCircle {
effect = effect.composite(this.offsetEffect, 'in');
effect.composite(add.$sourceAlpha, 'in');
add.merge(m => {
- m.mergeNode(add.$fill);
+ m.mergeNode();
m.mergeNode();
});
});
@@ -538,14 +538,14 @@ class DefaultPowerButtonShape extends PowerButtonShape {
this.pressedTimeline.finish();
const pressedScale = 0.75;
powerButtonAnimation(this.centerGroup).transform({scale: pressedScale});
- powerButtonAnimation(this.onLabelShape).transform({scale: pressedScale});
+ powerButtonAnimation(this.onLabelShape).transform({scale: pressedScale, origin: {x: cx, y: cy}});
this.pressedShadow.animate(6, 0.6);
}
protected onPressEnd() {
this.pressedTimeline.finish();
powerButtonAnimation(this.centerGroup).transform({scale: 1});
- powerButtonAnimation(this.onLabelShape).transform({scale: 1});
+ powerButtonAnimation(this.onLabelShape).transform({scale: 1, origin: {x: cx, y: cy}});
this.pressedShadow.animateRestore();
}
@@ -602,14 +602,14 @@ class SimplifiedPowerButtonShape extends PowerButtonShape {
this.pressedTimeline.finish();
const pressedScale = 0.75;
powerButtonAnimation(this.centerGroup).transform({scale: pressedScale});
- powerButtonAnimation(this.onLabelShape).transform({scale: pressedScale});
+ powerButtonAnimation(this.onLabelShape).transform({scale: pressedScale, origin: {x: cx, y: cy}});
this.pressedShadow.animate(6, 0.6);
}
protected onPressEnd() {
this.pressedTimeline.finish();
powerButtonAnimation(this.centerGroup).transform({scale: 1});
- powerButtonAnimation(this.onLabelShape).transform({scale: 1});
+ powerButtonAnimation(this.onLabelShape).transform({scale: 1, origin: {x: cx, y: cy}});
this.pressedShadow.animateRestore();
}
}
@@ -674,7 +674,7 @@ class OutlinedPowerButtonShape extends PowerButtonShape {
const pressedScale = 0.75;
powerButtonAnimation(this.centerGroup).transform({scale: pressedScale});
powerButtonAnimation(this.onCenterGroup).transform({scale: 0.98});
- powerButtonAnimation(this.onLabelShape).transform({scale: pressedScale / 0.98});
+ powerButtonAnimation(this.onLabelShape).transform({scale: pressedScale / 0.98, origin: {x: cx, y: cy}});
this.pressedShadow.animate(6, 0.6);
}
@@ -682,7 +682,7 @@ class OutlinedPowerButtonShape extends PowerButtonShape {
this.pressedTimeline.finish();
powerButtonAnimation(this.centerGroup).transform({scale: 1});
powerButtonAnimation(this.onCenterGroup).transform({scale: 1});
- powerButtonAnimation(this.onLabelShape).transform({scale: 1});
+ powerButtonAnimation(this.onLabelShape).transform({scale: 1, origin: {x: cx, y: cy}});
this.pressedShadow.animateRestore();
}
}
@@ -774,14 +774,14 @@ class DefaultVolumePowerButtonShape extends PowerButtonShape {
this.innerShadow.show();
const pressedScale = 0.75;
powerButtonAnimation(this.centerGroup).transform({scale: pressedScale});
- powerButtonAnimation(this.onLabelShape).transform({scale: pressedScale});
+ powerButtonAnimation(this.onLabelShape).transform({scale: pressedScale, origin: {x: cx, y: cy}});
this.innerShadow.animate(6, 0.6);
}
protected onPressEnd() {
this.pressedTimeline.finish();
powerButtonAnimation(this.centerGroup).transform({scale: 1});
- powerButtonAnimation(this.onLabelShape).transform({scale: 1});
+ powerButtonAnimation(this.onLabelShape).transform({scale: 1, origin: {x: cx, y: cy}});
this.innerShadow.animateRestore().after(() => {
if (this.disabled) {
this.innerShadow.hide();
@@ -849,14 +849,14 @@ class SimplifiedVolumePowerButtonShape extends PowerButtonShape {
this.backgroundShape.removeClass('tb-shadow');
}
powerButtonAnimation(this.centerGroup).transform({scale: pressedScale});
- powerButtonAnimation(this.onCenterGroup).transform({scale: pressedScale});
+ powerButtonAnimation(this.onCenterGroup).transform({scale: pressedScale, origin: {x: cx, y: cy}});
this.pressedShadow.animate(8, 0.4);
}
protected onPressEnd() {
this.pressedTimeline.finish();
powerButtonAnimation(this.centerGroup).transform({scale: 1});
- powerButtonAnimation(this.onCenterGroup).transform({scale: 1});
+ powerButtonAnimation(this.onCenterGroup).transform({scale: 1, origin: {x: cx, y: cy}});
this.pressedShadow.animateRestore().after(() => {
if (!this.value) {
this.backgroundShape.addClass('tb-shadow');
@@ -938,7 +938,7 @@ class OutlinedVolumePowerButtonShape extends PowerButtonShape {
const pressedScale = 0.75;
powerButtonAnimation(this.centerGroup).transform({scale: pressedScale});
powerButtonAnimation(this.onCenterGroup).transform({scale: 0.98});
- powerButtonAnimation(this.onLabelShape).transform({scale: pressedScale / 0.98});
+ powerButtonAnimation(this.onLabelShape).transform({scale: pressedScale / 0.98, origin: {x: cx, y: cy}});
this.pressedShadow.animate(6, 0.6);
}
@@ -946,7 +946,7 @@ class OutlinedVolumePowerButtonShape extends PowerButtonShape {
this.pressedTimeline.finish();
powerButtonAnimation(this.centerGroup).transform({scale: 1});
powerButtonAnimation(this.onCenterGroup).transform({scale: 1});
- powerButtonAnimation(this.onLabelShape).transform({scale: 1});
+ powerButtonAnimation(this.onLabelShape).transform({scale: 1, origin: {x: cx, y: cy}});
this.pressedShadow.animateRestore();
}
diff --git a/ui-ngx/src/app/modules/home/pages/device/device-check-connectivity-dialog.component.scss b/ui-ngx/src/app/modules/home/pages/device/device-check-connectivity-dialog.component.scss
index f7ed839541..ef5a1c0ff4 100644
--- a/ui-ngx/src/app/modules/home/pages/device/device-check-connectivity-dialog.component.scss
+++ b/ui-ngx/src/app/modules/home/pages/device/device-check-connectivity-dialog.component.scss
@@ -155,7 +155,9 @@
height: 18px;
background: #305680;
mask-image: url(/assets/copy-code-icon.svg);
+ -webkit-mask-image: url(/assets/copy-code-icon.svg);
mask-repeat: no-repeat;
+ -webkit-mask-repeat: no-repeat;
}
}
}
diff --git a/ui-ngx/src/app/modules/home/pages/edge/edge-instructions-dialog.component.scss b/ui-ngx/src/app/modules/home/pages/edge/edge-instructions-dialog.component.scss
index 4ff80e2c21..b28b28863e 100644
--- a/ui-ngx/src/app/modules/home/pages/edge/edge-instructions-dialog.component.scss
+++ b/ui-ngx/src/app/modules/home/pages/edge/edge-instructions-dialog.component.scss
@@ -92,7 +92,9 @@
height: 18px;
background: $tb-primary-color;
mask-image: url(/assets/copy-code-icon.svg);
+ -webkit-mask-image: url(/assets/copy-code-icon.svg);
mask-repeat: no-repeat;
+ -webkit-mask-repeat: no-repeat;
}
}
&.multiline {
diff --git a/ui-ngx/src/app/shared/components/image/multiple-gallery-image-input.component.html b/ui-ngx/src/app/shared/components/image/multiple-gallery-image-input.component.html
index 4a60b29ba9..ea6a4cc603 100644
--- a/ui-ngx/src/app/shared/components/image/multiple-gallery-image-input.component.html
+++ b/ui-ngx/src/app/shared/components/image/multiple-gallery-image-input.component.html
@@ -85,12 +85,11 @@