Commit 0bdf246383e35eef8270555398515785eb38668c

Authored by Igor Kulikov
1 parent 7cd8b2b3

Fixed bug with dashboard editing. Add IE support.

... ... @@ -20,7 +20,7 @@ export default class DataAggregator {
20 20 this.onDataCb = onDataCb;
21 21 this.tsKeyNames = tsKeyNames;
22 22 this.dataBuffer = {};
23   - for (var k in tsKeyNames) {
  23 + for (var k = 0; k < tsKeyNames.length; k++) {
24 24 this.dataBuffer[tsKeyNames[k]] = [];
25 25 }
26 26 this.startTs = startTs;
... ... @@ -143,7 +143,7 @@ export default class DataAggregator {
143 143 }
144 144
145 145 updateData() {
146   - for (var k in this.tsKeyNames) {
  146 + for (var k = 0; k < this.tsKeyNames.length; k++) {
147 147 this.dataBuffer[this.tsKeyNames[k]] = [];
148 148 }
149 149 for (var key in this.aggregationMap) {
... ... @@ -193,7 +193,7 @@ function processAggregatedData(data, isCount, noAggregation) {
193 193 aggregationMap[key] = aggKeyData;
194 194 }
195 195 var keyData = data[key];
196   - for (var i in keyData) {
  196 + for (var i = 0; i < keyData.length; i++) {
197 197 var kvPair = keyData[i];
198 198 var timestamp = kvPair[0];
199 199 var value = convertValue(kvPair[1], noAggregation);
... ... @@ -217,7 +217,7 @@ function updateAggregatedData(aggregationMap, isCount, noAggregation, aggFunctio
217 217 aggregationMap[key] = aggKeyData;
218 218 }
219 219 var keyData = data[key];
220   - for (var i in keyData) {
  220 + for (var i = 0; i < keyData.length; i++) {
221 221 var kvPair = keyData[i];
222 222 var timestamp = kvPair[0];
223 223 var value = convertValue(kvPair[1], noAggregation);
... ...
... ... @@ -44,7 +44,7 @@ function DatasourceService($timeout, $filter, $log, telemetryWebsocketService, t
44 44 }
45 45
46 46 var subscriptionDataKeys = [];
47   - for (var d in datasource.dataKeys) {
  47 + for (var d = 0; d < datasource.dataKeys.length; d++) {
48 48 var dataKey = datasource.dataKeys[d];
49 49 var subscriptionDataKey = {
50 50 name: dataKey.name,
... ... @@ -295,7 +295,7 @@ function DatasourceSubscription(datasourceSubscription, telemetryWebsocketServic
295 295 }
296 296 subscriber.onReconnected = function() {
297 297 var newSubsTw = null;
298   - for (var i2 in listeners) {
  298 + for (var i2 = 0; i2 < listeners.length; i2++) {
299 299 var listener = listeners[i2];
300 300 if (!newSubsTw) {
301 301 newSubsTw = listener.updateRealtimeSubscription();
... ... @@ -454,7 +454,7 @@ function DatasourceSubscription(datasourceSubscription, telemetryWebsocketServic
454 454 var value = dataKey.func(time, prevSeries[1]);
455 455 series.push(value);
456 456 datasourceData[dataKey.key].data = [series];
457   - for (var i in listeners) {
  457 + for (var i = 0; i < listeners.length; i++) {
458 458 var listener = listeners[i];
459 459 listener.dataUpdated(datasourceData[dataKey.key],
460 460 listener.datasourceIndex,
... ... @@ -566,7 +566,7 @@ function DatasourceSubscription(datasourceSubscription, telemetryWebsocketServic
566 566 }
567 567 if (datasourceSubscription.type === types.widgetType.timeseries.value) {
568 568 var series, time, value;
569   - for (var i in keyData) {
  569 + for (var i = 0; i < keyData.length; i++) {
570 570 series = keyData[i];
571 571 time = series[0];
572 572 value = convertValue(series[1]);
... ... @@ -593,7 +593,7 @@ function DatasourceSubscription(datasourceSubscription, telemetryWebsocketServic
593 593 }
594 594 if (update) {
595 595 datasourceData[datasourceKey].data = data;
596   - for (var i2 in listeners) {
  596 + for (var i2 = 0; i2 < listeners.length; i2++) {
597 597 var listener = listeners[i2];
598 598 if (angular.isFunction(listener))
599 599 continue;
... ...
... ... @@ -160,7 +160,7 @@ function DeviceService($http, $q, $filter, userService, telemetryWebsocketServic
160 160
161 161 function devicesToDevicesInfo(devices) {
162 162 var devicesInfo = [];
163   - for (var d in devices) {
  163 + for (var d = 0; d < devices.length; d++) {
164 164 devicesInfo.push(deviceToDeviceInfo(devices[d]));
165 165 }
166 166 return devicesInfo;
... ... @@ -376,7 +376,7 @@ function DeviceService($http, $q, $filter, userService, telemetryWebsocketServic
376 376 if (query) {
377 377 var dataKeys = response.data;
378 378 var lowercaseQuery = angular.lowercase(query);
379   - for (var i in dataKeys) {
  379 + for (var i=0; i<dataKeys.length;i++) {
380 380 if (angular.lowercase(dataKeys[i]).indexOf(lowercaseQuery) === 0) {
381 381 result.push(dataKeys[i]);
382 382 }
... ... @@ -526,7 +526,7 @@ function DeviceService($http, $q, $filter, userService, telemetryWebsocketServic
526 526 function saveDeviceAttributes(deviceId, attributeScope, attributes) {
527 527 var deferred = $q.defer();
528 528 var attributesData = {};
529   - for (var a in attributes) {
  529 + for (var a=0; a<attributes.length;a++) {
530 530 attributesData[attributes[a].key] = attributes[a].value;
531 531 }
532 532 var url = '/api/plugins/telemetry/' + deviceId + '/' + attributeScope;
... ...
... ... @@ -94,7 +94,7 @@ function TelemetryWebsocketService($rootScope, $websocket, $timeout, $window, ty
94 94 }
95 95 if (isReconnect) {
96 96 isReconnect = false;
97   - for (var r in reconnectSubscribers) {
  97 + for (var r=0; r<reconnectSubscribers.length;r++) {
98 98 var reconnectSubscriber = reconnectSubscribers[r];
99 99 if (reconnectSubscriber.onReconnected) {
100 100 reconnectSubscriber.onReconnected();
... ... @@ -136,7 +136,7 @@ function TelemetryWebsocketService($rootScope, $websocket, $timeout, $window, ty
136 136 if (!data.data) {
137 137 data.data = {};
138 138 }
139   - for (var k in keys) {
  139 + for (var k = 0; k < keys.length; k++) {
140 140 var key = keys[k];
141 141 if (!data.data[key]) {
142 142 data.data[key] = [];
... ...
... ... @@ -157,18 +157,14 @@ function UserService($http, $q, $rootScope, adminService, dashboardService, toas
157 157 }
158 158
159 159 function resolveRefreshTokenQueue(data) {
160   - for (var q in refreshTokenQueue) {
161   - if (isNaN(q))
162   - continue;
  160 + for (var q=0; q < refreshTokenQueue.length;q++) {
163 161 refreshTokenQueue[q].resolve(data);
164 162 }
165 163 refreshTokenQueue = [];
166 164 }
167 165
168 166 function rejectRefreshTokenQueue(message) {
169   - for (var q in refreshTokenQueue) {
170   - if (isNaN(q))
171   - continue;
  167 + for (var q=0;q<refreshTokenQueue.length;q++) {
172 168 refreshTokenQueue[q].reject(message);
173 169 }
174 170 refreshTokenQueue = [];
... ... @@ -246,7 +242,7 @@ function UserService($http, $q, $rootScope, adminService, dashboardService, toas
246 242 dashboardService.getCustomerDashboards(currentUser.customerId, pageLink).then(
247 243 function success(result) {
248 244 var dashboards = result.data;
249   - for (var d in dashboards) {
  245 + for (var d=0;d<dashboards.length;d++) {
250 246 allowedDashboardIds.push(dashboards[d].id.id);
251 247 }
252 248 deferred.resolve();
... ...
... ... @@ -13,6 +13,8 @@
13 13 * See the License for the specific language governing permissions and
14 14 * limitations under the License.
15 15 */
  16 +
  17 +import './ie.support';
16 18 import angular from 'angular';
17 19 import ngMaterial from 'angular-material';
18 20 import ngMdIcons from 'angular-material-icons';
... ...
... ... @@ -24,7 +24,6 @@
24 24 <div ng-class="vm.dashboardClass" id="gridster-background" style="height: auto; min-height: 100%;">
25 25 <div id="gridster-child" gridster="vm.gridsterOpts">
26 26 <ul>
27   - <!-- ng-click="widgetClicked($event, widget)" -->
28 27 <li gridster-item="vm.widgetItemMap" class="tb-noselect" ng-repeat="widget in vm.widgets">
29 28 <md-menu md-position-mode="target target" tb-mousepoint-menu>
30 29 <div tb-expand-fullscreen
... ...
... ... @@ -76,7 +76,7 @@ function DetailsSidenav($timeout) {
76 76 detailsButtons: '?detailsButtons'
77 77 },
78 78 scope: {
79   - headerTitle: '=',
  79 + headerTitle: '@',
80 80 headerSubtitle: '@',
81 81 headerHeightPx: '@',
82 82 isReadOnly: '=',
... ...
... ... @@ -61,7 +61,7 @@
61 61 </md-virtual-repeat-container>
62 62 </div>
63 63 <tb-details-sidenav
64   - header-title="vm.getItemTitleFunc(vm.operatingItem())"
  64 + header-title="{{vm.getItemTitleFunc(vm.operatingItem())}}"
65 65 header-subtitle="{{vm.itemDetailsText()}}"
66 66 is-read-only="vm.isDetailsReadOnly(vm.operatingItem())"
67 67 is-open="vm.detailsConfig.isDetailsOpen"
... ...
... ... @@ -341,9 +341,9 @@ export default function WidgetController($scope, $timeout, $window, $element, $q
341 341 $scope.legendConfig.showTotal === true);
342 342
343 343 if (widget.type !== types.widgetType.rpc.value && widget.type !== types.widgetType.static.value) {
344   - for (var i in widgetContext.datasources) {
  344 + for (var i = 0; i < widgetContext.datasources.length; i++) {
345 345 var datasource = widgetContext.datasources[i];
346   - for (var a in datasource.dataKeys) {
  346 + for (var a = 0; a < datasource.dataKeys.length; a++) {
347 347 var dataKey = datasource.dataKeys[a];
348 348 dataKey.pattern = angular.copy(dataKey.label);
349 349 var datasourceData = {
... ... @@ -723,7 +723,7 @@ export default function WidgetController($scope, $timeout, $window, $element, $q
723 723 function checkSubscriptions() {
724 724 if (widget.type !== types.widgetType.rpc.value) {
725 725 var subscriptionsChanged = false;
726   - for (var i in datasourceListeners) {
  726 + for (var i = 0; i < datasourceListeners.length; i++) {
727 727 var listener = datasourceListeners[i];
728 728 var deviceId = null;
729 729 var aliasName = null;
... ... @@ -748,7 +748,7 @@ export default function WidgetController($scope, $timeout, $window, $element, $q
748 748
749 749 function unsubscribe() {
750 750 if (widget.type !== types.widgetType.rpc.value) {
751   - for (var i in datasourceListeners) {
  751 + for (var i = 0; i < datasourceListeners.length; i++) {
752 752 var listener = datasourceListeners[i];
753 753 datasourceService.unsubscribeFromDatasource(listener);
754 754 }
... ... @@ -805,7 +805,7 @@ export default function WidgetController($scope, $timeout, $window, $element, $q
805 805 }
806 806 }
807 807 var index = 0;
808   - for (var i in widgetContext.datasources) {
  808 + for (var i = 0; i < widgetContext.datasources.length; i++) {
809 809 var datasource = widgetContext.datasources[i];
810 810 if (angular.isFunction(datasource))
811 811 continue;
... ...
... ... @@ -153,7 +153,7 @@
153 153 </tb-dashboard>
154 154 </div>
155 155 <tb-details-sidenav class="tb-widget-details-sidenav"
156   - header-title="vm.editingWidget.config.title"
  156 + header-title="{{vm.editingWidget.config.title}}"
157 157 header-subtitle="{{vm.editingWidgetSubtitle}}"
158 158 is-read-only="false"
159 159 is-open="vm.isEditingWidget"
... ... @@ -175,7 +175,7 @@
175 175 </form>
176 176 </tb-details-sidenav>
177 177 <tb-details-sidenav ng-if="!vm.widgetEditMode" class="tb-select-widget-sidenav"
178   - header-title="'dashboard.select-widget-title' | translate"
  178 + header-title="{{'dashboard.select-widget-title' | translate}}"
179 179 header-height-px="120"
180 180 is-read-only="true"
181 181 is-open="vm.isAddingWidget"
... ... @@ -249,7 +249,6 @@
249 249 class="md-headline tb-absolute-fill">widget.select-widgets-bundle</span>
250 250 </div>
251 251 </tb-details-sidenav>
252   - <!-- </section> -->
253 252 <section layout="row" layout-wrap class="tb-footer-buttons md-fab" layout-align="start end">
254 253 <md-fab-speed-dial ng-disabled="loading" ng-show="!vm.isAddingWidget && vm.isEdit && !vm.widgetEditMode"
255 254 md-open="vm.addItemActionsOpen" class="md-scale" md-direction="up">
... ...
... ... @@ -275,7 +275,7 @@ export default function AttributeTableDirective($compile, $templateCache, $rootS
275 275 dataKeys: []
276 276 }
277 277 var i = 0;
278   - for (var attr in scope.selectedAttributes) {
  278 + for (var attr =0; attr < scope.selectedAttributes.length;attr++) {
279 279 var attribute = scope.selectedAttributes[attr];
280 280 var dataKey = {
281 281 name: attribute.key,
... ...
  1 +/*
  2 + * Copyright © 2016-2017 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +
  17 +(function () {
  18 + if (!String.prototype.startsWith) {
  19 + String.prototype.startsWith = function(searchString, position) {
  20 + position = position || 0;
  21 + return this.indexOf(searchString, position) === position;
  22 + };
  23 + }
  24 + if (!String.prototype.endsWith) {
  25 + String.prototype.endsWith = function (suffix) {
  26 + return this.indexOf(suffix, this.length - suffix.length) !== -1;
  27 + };
  28 + }
  29 +})();
\ No newline at end of file
... ...
... ... @@ -25,8 +25,8 @@
25 25 md-is-locked-open="vm.isLockSidenav"
26 26 layout="column">
27 27 <header class="tb-nav-header">
28   - <md-toolbar md-scroll-shrink class="tb-nav-header-toolbar">
29   - <div flex layout="row" layout-align="start center" class="md-toolbar-tools inset">
  28 + <md-toolbar class="tb-nav-header-toolbar">
  29 + <div flex layout="row" layout-align="start start" class="md-toolbar-tools inset">
30 30 <md-icon md-svg-src="{{vm.logoSvg}}" aria-label="logo" class="tb-logo-title"></md-icon>
31 31 </div>
32 32 </md-toolbar>
... ...
... ... @@ -33,7 +33,7 @@ export default class TbFlot {
33 33 this.chartType = chartType || 'line';
34 34
35 35 var colors = [];
36   - for (var i in ctx.data) {
  36 + for (var i = 0; i < ctx.data.length; i++) {
37 37 var series = ctx.data[i];
38 38 colors.push(series.dataKey.color);
39 39 var keySettings = series.dataKey.settings;
... ... @@ -61,7 +61,7 @@ export default class TbFlot {
61 61 }
62 62 ctx.tooltip = $('#flot-series-tooltip');
63 63 if (ctx.tooltip.length === 0) {
64   - ctx.tooltip = $("<div id=flot-series-tooltip' class='flot-mouse-value'></div>");
  64 + ctx.tooltip = $("<div id='flot-series-tooltip' class='flot-mouse-value'></div>");
65 65 ctx.tooltip.css({
66 66 fontSize: "12px",
67 67 fontFamily: "Roboto",
... ... @@ -85,7 +85,7 @@ export default class TbFlot {
85 85 divElement.css({
86 86 display: "flex",
87 87 alignItems: "center",
88   - justifyContent: "center"
  88 + justifyContent: "flex-start"
89 89 });
90 90 var lineSpan = $('<span></span>');
91 91 lineSpan.css({
... ... @@ -147,7 +147,7 @@ export default class TbFlot {
147 147 fontWeight: "700"
148 148 });
149 149 content += dateDiv.prop('outerHTML');
150   - for (var i in hoverInfo.seriesHover) {
  150 + for (var i = 0; i < hoverInfo.seriesHover.length; i++) {
151 151 var seriesHoverInfo = hoverInfo.seriesHover[i];
152 152 if (tbFlot.ctx.tooltipIndividual && seriesHoverInfo.index !== seriesIndex) {
153 153 continue;
... ... @@ -333,7 +333,7 @@ export default class TbFlot {
333 333 this.ctx.pieData = angular.copy(this.ctx.data);
334 334 this.ctx.pieRenderedData = [];
335 335 this.ctx.pieTargetData = [];
336   - for (i in this.ctx.data) {
  336 + for (i = 0; i < this.ctx.data.length; i++) {
337 337 this.ctx.pieTargetData[i] = (this.ctx.data[i].data && this.ctx.data[i].data[0])
338 338 ? this.ctx.data[i].data[0][1] : 0;
339 339 }
... ... @@ -929,7 +929,7 @@ export default class TbFlot {
929 929 }
930 930
931 931 pieDataRendered() {
932   - for (var i in this.ctx.pieTargetData) {
  932 + for (var i = 0; i < this.ctx.pieTargetData.length; i++) {
933 933 var value = this.ctx.pieTargetData[i] ? this.ctx.pieTargetData[i] : 0;
934 934 this.ctx.pieRenderedData[i] = value;
935 935 if (!this.ctx.pieData[i].data[0]) {
... ... @@ -943,7 +943,7 @@ export default class TbFlot {
943 943 if (start) {
944 944 this.finishPieDataAnimation();
945 945 this.ctx.pieAnimationStartTime = this.ctx.pieAnimationLastTime = Date.now();
946   - for (var i in this.ctx.data) {
  946 + for (var i = 0; i < this.ctx.data.length; i++) {
947 947 this.ctx.pieTargetData[i] = (this.ctx.data[i].data && this.ctx.data[i].data[0])
948 948 ? this.ctx.data[i].data[0][1] : 0;
949 949 }
... ... @@ -968,7 +968,7 @@ export default class TbFlot {
968 968 this.finishPieDataAnimation();
969 969 } else {
970 970 if (elapsed >= 40) {
971   - for (var i in this.ctx.pieTargetData) {
  971 + for (var i = 0; i < this.ctx.pieTargetData.length; i++) {
972 972 var prevValue = this.ctx.pieRenderedData[i];
973 973 var targetValue = this.ctx.pieTargetData[i];
974 974 var value = prevValue + (targetValue - prevValue) * progress;
... ...
... ... @@ -91,7 +91,7 @@ export default class TbGoogleMap {
91 91 function success() {
92 92 gmGlobals.gmApiKeys[tbMap.apiKey].loaded = true;
93 93 initGoogleMap();
94   - for (var p in gmGlobals.gmApiKeys[tbMap.apiKey].pendingInits) {
  94 + for (var p = 0; p < gmGlobals.gmApiKeys[tbMap.apiKey].pendingInits.length; p++) {
95 95 var pendingInit = gmGlobals.gmApiKeys[tbMap.apiKey].pendingInits[p];
96 96 pendingInit();
97 97 }
... ...
... ... @@ -364,7 +364,7 @@ export default class TbMapWidget {
364 364 var bounds = tbMap.map.createBounds();
365 365 tbMap.locations = [];
366 366 var dataMap = toLabelValueMap(data);
367   - for (var l in tbMap.locationsSettings) {
  367 + for (var l=0; l < tbMap.locationsSettings.length; l++) {
368 368 var locationSettings = tbMap.locationsSettings[l];
369 369 var latIndex = -1;
370 370 var lngIndex = -1;
... ... @@ -398,7 +398,7 @@ export default class TbMapWidget {
398 398 var locationsChanged = false;
399 399 var bounds = tbMap.map.createBounds();
400 400 var dataMap = toLabelValueMap(data);
401   - for (var p in tbMap.locations) {
  401 + for (var p = 0; p < tbMap.locations.length; p++) {
402 402 var location = tbMap.locations[p];
403 403 locationsChanged |= updateLocation(location, data, dataMap);
404 404 if (location.polyline) {
... ... @@ -421,11 +421,11 @@ export default class TbMapWidget {
421 421 }
422 422 }
423 423 var tooltips = this.map.getTooltips();
424   - for (var t in tooltips) {
  424 + for (var t=0; t < tooltips.length; t++) {
425 425 var tooltip = tooltips[t];
426 426 var text = tooltip.pattern;
427 427 var replaceInfo = tooltip.replaceInfo;
428   - for (var v in replaceInfo.variables) {
  428 + for (var v = 0; v < replaceInfo.variables.length; v++) {
429 429 var variableInfo = replaceInfo.variables[v];
430 430 var txtVal = '';
431 431 if (variableInfo.dataKeyIndex > -1) {
... ... @@ -451,11 +451,11 @@ export default class TbMapWidget {
451 451 this.map.invalidateSize();
452 452 if (this.locations && this.locations.size > 0) {
453 453 var bounds = this.map.createBounds();
454   - for (var m in this.markers) {
  454 + for (var m = 0; m < this.markers.length; m++) {
455 455 this.map.extendBoundsWithMarker(bounds, this.markers[m]);
456 456 }
457 457 if (this.polylines) {
458   - for (var p in this.polylines) {
  458 + for (var p = 0; p < this.polylines.length; p++) {
459 459 this.map.extendBounds(bounds, this.polylines[p]);
460 460 }
461 461 }
... ...
... ... @@ -343,7 +343,7 @@ export default function WidgetEditorController(widgetService, userService, types
343 343 }
344 344 };
345 345 }
346   - for (var i in config.datasources) {
  346 + for (var i = 0; i < config.datasources.length; i++) {
347 347 var datasource = config.datasources[i];
348 348 datasource.type = vm.widget.type;
349 349 if (vm.widget.type !== types.widgetType.timeseries.value && datasource.intervalSec) {
... ... @@ -455,7 +455,7 @@ export default function WidgetEditorController(widgetService, userService, types
455 455 }
456 456
457 457 function onDividerDrag() {
458   - for (var i in ace_editors) {
  458 + for (var i = 0; i < ace_editors.length; i++) {
459 459 var ace = ace_editors[i];
460 460 ace.resize();
461 461 ace.renderer.updateFull();
... ...