Commit c66b06b8f71f240d064d76019090c4c4d078ac1c
1 parent
7378973a
Minor UI bug fixes and improvements.
Showing
20 changed files
with
107 additions
and
77 deletions
... | ... | @@ -295,9 +295,8 @@ function AlarmService($http, $q, $interval, $filter, $timeout, utils, types) { |
295 | 295 | if (alarmSourceListener.lastUpdateTs) { |
296 | 296 | var interval = now - alarmSourceListener.lastUpdateTs; |
297 | 297 | alarmSourceListener.alarmsQuery.startTime += interval; |
298 | - } else { | |
299 | - alarmSourceListener.lastUpdateTs = now; | |
300 | 298 | } |
299 | + alarmSourceListener.lastUpdateTs = now; | |
301 | 300 | } |
302 | 301 | alarmSourceListener.alarmsUpdated(alarms, false); |
303 | 302 | } | ... | ... |
... | ... | @@ -63,7 +63,7 @@ function DashboardService($rootScope, $http, $q, $location, customerService) { |
63 | 63 | return deferred.promise; |
64 | 64 | } |
65 | 65 | |
66 | - function getTenantDashboards(pageLink) { | |
66 | + function getTenantDashboards(pageLink, applyCustomersInfo) { | |
67 | 67 | var deferred = $q.defer(); |
68 | 68 | var url = '/api/tenant/dashboards?limit=' + pageLink.limit; |
69 | 69 | if (angular.isDefined(pageLink.textSearch)) { |
... | ... | @@ -76,22 +76,26 @@ function DashboardService($rootScope, $http, $q, $location, customerService) { |
76 | 76 | url += '&textOffset=' + pageLink.textOffset; |
77 | 77 | } |
78 | 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 | 92 | }, function fail() { |
89 | 93 | deferred.reject(); |
90 | 94 | }); |
91 | 95 | return deferred.promise; |
92 | 96 | } |
93 | 97 | |
94 | - function getCustomerDashboards(customerId, pageLink) { | |
98 | + function getCustomerDashboards(customerId, pageLink, applyCustomersInfo) { | |
95 | 99 | var deferred = $q.defer(); |
96 | 100 | var url = '/api/customer/' + customerId + '/dashboards?limit=' + pageLink.limit; |
97 | 101 | if (angular.isDefined(pageLink.textSearch)) { |
... | ... | @@ -104,15 +108,19 @@ function DashboardService($rootScope, $http, $q, $location, customerService) { |
104 | 108 | url += '&textOffset=' + pageLink.textOffset; |
105 | 109 | } |
106 | 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 | 124 | }, function fail() { |
117 | 125 | deferred.reject(); |
118 | 126 | }); | ... | ... |
... | ... | @@ -267,9 +267,9 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device |
267 | 267 | break; |
268 | 268 | case types.entityType.dashboard: |
269 | 269 | if (user.authority === 'CUSTOMER_USER') { |
270 | - promise = dashboardService.getCustomerDashboards(customerId, pageLink); | |
270 | + promise = dashboardService.getCustomerDashboards(customerId, pageLink, false); | |
271 | 271 | } else { |
272 | - promise = dashboardService.getTenantDashboards(pageLink); | |
272 | + promise = dashboardService.getTenantDashboards(pageLink, false); | |
273 | 273 | } |
274 | 274 | break; |
275 | 275 | case types.entityType.user: | ... | ... |
... | ... | @@ -674,11 +674,14 @@ export default class Subscription { |
674 | 674 | |
675 | 675 | alarmsUpdated(alarms, apply) { |
676 | 676 | this.notifyDataLoaded(); |
677 | + var updated = !angular.equals(this.alarms, alarms); | |
677 | 678 | this.alarms = alarms; |
678 | 679 | if (this.subscriptionTimewindow && this.subscriptionTimewindow.realtimeWindowMs) { |
679 | 680 | this.updateTimewindow(); |
680 | 681 | } |
681 | - this.onDataUpdated(apply); | |
682 | + if (updated) { | |
683 | + this.onDataUpdated(apply); | |
684 | + } | |
682 | 685 | } |
683 | 686 | |
684 | 687 | updateLegend(dataIndex, data, apply) { | ... | ... |
... | ... | @@ -265,9 +265,9 @@ function UserService($http, $q, $rootScope, adminService, dashboardService, logi |
265 | 265 | var pageLink = {limit: 100}; |
266 | 266 | var fetchDashboardsPromise; |
267 | 267 | if (currentUser.authority === 'TENANT_ADMIN') { |
268 | - fetchDashboardsPromise = dashboardService.getTenantDashboards(pageLink); | |
268 | + fetchDashboardsPromise = dashboardService.getTenantDashboards(pageLink, false); | |
269 | 269 | } else { |
270 | - fetchDashboardsPromise = dashboardService.getCustomerDashboards(currentUser.customerId, pageLink); | |
270 | + fetchDashboardsPromise = dashboardService.getCustomerDashboards(currentUser.customerId, pageLink, false); | |
271 | 271 | } |
272 | 272 | fetchDashboardsPromise.then( |
273 | 273 | function success(result) { | ... | ... |
... | ... | @@ -48,7 +48,7 @@ function DashboardAutocomplete($compile, $templateCache, $q, dashboardService, u |
48 | 48 | var promise; |
49 | 49 | if (scope.dashboardsScope === 'customer' || userService.getAuthority() === 'CUSTOMER_USER') { |
50 | 50 | if (scope.customerId) { |
51 | - promise = dashboardService.getCustomerDashboards(scope.customerId, pageLink); | |
51 | + promise = dashboardService.getCustomerDashboards(scope.customerId, pageLink, false); | |
52 | 52 | } else { |
53 | 53 | promise = $q.when({data: []}); |
54 | 54 | } |
... | ... | @@ -60,7 +60,7 @@ function DashboardAutocomplete($compile, $templateCache, $q, dashboardService, u |
60 | 60 | promise = $q.when({data: []}); |
61 | 61 | } |
62 | 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 | 48 | var promise; |
49 | 49 | if (scope.dashboardsScope === 'customer' || userService.getAuthority() === 'CUSTOMER_USER') { |
50 | 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 | 52 | } else { |
53 | 53 | promise = $q.when({data: []}); |
54 | 54 | } |
55 | 55 | } else { |
56 | - promise = dashboardService.getTenantDashboards(pageLink); | |
56 | + promise = dashboardService.getTenantDashboards(pageLink, false); | |
57 | 57 | } |
58 | 58 | |
59 | 59 | promise.then(function success(result) { | ... | ... |
... | ... | @@ -15,7 +15,6 @@ |
15 | 15 | */ |
16 | 16 | import './dashboard.scss'; |
17 | 17 | |
18 | -import $ from 'jquery'; | |
19 | 18 | import 'javascript-detect-element-resize/detect-element-resize'; |
20 | 19 | import angularGridster from 'angular-gridster'; |
21 | 20 | import thingsboardTypes from '../common/types.constant'; |
... | ... | @@ -94,8 +93,8 @@ function DashboardController($scope, $rootScope, $element, $timeout, $mdMedia, $ |
94 | 93 | var highlightedWidget = null; |
95 | 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 | 99 | var vm = this; |
101 | 100 | |
... | ... | @@ -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 | 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 | 236 | watchWidgets(); |
238 | 237 | |
239 | - function onGirdsterParentResize() { | |
238 | + function onGridsterParentResize() { | |
240 | 239 | if (gridsterParent.height() && autofillHeight()) { |
241 | 240 | updateMobileOpts(); |
242 | 241 | } |
... | ... | @@ -244,6 +243,10 @@ function DashboardController($scope, $rootScope, $element, $timeout, $mdMedia, $ |
244 | 243 | |
245 | 244 | function watchWidgets() { |
246 | 245 | $scope.widgetsCollectionWatch = $scope.$watchCollection('vm.widgets', function () { |
246 | + if (vm.skipInitialWidgetsWatch) { | |
247 | + $timeout(function() { vm.skipInitialWidgetsWatch = false; }); | |
248 | + return; | |
249 | + } | |
247 | 250 | var ids = []; |
248 | 251 | for (var i=0;i<vm.widgets.length;i++) { |
249 | 252 | var widget = vm.widgets[i]; |
... | ... | @@ -524,6 +527,7 @@ function DashboardController($scope, $rootScope, $element, $timeout, $mdMedia, $ |
524 | 527 | } |
525 | 528 | return res; |
526 | 529 | }); |
530 | + vm.skipInitialWidgetsWatch = true; | |
527 | 531 | watchWidgets(); |
528 | 532 | } |
529 | 533 | |
... | ... | @@ -714,9 +718,9 @@ function DashboardController($scope, $rootScope, $element, $timeout, $mdMedia, $ |
714 | 718 | |
715 | 719 | function scrollToWidget(widget, delay) { |
716 | 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 | 722 | if (item) { |
719 | - var height = $(item).outerHeight(true); | |
723 | + var height = angular.element(item).outerHeight(true); | |
720 | 724 | var rectHeight = gridsterParent.height(); |
721 | 725 | var offset = (rectHeight - height) / 2; |
722 | 726 | var scrollTop = item.offsetTop; | ... | ... |
... | ... | @@ -55,7 +55,7 @@ |
55 | 55 | ng-show="!vm.isEdit" |
56 | 56 | ng-click="action.onAction($event)" |
57 | 57 | class="md-icon-button"> |
58 | - <md-tooltip md-direction="top"> | |
58 | + <md-tooltip md-direction="{{vm.isWidgetExpanded ? 'bottom' : 'top'}}"> | |
59 | 59 | {{action.displayName}} |
60 | 60 | </md-tooltip> |
61 | 61 | <ng-md-icon size="20" icon="{{action.icon}}"></ng-md-icon> |
... | ... | @@ -65,7 +65,7 @@ |
65 | 65 | ng-show="!vm.isEdit && action.show" |
66 | 66 | ng-click="action.onAction($event)" |
67 | 67 | class="md-icon-button"> |
68 | - <md-tooltip md-direction="top"> | |
68 | + <md-tooltip md-direction="{{vm.isWidgetExpanded ? 'bottom' : 'top'}}"> | |
69 | 69 | {{ action.name | translate }} |
70 | 70 | </md-tooltip> |
71 | 71 | <ng-md-icon size="20" icon="{{action.icon}}"></ng-md-icon> |
... | ... | @@ -114,7 +114,8 @@ |
114 | 114 | isEdit: vm.isEdit, |
115 | 115 | isMobile: vm.isMobileSize, |
116 | 116 | dashboardTimewindow: vm.dashboardTimewindow, |
117 | - dashboardTimewindowApi: vm.dashboardTimewindowApi }"> | |
117 | + dashboardTimewindowApi: vm.dashboardTimewindowApi, | |
118 | + dashboard: vm }"> | |
118 | 119 | </div> |
119 | 120 | </div> |
120 | 121 | </div> | ... | ... |
... | ... | @@ -186,7 +186,7 @@ |
186 | 186 | <div translate ng-message="entityKeys" ng-if="widgetType === types.widgetType.latest.value" class="tb-error-message">datakey.timeseries-or-attributes-required</div> |
187 | 187 | <div translate ng-message="entityKeys" ng-if="widgetType === types.widgetType.alarm.value" class="tb-error-message">datakey.alarm-fields-required</div> |
188 | 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 | 190 | translate="datakey.maximum-timeseries-or-attributes" |
191 | 191 | translate-values="{count: maxDataKeys}" |
192 | 192 | translate-interpolation="messageformat" | ... | ... |
... | ... | @@ -132,7 +132,7 @@ |
132 | 132 | <div translate ng-message="datasourceKeys" ng-if="widgetType !== types.widgetType.alarm.value" class="tb-error-message">datakey.function-types-required</div> |
133 | 133 | <div translate ng-message="datasourceKeys" ng-if="widgetType === types.widgetType.alarm.value" class="tb-error-message">datakey.alarm-fields-required</div> |
134 | 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 | 136 | translate="datakey.maximum-function-types" |
137 | 137 | translate-values="{count: maxDataKeys}" |
138 | 138 | translate-interpolation="messageformat" | ... | ... |
... | ... | @@ -22,7 +22,7 @@ import Subscription from '../../api/subscription'; |
22 | 22 | /*@ngInject*/ |
23 | 23 | export default function WidgetController($scope, $state, $timeout, $window, $element, $q, $log, $injector, $filter, $compile, tbRaf, types, utils, timeService, |
24 | 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 | 27 | var vm = this; |
28 | 28 | |
... | ... | @@ -67,6 +67,7 @@ export default function WidgetController($scope, $state, $timeout, $window, $ele |
67 | 67 | hideTitlePanel: false, |
68 | 68 | isEdit: isEdit, |
69 | 69 | isMobile: isMobile, |
70 | + dashboard: dashboard, | |
70 | 71 | widgetConfig: widget.config, |
71 | 72 | settings: widget.config.settings, |
72 | 73 | units: widget.config.units || '', | ... | ... |
... | ... | @@ -52,7 +52,7 @@ export default function AddDashboardsToCustomerController(dashboardService, $mdD |
52 | 52 | fetchMoreItems_: function () { |
53 | 53 | if (vm.dashboards.hasNext && !vm.dashboards.pending) { |
54 | 54 | vm.dashboards.pending = true; |
55 | - dashboardService.getTenantDashboards(vm.dashboards.nextPageLink).then( | |
55 | + dashboardService.getTenantDashboards(vm.dashboards.nextPageLink, false).then( | |
56 | 56 | function success(dashboards) { |
57 | 57 | vm.dashboards.data = vm.dashboards.data.concat(dashboards.data); |
58 | 58 | vm.dashboards.nextPageLink = dashboards.nextPageLink; | ... | ... |
... | ... | @@ -15,7 +15,7 @@ |
15 | 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 | 19 | hide-expand-button="vm.widgetEditMode || vm.iframeMode || forceFullscreen" expand-tooltip-direction="bottom" ng-if="vm.dashboard"> |
20 | 20 | <section class="tb-dashboard-toolbar" ng-show="vm.showDashboardToolbar()" |
21 | 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 | 167 | |
168 | 168 | if (vm.dashboardsScope === 'tenant') { |
169 | 169 | fetchDashboardsFunction = function (pageLink) { |
170 | - return dashboardService.getTenantDashboards(pageLink); | |
170 | + return dashboardService.getTenantDashboards(pageLink, true); | |
171 | 171 | }; |
172 | 172 | deleteDashboardFunction = function (dashboardId) { |
173 | 173 | return dashboardService.deleteDashboard(dashboardId); |
... | ... | @@ -290,7 +290,7 @@ export function DashboardsController(userService, dashboardService, customerServ |
290 | 290 | }); |
291 | 291 | } else if (vm.dashboardsScope === 'customer' || vm.dashboardsScope === 'customer_user') { |
292 | 292 | fetchDashboardsFunction = function (pageLink) { |
293 | - return dashboardService.getCustomerDashboards(customerId, pageLink); | |
293 | + return dashboardService.getCustomerDashboards(customerId, pageLink, true); | |
294 | 294 | }; |
295 | 295 | deleteDashboardFunction = function (dashboardId) { |
296 | 296 | return dashboardService.unassignDashboardFromCustomer(dashboardId); |
... | ... | @@ -468,7 +468,7 @@ export function DashboardsController(userService, dashboardService, customerServ |
468 | 468 | $event.stopPropagation(); |
469 | 469 | } |
470 | 470 | var pageSize = 10; |
471 | - dashboardService.getTenantDashboards({limit: pageSize, textSearch: ''}).then( | |
471 | + dashboardService.getTenantDashboards({limit: pageSize, textSearch: ''}, false).then( | |
472 | 472 | function success(_dashboards) { |
473 | 473 | var dashboards = { |
474 | 474 | pageSize: pageSize, | ... | ... |
... | ... | @@ -22,18 +22,22 @@ export default function BreadcrumbLabel($translate) { |
22 | 22 | var labelObj; |
23 | 23 | labelObj = angular.fromJson(bLabel); |
24 | 24 | if (labelObj) { |
25 | + var translate = !(labelObj.translate && labelObj.translate === 'false'); | |
26 | + var key = translate ? $translate.use() : 'orig'; | |
25 | 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 | 32 | if (translate) { |
29 | 33 | $translate([labelObj.label]).then( |
30 | 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 | 41 | } else { |
38 | 42 | return ''; |
39 | 43 | } | ... | ... |
... | ... | @@ -22,7 +22,7 @@ |
22 | 22 | <div class="md-toolbar-tools"> |
23 | 23 | <md-button class="md-icon-button" aria-label="{{ 'action.search' | translate }}"> |
24 | 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 | 26 | {{'alarm.search' | translate}} |
27 | 27 | </md-tooltip> |
28 | 28 | </md-button> |
... | ... | @@ -32,7 +32,7 @@ |
32 | 32 | </md-input-container> |
33 | 33 | <md-button class="md-icon-button" aria-label="Close" ng-click="vm.exitFilterMode()"> |
34 | 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 | 36 | {{ 'action.close' | translate }} |
37 | 37 | </md-tooltip> |
38 | 38 | </md-button> |
... | ... | @@ -46,13 +46,13 @@ |
46 | 46 | <span flex></span> |
47 | 47 | <md-button ng-if="vm.allowAcknowledgment" class="md-icon-button" ng-click="vm.ackAlarms($event)"> |
48 | 48 | <md-icon>done</md-icon> |
49 | - <md-tooltip md-direction="top"> | |
49 | + <md-tooltip md-direction="{{vm.ctx.dashboard.isWidgetExpanded ? 'bottom' : 'top'}}"> | |
50 | 50 | {{ 'alarm.acknowledge' | translate }} |
51 | 51 | </md-tooltip> |
52 | 52 | </md-button> |
53 | 53 | <md-button ng-if="vm.allowClear" class="md-icon-button" ng-click="vm.clearAlarms($event)"> |
54 | 54 | <md-icon>clear</md-icon> |
55 | - <md-tooltip md-direction="top"> | |
55 | + <md-tooltip md-direction="{{vm.ctx.dashboard.isWidgetExpanded ? 'bottom' : 'top'}}"> | |
56 | 56 | {{ 'alarm.clear' | translate }} |
57 | 57 | </md-tooltip> |
58 | 58 | </md-button> | ... | ... |
... | ... | @@ -17,6 +17,8 @@ import $ from 'jquery'; |
17 | 17 | import canvasGauges from 'canvas-gauges'; |
18 | 18 | /*import tinycolor from 'tinycolor2';*/ |
19 | 19 | |
20 | +/* eslint-disable angular/angularelement */ | |
21 | + | |
20 | 22 | export default class TbAnalogueCompass { |
21 | 23 | constructor(ctx, canvasId) { |
22 | 24 | this.ctx = ctx; |
... | ... | @@ -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 | 21 | <div class="md-toolbar-tools"> |
22 | 22 | <md-button class="md-icon-button" aria-label="{{ 'action.search' | translate }}"> |
23 | 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 | 25 | {{'entity.search' | translate}} |
26 | 26 | </md-tooltip> |
27 | 27 | </md-button> |
... | ... | @@ -31,7 +31,7 @@ |
31 | 31 | </md-input-container> |
32 | 32 | <md-button class="md-icon-button" aria-label="Close" ng-click="vm.exitFilterMode()"> |
33 | 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 | 35 | {{ 'action.close' | translate }} |
36 | 36 | </md-tooltip> |
37 | 37 | </md-button> | ... | ... |
... | ... | @@ -275,9 +275,11 @@ export default class TbMapWidgetV2 { |
275 | 275 | for (var i = 0; i < latData.length; i++) { |
276 | 276 | lat = latData[i][1]; |
277 | 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 | 285 | if (latLngs.length > 0) { |
... | ... | @@ -308,24 +310,28 @@ export default class TbMapWidgetV2 { |
308 | 310 | // Create or update marker |
309 | 311 | lat = latData[latData.length - 1][1]; |
310 | 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 | 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 | 337 | return locationChanged; | ... | ... |