Commit c66b06b8f71f240d064d76019090c4c4d078ac1c

Authored by Igor Kulikov
1 parent 7378973a

Minor UI bug fixes and improvements.

@@ -295,9 +295,8 @@ function AlarmService($http, $q, $interval, $filter, $timeout, utils, types) { @@ -295,9 +295,8 @@ function AlarmService($http, $q, $interval, $filter, $timeout, utils, types) {
295 if (alarmSourceListener.lastUpdateTs) { 295 if (alarmSourceListener.lastUpdateTs) {
296 var interval = now - alarmSourceListener.lastUpdateTs; 296 var interval = now - alarmSourceListener.lastUpdateTs;
297 alarmSourceListener.alarmsQuery.startTime += interval; 297 alarmSourceListener.alarmsQuery.startTime += interval;
298 - } else {  
299 - alarmSourceListener.lastUpdateTs = now;  
300 } 298 }
  299 + alarmSourceListener.lastUpdateTs = now;
301 } 300 }
302 alarmSourceListener.alarmsUpdated(alarms, false); 301 alarmSourceListener.alarmsUpdated(alarms, false);
303 } 302 }
@@ -63,7 +63,7 @@ function DashboardService($rootScope, $http, $q, $location, customerService) { @@ -63,7 +63,7 @@ function DashboardService($rootScope, $http, $q, $location, customerService) {
63 return deferred.promise; 63 return deferred.promise;
64 } 64 }
65 65
66 - function getTenantDashboards(pageLink) { 66 + function getTenantDashboards(pageLink, applyCustomersInfo) {
67 var deferred = $q.defer(); 67 var deferred = $q.defer();
68 var url = '/api/tenant/dashboards?limit=' + pageLink.limit; 68 var url = '/api/tenant/dashboards?limit=' + pageLink.limit;
69 if (angular.isDefined(pageLink.textSearch)) { 69 if (angular.isDefined(pageLink.textSearch)) {
@@ -76,22 +76,26 @@ function DashboardService($rootScope, $http, $q, $location, customerService) { @@ -76,22 +76,26 @@ function DashboardService($rootScope, $http, $q, $location, customerService) {
76 url += '&textOffset=' + pageLink.textOffset; 76 url += '&textOffset=' + pageLink.textOffset;
77 } 77 }
78 $http.get(url, null).then(function success(response) { 78 $http.get(url, null).then(function success(response) {
79 - customerService.applyAssignedCustomersInfo(response.data.data).then(  
80 - function success(data) {  
81 - response.data.data = data;  
82 - deferred.resolve(response.data);  
83 - },  
84 - function fail() {  
85 - deferred.reject();  
86 - }  
87 - ); 79 + if (applyCustomersInfo) {
  80 + customerService.applyAssignedCustomersInfo(response.data.data).then(
  81 + function success(data) {
  82 + response.data.data = data;
  83 + deferred.resolve(response.data);
  84 + },
  85 + function fail() {
  86 + deferred.reject();
  87 + }
  88 + );
  89 + } else {
  90 + deferred.resolve(response.data);
  91 + }
88 }, function fail() { 92 }, function fail() {
89 deferred.reject(); 93 deferred.reject();
90 }); 94 });
91 return deferred.promise; 95 return deferred.promise;
92 } 96 }
93 97
94 - function getCustomerDashboards(customerId, pageLink) { 98 + function getCustomerDashboards(customerId, pageLink, applyCustomersInfo) {
95 var deferred = $q.defer(); 99 var deferred = $q.defer();
96 var url = '/api/customer/' + customerId + '/dashboards?limit=' + pageLink.limit; 100 var url = '/api/customer/' + customerId + '/dashboards?limit=' + pageLink.limit;
97 if (angular.isDefined(pageLink.textSearch)) { 101 if (angular.isDefined(pageLink.textSearch)) {
@@ -104,15 +108,19 @@ function DashboardService($rootScope, $http, $q, $location, customerService) { @@ -104,15 +108,19 @@ function DashboardService($rootScope, $http, $q, $location, customerService) {
104 url += '&textOffset=' + pageLink.textOffset; 108 url += '&textOffset=' + pageLink.textOffset;
105 } 109 }
106 $http.get(url, null).then(function success(response) { 110 $http.get(url, null).then(function success(response) {
107 - customerService.applyAssignedCustomerInfo(response.data.data, customerId).then(  
108 - function success(data) {  
109 - response.data.data = data;  
110 - deferred.resolve(response.data);  
111 - },  
112 - function fail() {  
113 - deferred.reject();  
114 - }  
115 - ); 111 + if (applyCustomersInfo) {
  112 + customerService.applyAssignedCustomerInfo(response.data.data, customerId).then(
  113 + function success(data) {
  114 + response.data.data = data;
  115 + deferred.resolve(response.data);
  116 + },
  117 + function fail() {
  118 + deferred.reject();
  119 + }
  120 + );
  121 + } else {
  122 + deferred.resolve(response.data);
  123 + }
116 }, function fail() { 124 }, function fail() {
117 deferred.reject(); 125 deferred.reject();
118 }); 126 });
@@ -267,9 +267,9 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device @@ -267,9 +267,9 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device
267 break; 267 break;
268 case types.entityType.dashboard: 268 case types.entityType.dashboard:
269 if (user.authority === 'CUSTOMER_USER') { 269 if (user.authority === 'CUSTOMER_USER') {
270 - promise = dashboardService.getCustomerDashboards(customerId, pageLink); 270 + promise = dashboardService.getCustomerDashboards(customerId, pageLink, false);
271 } else { 271 } else {
272 - promise = dashboardService.getTenantDashboards(pageLink); 272 + promise = dashboardService.getTenantDashboards(pageLink, false);
273 } 273 }
274 break; 274 break;
275 case types.entityType.user: 275 case types.entityType.user:
@@ -674,11 +674,14 @@ export default class Subscription { @@ -674,11 +674,14 @@ export default class Subscription {
674 674
675 alarmsUpdated(alarms, apply) { 675 alarmsUpdated(alarms, apply) {
676 this.notifyDataLoaded(); 676 this.notifyDataLoaded();
  677 + var updated = !angular.equals(this.alarms, alarms);
677 this.alarms = alarms; 678 this.alarms = alarms;
678 if (this.subscriptionTimewindow && this.subscriptionTimewindow.realtimeWindowMs) { 679 if (this.subscriptionTimewindow && this.subscriptionTimewindow.realtimeWindowMs) {
679 this.updateTimewindow(); 680 this.updateTimewindow();
680 } 681 }
681 - this.onDataUpdated(apply); 682 + if (updated) {
  683 + this.onDataUpdated(apply);
  684 + }
682 } 685 }
683 686
684 updateLegend(dataIndex, data, apply) { 687 updateLegend(dataIndex, data, apply) {
@@ -265,9 +265,9 @@ function UserService($http, $q, $rootScope, adminService, dashboardService, logi @@ -265,9 +265,9 @@ function UserService($http, $q, $rootScope, adminService, dashboardService, logi
265 var pageLink = {limit: 100}; 265 var pageLink = {limit: 100};
266 var fetchDashboardsPromise; 266 var fetchDashboardsPromise;
267 if (currentUser.authority === 'TENANT_ADMIN') { 267 if (currentUser.authority === 'TENANT_ADMIN') {
268 - fetchDashboardsPromise = dashboardService.getTenantDashboards(pageLink); 268 + fetchDashboardsPromise = dashboardService.getTenantDashboards(pageLink, false);
269 } else { 269 } else {
270 - fetchDashboardsPromise = dashboardService.getCustomerDashboards(currentUser.customerId, pageLink); 270 + fetchDashboardsPromise = dashboardService.getCustomerDashboards(currentUser.customerId, pageLink, false);
271 } 271 }
272 fetchDashboardsPromise.then( 272 fetchDashboardsPromise.then(
273 function success(result) { 273 function success(result) {
@@ -48,7 +48,7 @@ function DashboardAutocomplete($compile, $templateCache, $q, dashboardService, u @@ -48,7 +48,7 @@ function DashboardAutocomplete($compile, $templateCache, $q, dashboardService, u
48 var promise; 48 var promise;
49 if (scope.dashboardsScope === 'customer' || userService.getAuthority() === 'CUSTOMER_USER') { 49 if (scope.dashboardsScope === 'customer' || userService.getAuthority() === 'CUSTOMER_USER') {
50 if (scope.customerId) { 50 if (scope.customerId) {
51 - promise = dashboardService.getCustomerDashboards(scope.customerId, pageLink); 51 + promise = dashboardService.getCustomerDashboards(scope.customerId, pageLink, false);
52 } else { 52 } else {
53 promise = $q.when({data: []}); 53 promise = $q.when({data: []});
54 } 54 }
@@ -60,7 +60,7 @@ function DashboardAutocomplete($compile, $templateCache, $q, dashboardService, u @@ -60,7 +60,7 @@ function DashboardAutocomplete($compile, $templateCache, $q, dashboardService, u
60 promise = $q.when({data: []}); 60 promise = $q.when({data: []});
61 } 61 }
62 } else { 62 } else {
63 - promise = dashboardService.getTenantDashboards(pageLink); 63 + promise = dashboardService.getTenantDashboards(pageLink, false);
64 } 64 }
65 } 65 }
66 66
@@ -48,12 +48,12 @@ function DashboardSelect($compile, $templateCache, $q, $mdMedia, $mdPanel, $docu @@ -48,12 +48,12 @@ function DashboardSelect($compile, $templateCache, $q, $mdMedia, $mdPanel, $docu
48 var promise; 48 var promise;
49 if (scope.dashboardsScope === 'customer' || userService.getAuthority() === 'CUSTOMER_USER') { 49 if (scope.dashboardsScope === 'customer' || userService.getAuthority() === 'CUSTOMER_USER') {
50 if (scope.customerId && scope.customerId != types.id.nullUid) { 50 if (scope.customerId && scope.customerId != types.id.nullUid) {
51 - promise = dashboardService.getCustomerDashboards(scope.customerId, pageLink); 51 + promise = dashboardService.getCustomerDashboards(scope.customerId, pageLink, false);
52 } else { 52 } else {
53 promise = $q.when({data: []}); 53 promise = $q.when({data: []});
54 } 54 }
55 } else { 55 } else {
56 - promise = dashboardService.getTenantDashboards(pageLink); 56 + promise = dashboardService.getTenantDashboards(pageLink, false);
57 } 57 }
58 58
59 promise.then(function success(result) { 59 promise.then(function success(result) {
@@ -15,7 +15,6 @@ @@ -15,7 +15,6 @@
15 */ 15 */
16 import './dashboard.scss'; 16 import './dashboard.scss';
17 17
18 -import $ from 'jquery';  
19 import 'javascript-detect-element-resize/detect-element-resize'; 18 import 'javascript-detect-element-resize/detect-element-resize';
20 import angularGridster from 'angular-gridster'; 19 import angularGridster from 'angular-gridster';
21 import thingsboardTypes from '../common/types.constant'; 20 import thingsboardTypes from '../common/types.constant';
@@ -94,8 +93,8 @@ function DashboardController($scope, $rootScope, $element, $timeout, $mdMedia, $ @@ -94,8 +93,8 @@ function DashboardController($scope, $rootScope, $element, $timeout, $mdMedia, $
94 var highlightedWidget = null; 93 var highlightedWidget = null;
95 var selectedWidget = null; 94 var selectedWidget = null;
96 95
97 - var gridsterParent = $('#gridster-parent', $element);  
98 - var gridsterElement = angular.element($('#gridster-child', gridsterParent)); 96 + var gridsterParent = angular.element('#gridster-parent', $element);
  97 + var gridsterElement = angular.element('#gridster-child', gridsterParent);
99 98
100 var vm = this; 99 var vm = this;
101 100
@@ -228,15 +227,15 @@ function DashboardController($scope, $rootScope, $element, $timeout, $mdMedia, $ @@ -228,15 +227,15 @@ function DashboardController($scope, $rootScope, $element, $timeout, $mdMedia, $
228 } 227 }
229 }; 228 };
230 229
231 - addResizeListener(gridsterParent[0], onGirdsterParentResize); // eslint-disable-line no-undef 230 + addResizeListener(gridsterParent[0], onGridsterParentResize); // eslint-disable-line no-undef
232 231
233 $scope.$on("$destroy", function () { 232 $scope.$on("$destroy", function () {
234 - removeResizeListener(gridsterParent[0], onGirdsterParentResize); // eslint-disable-line no-undef 233 + removeResizeListener(gridsterParent[0], onGridsterParentResize); // eslint-disable-line no-undef
235 }); 234 });
236 235
237 watchWidgets(); 236 watchWidgets();
238 237
239 - function onGirdsterParentResize() { 238 + function onGridsterParentResize() {
240 if (gridsterParent.height() && autofillHeight()) { 239 if (gridsterParent.height() && autofillHeight()) {
241 updateMobileOpts(); 240 updateMobileOpts();
242 } 241 }
@@ -244,6 +243,10 @@ function DashboardController($scope, $rootScope, $element, $timeout, $mdMedia, $ @@ -244,6 +243,10 @@ function DashboardController($scope, $rootScope, $element, $timeout, $mdMedia, $
244 243
245 function watchWidgets() { 244 function watchWidgets() {
246 $scope.widgetsCollectionWatch = $scope.$watchCollection('vm.widgets', function () { 245 $scope.widgetsCollectionWatch = $scope.$watchCollection('vm.widgets', function () {
  246 + if (vm.skipInitialWidgetsWatch) {
  247 + $timeout(function() { vm.skipInitialWidgetsWatch = false; });
  248 + return;
  249 + }
247 var ids = []; 250 var ids = [];
248 for (var i=0;i<vm.widgets.length;i++) { 251 for (var i=0;i<vm.widgets.length;i++) {
249 var widget = vm.widgets[i]; 252 var widget = vm.widgets[i];
@@ -524,6 +527,7 @@ function DashboardController($scope, $rootScope, $element, $timeout, $mdMedia, $ @@ -524,6 +527,7 @@ function DashboardController($scope, $rootScope, $element, $timeout, $mdMedia, $
524 } 527 }
525 return res; 528 return res;
526 }); 529 });
  530 + vm.skipInitialWidgetsWatch = true;
527 watchWidgets(); 531 watchWidgets();
528 } 532 }
529 533
@@ -714,9 +718,9 @@ function DashboardController($scope, $rootScope, $element, $timeout, $mdMedia, $ @@ -714,9 +718,9 @@ function DashboardController($scope, $rootScope, $element, $timeout, $mdMedia, $
714 718
715 function scrollToWidget(widget, delay) { 719 function scrollToWidget(widget, delay) {
716 if (vm.gridster) { 720 if (vm.gridster) {
717 - var item = $('.gridster-item', vm.gridster.$element)[vm.widgets.indexOf(widget)]; 721 + var item = angular.element('.gridster-item', vm.gridster.$element)[vm.widgets.indexOf(widget)];
718 if (item) { 722 if (item) {
719 - var height = $(item).outerHeight(true); 723 + var height = angular.element(item).outerHeight(true);
720 var rectHeight = gridsterParent.height(); 724 var rectHeight = gridsterParent.height();
721 var offset = (rectHeight - height) / 2; 725 var offset = (rectHeight - height) / 2;
722 var scrollTop = item.offsetTop; 726 var scrollTop = item.offsetTop;
@@ -55,7 +55,7 @@ @@ -55,7 +55,7 @@
55 ng-show="!vm.isEdit" 55 ng-show="!vm.isEdit"
56 ng-click="action.onAction($event)" 56 ng-click="action.onAction($event)"
57 class="md-icon-button"> 57 class="md-icon-button">
58 - <md-tooltip md-direction="top"> 58 + <md-tooltip md-direction="{{vm.isWidgetExpanded ? 'bottom' : 'top'}}">
59 {{action.displayName}} 59 {{action.displayName}}
60 </md-tooltip> 60 </md-tooltip>
61 <ng-md-icon size="20" icon="{{action.icon}}"></ng-md-icon> 61 <ng-md-icon size="20" icon="{{action.icon}}"></ng-md-icon>
@@ -65,7 +65,7 @@ @@ -65,7 +65,7 @@
65 ng-show="!vm.isEdit && action.show" 65 ng-show="!vm.isEdit && action.show"
66 ng-click="action.onAction($event)" 66 ng-click="action.onAction($event)"
67 class="md-icon-button"> 67 class="md-icon-button">
68 - <md-tooltip md-direction="top"> 68 + <md-tooltip md-direction="{{vm.isWidgetExpanded ? 'bottom' : 'top'}}">
69 {{ action.name | translate }} 69 {{ action.name | translate }}
70 </md-tooltip> 70 </md-tooltip>
71 <ng-md-icon size="20" icon="{{action.icon}}"></ng-md-icon> 71 <ng-md-icon size="20" icon="{{action.icon}}"></ng-md-icon>
@@ -114,7 +114,8 @@ @@ -114,7 +114,8 @@
114 isEdit: vm.isEdit, 114 isEdit: vm.isEdit,
115 isMobile: vm.isMobileSize, 115 isMobile: vm.isMobileSize,
116 dashboardTimewindow: vm.dashboardTimewindow, 116 dashboardTimewindow: vm.dashboardTimewindow,
117 - dashboardTimewindowApi: vm.dashboardTimewindowApi }"> 117 + dashboardTimewindowApi: vm.dashboardTimewindowApi,
  118 + dashboard: vm }">
118 </div> 119 </div>
119 </div> 120 </div>
120 </div> 121 </div>
@@ -186,7 +186,7 @@ @@ -186,7 +186,7 @@
186 <div translate ng-message="entityKeys" ng-if="widgetType === types.widgetType.latest.value" class="tb-error-message">datakey.timeseries-or-attributes-required</div> 186 <div translate ng-message="entityKeys" ng-if="widgetType === types.widgetType.latest.value" class="tb-error-message">datakey.timeseries-or-attributes-required</div>
187 <div translate ng-message="entityKeys" ng-if="widgetType === types.widgetType.alarm.value" class="tb-error-message">datakey.alarm-fields-required</div> 187 <div translate ng-message="entityKeys" ng-if="widgetType === types.widgetType.alarm.value" class="tb-error-message">datakey.alarm-fields-required</div>
188 </div> 188 </div>
189 - <div class="md-caption" style="color: rgba(0,0,0,0.57);" ng-if="maxDataKeys != -1" 189 + <div class="md-caption" style="color: rgba(0,0,0,0.57);" ng-if="maxDataKeys > -1"
190 translate="datakey.maximum-timeseries-or-attributes" 190 translate="datakey.maximum-timeseries-or-attributes"
191 translate-values="{count: maxDataKeys}" 191 translate-values="{count: maxDataKeys}"
192 translate-interpolation="messageformat" 192 translate-interpolation="messageformat"
@@ -132,7 +132,7 @@ @@ -132,7 +132,7 @@
132 <div translate ng-message="datasourceKeys" ng-if="widgetType !== types.widgetType.alarm.value" class="tb-error-message">datakey.function-types-required</div> 132 <div translate ng-message="datasourceKeys" ng-if="widgetType !== types.widgetType.alarm.value" class="tb-error-message">datakey.function-types-required</div>
133 <div translate ng-message="datasourceKeys" ng-if="widgetType === types.widgetType.alarm.value" class="tb-error-message">datakey.alarm-fields-required</div> 133 <div translate ng-message="datasourceKeys" ng-if="widgetType === types.widgetType.alarm.value" class="tb-error-message">datakey.alarm-fields-required</div>
134 </div> 134 </div>
135 - <div class="md-caption" style="color: rgba(0,0,0,0.57);" ng-if="maxDataKeys != -1" 135 + <div class="md-caption" style="color: rgba(0,0,0,0.57);" ng-if="maxDataKeys > -1"
136 translate="datakey.maximum-function-types" 136 translate="datakey.maximum-function-types"
137 translate-values="{count: maxDataKeys}" 137 translate-values="{count: maxDataKeys}"
138 translate-interpolation="messageformat" 138 translate-interpolation="messageformat"
@@ -22,7 +22,7 @@ import Subscription from '../../api/subscription'; @@ -22,7 +22,7 @@ import Subscription from '../../api/subscription';
22 /*@ngInject*/ 22 /*@ngInject*/
23 export default function WidgetController($scope, $state, $timeout, $window, $element, $q, $log, $injector, $filter, $compile, tbRaf, types, utils, timeService, 23 export default function WidgetController($scope, $state, $timeout, $window, $element, $q, $log, $injector, $filter, $compile, tbRaf, types, utils, timeService,
24 datasourceService, alarmService, entityService, dashboardService, deviceService, visibleRect, isEdit, isMobile, dashboardTimewindow, 24 datasourceService, alarmService, entityService, dashboardService, deviceService, visibleRect, isEdit, isMobile, dashboardTimewindow,
25 - dashboardTimewindowApi, widget, aliasController, stateController, widgetInfo, widgetType) { 25 + dashboardTimewindowApi, dashboard, widget, aliasController, stateController, widgetInfo, widgetType) {
26 26
27 var vm = this; 27 var vm = this;
28 28
@@ -67,6 +67,7 @@ export default function WidgetController($scope, $state, $timeout, $window, $ele @@ -67,6 +67,7 @@ export default function WidgetController($scope, $state, $timeout, $window, $ele
67 hideTitlePanel: false, 67 hideTitlePanel: false,
68 isEdit: isEdit, 68 isEdit: isEdit,
69 isMobile: isMobile, 69 isMobile: isMobile,
  70 + dashboard: dashboard,
70 widgetConfig: widget.config, 71 widgetConfig: widget.config,
71 settings: widget.config.settings, 72 settings: widget.config.settings,
72 units: widget.config.units || '', 73 units: widget.config.units || '',
@@ -52,7 +52,7 @@ export default function AddDashboardsToCustomerController(dashboardService, $mdD @@ -52,7 +52,7 @@ export default function AddDashboardsToCustomerController(dashboardService, $mdD
52 fetchMoreItems_: function () { 52 fetchMoreItems_: function () {
53 if (vm.dashboards.hasNext && !vm.dashboards.pending) { 53 if (vm.dashboards.hasNext && !vm.dashboards.pending) {
54 vm.dashboards.pending = true; 54 vm.dashboards.pending = true;
55 - dashboardService.getTenantDashboards(vm.dashboards.nextPageLink).then( 55 + dashboardService.getTenantDashboards(vm.dashboards.nextPageLink, false).then(
56 function success(dashboards) { 56 function success(dashboards) {
57 vm.dashboards.data = vm.dashboards.data.concat(dashboards.data); 57 vm.dashboards.data = vm.dashboards.data.concat(dashboards.data);
58 vm.dashboards.nextPageLink = dashboards.nextPageLink; 58 vm.dashboards.nextPageLink = dashboards.nextPageLink;
@@ -15,7 +15,7 @@ @@ -15,7 +15,7 @@
15 limitations under the License. 15 limitations under the License.
16 16
17 --> 17 -->
18 -<md-content flex tb-expand-fullscreen="vm.widgetEditMode || vm.iframeMode || forceFullscreen" expand-button-id="dashboard-expand-button" 18 +<md-content style="padding-top: 150px;" flex tb-expand-fullscreen="vm.widgetEditMode || vm.iframeMode || forceFullscreen" expand-button-id="dashboard-expand-button"
19 hide-expand-button="vm.widgetEditMode || vm.iframeMode || forceFullscreen" expand-tooltip-direction="bottom" ng-if="vm.dashboard"> 19 hide-expand-button="vm.widgetEditMode || vm.iframeMode || forceFullscreen" expand-tooltip-direction="bottom" ng-if="vm.dashboard">
20 <section class="tb-dashboard-toolbar" ng-show="vm.showDashboardToolbar()" 20 <section class="tb-dashboard-toolbar" ng-show="vm.showDashboardToolbar()"
21 ng-class="{ 'tb-dashboard-toolbar-opened': vm.toolbarOpened, 'tb-dashboard-toolbar-closed': !vm.toolbarOpened }"> 21 ng-class="{ 'tb-dashboard-toolbar-opened': vm.toolbarOpened, 'tb-dashboard-toolbar-closed': !vm.toolbarOpened }">
@@ -167,7 +167,7 @@ export function DashboardsController(userService, dashboardService, customerServ @@ -167,7 +167,7 @@ export function DashboardsController(userService, dashboardService, customerServ
167 167
168 if (vm.dashboardsScope === 'tenant') { 168 if (vm.dashboardsScope === 'tenant') {
169 fetchDashboardsFunction = function (pageLink) { 169 fetchDashboardsFunction = function (pageLink) {
170 - return dashboardService.getTenantDashboards(pageLink); 170 + return dashboardService.getTenantDashboards(pageLink, true);
171 }; 171 };
172 deleteDashboardFunction = function (dashboardId) { 172 deleteDashboardFunction = function (dashboardId) {
173 return dashboardService.deleteDashboard(dashboardId); 173 return dashboardService.deleteDashboard(dashboardId);
@@ -290,7 +290,7 @@ export function DashboardsController(userService, dashboardService, customerServ @@ -290,7 +290,7 @@ export function DashboardsController(userService, dashboardService, customerServ
290 }); 290 });
291 } else if (vm.dashboardsScope === 'customer' || vm.dashboardsScope === 'customer_user') { 291 } else if (vm.dashboardsScope === 'customer' || vm.dashboardsScope === 'customer_user') {
292 fetchDashboardsFunction = function (pageLink) { 292 fetchDashboardsFunction = function (pageLink) {
293 - return dashboardService.getCustomerDashboards(customerId, pageLink); 293 + return dashboardService.getCustomerDashboards(customerId, pageLink, true);
294 }; 294 };
295 deleteDashboardFunction = function (dashboardId) { 295 deleteDashboardFunction = function (dashboardId) {
296 return dashboardService.unassignDashboardFromCustomer(dashboardId); 296 return dashboardService.unassignDashboardFromCustomer(dashboardId);
@@ -468,7 +468,7 @@ export function DashboardsController(userService, dashboardService, customerServ @@ -468,7 +468,7 @@ export function DashboardsController(userService, dashboardService, customerServ
468 $event.stopPropagation(); 468 $event.stopPropagation();
469 } 469 }
470 var pageSize = 10; 470 var pageSize = 10;
471 - dashboardService.getTenantDashboards({limit: pageSize, textSearch: ''}).then( 471 + dashboardService.getTenantDashboards({limit: pageSize, textSearch: ''}, false).then(
472 function success(_dashboards) { 472 function success(_dashboards) {
473 var dashboards = { 473 var dashboards = {
474 pageSize: pageSize, 474 pageSize: pageSize,
@@ -22,18 +22,22 @@ export default function BreadcrumbLabel($translate) { @@ -22,18 +22,22 @@ export default function BreadcrumbLabel($translate) {
22 var labelObj; 22 var labelObj;
23 labelObj = angular.fromJson(bLabel); 23 labelObj = angular.fromJson(bLabel);
24 if (labelObj) { 24 if (labelObj) {
  25 + var translate = !(labelObj.translate && labelObj.translate === 'false');
  26 + var key = translate ? $translate.use() : 'orig';
25 if (!labels[labelObj.label]) { 27 if (!labels[labelObj.label]) {
26 - labels[labelObj.label] = labelObj.label;  
27 - var translate = !(labelObj.translate && labelObj.translate === 'false'); 28 + labels[labelObj.label] = {};
  29 + }
  30 + if (!labels[labelObj.label][key]) {
  31 + labels[labelObj.label][key] = labelObj.label;
28 if (translate) { 32 if (translate) {
29 $translate([labelObj.label]).then( 33 $translate([labelObj.label]).then(
30 function (translations) { 34 function (translations) {
31 - labels[labelObj.label] = translations[labelObj.label]; 35 + labels[labelObj.label][key] = translations[labelObj.label];
32 } 36 }
33 ) 37 )
34 } 38 }
35 } 39 }
36 - return labels[labelObj.label]; 40 + return labels[labelObj.label][key];
37 } else { 41 } else {
38 return ''; 42 return '';
39 } 43 }
@@ -22,7 +22,7 @@ @@ -22,7 +22,7 @@
22 <div class="md-toolbar-tools"> 22 <div class="md-toolbar-tools">
23 <md-button class="md-icon-button" aria-label="{{ 'action.search' | translate }}"> 23 <md-button class="md-icon-button" aria-label="{{ 'action.search' | translate }}">
24 <md-icon aria-label="{{ 'action.search' | translate }}" class="material-icons">search</md-icon> 24 <md-icon aria-label="{{ 'action.search' | translate }}" class="material-icons">search</md-icon>
25 - <md-tooltip md-direction="top"> 25 + <md-tooltip md-direction="{{vm.ctx.dashboard.isWidgetExpanded ? 'bottom' : 'top'}}">
26 {{'alarm.search' | translate}} 26 {{'alarm.search' | translate}}
27 </md-tooltip> 27 </md-tooltip>
28 </md-button> 28 </md-button>
@@ -32,7 +32,7 @@ @@ -32,7 +32,7 @@
32 </md-input-container> 32 </md-input-container>
33 <md-button class="md-icon-button" aria-label="Close" ng-click="vm.exitFilterMode()"> 33 <md-button class="md-icon-button" aria-label="Close" ng-click="vm.exitFilterMode()">
34 <md-icon aria-label="Close" class="material-icons">close</md-icon> 34 <md-icon aria-label="Close" class="material-icons">close</md-icon>
35 - <md-tooltip md-direction="top"> 35 + <md-tooltip md-direction="{{vm.ctx.dashboard.isWidgetExpanded ? 'bottom' : 'top'}}">
36 {{ 'action.close' | translate }} 36 {{ 'action.close' | translate }}
37 </md-tooltip> 37 </md-tooltip>
38 </md-button> 38 </md-button>
@@ -46,13 +46,13 @@ @@ -46,13 +46,13 @@
46 <span flex></span> 46 <span flex></span>
47 <md-button ng-if="vm.allowAcknowledgment" class="md-icon-button" ng-click="vm.ackAlarms($event)"> 47 <md-button ng-if="vm.allowAcknowledgment" class="md-icon-button" ng-click="vm.ackAlarms($event)">
48 <md-icon>done</md-icon> 48 <md-icon>done</md-icon>
49 - <md-tooltip md-direction="top"> 49 + <md-tooltip md-direction="{{vm.ctx.dashboard.isWidgetExpanded ? 'bottom' : 'top'}}">
50 {{ 'alarm.acknowledge' | translate }} 50 {{ 'alarm.acknowledge' | translate }}
51 </md-tooltip> 51 </md-tooltip>
52 </md-button> 52 </md-button>
53 <md-button ng-if="vm.allowClear" class="md-icon-button" ng-click="vm.clearAlarms($event)"> 53 <md-button ng-if="vm.allowClear" class="md-icon-button" ng-click="vm.clearAlarms($event)">
54 <md-icon>clear</md-icon> 54 <md-icon>clear</md-icon>
55 - <md-tooltip md-direction="top"> 55 + <md-tooltip md-direction="{{vm.ctx.dashboard.isWidgetExpanded ? 'bottom' : 'top'}}">
56 {{ 'alarm.clear' | translate }} 56 {{ 'alarm.clear' | translate }}
57 </md-tooltip> 57 </md-tooltip>
58 </md-button> 58 </md-button>
@@ -17,6 +17,8 @@ import $ from 'jquery'; @@ -17,6 +17,8 @@ import $ from 'jquery';
17 import canvasGauges from 'canvas-gauges'; 17 import canvasGauges from 'canvas-gauges';
18 /*import tinycolor from 'tinycolor2';*/ 18 /*import tinycolor from 'tinycolor2';*/
19 19
  20 +/* eslint-disable angular/angularelement */
  21 +
20 export default class TbAnalogueCompass { 22 export default class TbAnalogueCompass {
21 constructor(ctx, canvasId) { 23 constructor(ctx, canvasId) {
22 this.ctx = ctx; 24 this.ctx = ctx;
@@ -436,3 +438,5 @@ export default class TbAnalogueCompass { @@ -436,3 +438,5 @@ export default class TbAnalogueCompass {
436 }; 438 };
437 } 439 }
438 } 440 }
  441 +
  442 +/* eslint-enable angular/angularelement */
@@ -21,7 +21,7 @@ @@ -21,7 +21,7 @@
21 <div class="md-toolbar-tools"> 21 <div class="md-toolbar-tools">
22 <md-button class="md-icon-button" aria-label="{{ 'action.search' | translate }}"> 22 <md-button class="md-icon-button" aria-label="{{ 'action.search' | translate }}">
23 <md-icon aria-label="{{ 'action.search' | translate }}" class="material-icons">search</md-icon> 23 <md-icon aria-label="{{ 'action.search' | translate }}" class="material-icons">search</md-icon>
24 - <md-tooltip md-direction="top"> 24 + <md-tooltip md-direction="{{vm.ctx.dashboard.isWidgetExpanded ? 'bottom' : 'top'}}">
25 {{'entity.search' | translate}} 25 {{'entity.search' | translate}}
26 </md-tooltip> 26 </md-tooltip>
27 </md-button> 27 </md-button>
@@ -31,7 +31,7 @@ @@ -31,7 +31,7 @@
31 </md-input-container> 31 </md-input-container>
32 <md-button class="md-icon-button" aria-label="Close" ng-click="vm.exitFilterMode()"> 32 <md-button class="md-icon-button" aria-label="Close" ng-click="vm.exitFilterMode()">
33 <md-icon aria-label="Close" class="material-icons">close</md-icon> 33 <md-icon aria-label="Close" class="material-icons">close</md-icon>
34 - <md-tooltip md-direction="top"> 34 + <md-tooltip md-direction="{{vm.ctx.dashboard.isWidgetExpanded ? 'bottom' : 'top'}}">
35 {{ 'action.close' | translate }} 35 {{ 'action.close' | translate }}
36 </md-tooltip> 36 </md-tooltip>
37 </md-button> 37 </md-button>
@@ -275,9 +275,11 @@ export default class TbMapWidgetV2 { @@ -275,9 +275,11 @@ export default class TbMapWidgetV2 {
275 for (var i = 0; i < latData.length; i++) { 275 for (var i = 0; i < latData.length; i++) {
276 lat = latData[i][1]; 276 lat = latData[i][1];
277 lng = lngData[i][1]; 277 lng = lngData[i][1];
278 - latLng = tbMap.map.createLatLng(lat, lng);  
279 - if (i == 0 || !latLngs[latLngs.length - 1].equals(latLng)) {  
280 - latLngs.push(latLng); 278 + if (angular.isDefined(lat) && lat != null && angular.isDefined(lng) && lng != null) {
  279 + latLng = tbMap.map.createLatLng(lat, lng);
  280 + if (i == 0 || !latLngs[latLngs.length - 1].equals(latLng)) {
  281 + latLngs.push(latLng);
  282 + }
281 } 283 }
282 } 284 }
283 if (latLngs.length > 0) { 285 if (latLngs.length > 0) {
@@ -308,24 +310,28 @@ export default class TbMapWidgetV2 { @@ -308,24 +310,28 @@ export default class TbMapWidgetV2 {
308 // Create or update marker 310 // Create or update marker
309 lat = latData[latData.length - 1][1]; 311 lat = latData[latData.length - 1][1];
310 lng = lngData[lngData.length - 1][1]; 312 lng = lngData[lngData.length - 1][1];
311 - latLng = tbMap.map.createLatLng(lat, lng);  
312 - if (!location.marker) {  
313 - location.marker = tbMap.map.createMarker(latLng, location.settings,  
314 - function (event) {  
315 - tbMap.callbacks.onLocationClick(location);  
316 - locationRowClick(event, location);  
317 - }, [location.dsIndex]);  
318 - tbMap.markers.push(location.marker);  
319 - locationChanged = true;  
320 - } else {  
321 - var prevPosition = tbMap.map.getMarkerPosition(location.marker);  
322 - if (!prevPosition.equals(latLng)) {  
323 - tbMap.map.setMarkerPosition(location.marker, latLng); 313 + if (angular.isDefined(lat) && lat != null && angular.isDefined(lng) && lng != null) {
  314 + latLng = tbMap.map.createLatLng(lat, lng);
  315 + if (!location.marker) {
  316 + location.marker = tbMap.map.createMarker(latLng, location.settings,
  317 + function (event) {
  318 + tbMap.callbacks.onLocationClick(location);
  319 + locationRowClick(event, location);
  320 + }, [location.dsIndex]);
  321 + tbMap.markers.push(location.marker);
324 locationChanged = true; 322 locationChanged = true;
  323 + } else {
  324 + var prevPosition = tbMap.map.getMarkerPosition(location.marker);
  325 + if (!prevPosition.equals(latLng)) {
  326 + tbMap.map.setMarkerPosition(location.marker, latLng);
  327 + locationChanged = true;
  328 + }
325 } 329 }
326 } 330 }
327 } 331 }
328 - updateLocationStyle(location, dataMap); 332 + if (location.marker) {
  333 + updateLocationStyle(location, dataMap);
  334 + }
329 } 335 }
330 } 336 }
331 return locationChanged; 337 return locationChanged;