Minor UI bug fixes and improvements.

This commit is contained in:
Igor Kulikov 2017-10-23 20:25:03 +03:00
parent 7378973a2b
commit c66b06b8f7
20 changed files with 107 additions and 77 deletions

View File

@ -295,9 +295,8 @@ function AlarmService($http, $q, $interval, $filter, $timeout, utils, types) {
if (alarmSourceListener.lastUpdateTs) {
var interval = now - alarmSourceListener.lastUpdateTs;
alarmSourceListener.alarmsQuery.startTime += interval;
} else {
alarmSourceListener.lastUpdateTs = now;
}
alarmSourceListener.lastUpdateTs = now;
}
alarmSourceListener.alarmsUpdated(alarms, false);
}

View File

@ -63,7 +63,7 @@ function DashboardService($rootScope, $http, $q, $location, customerService) {
return deferred.promise;
}
function getTenantDashboards(pageLink) {
function getTenantDashboards(pageLink, applyCustomersInfo) {
var deferred = $q.defer();
var url = '/api/tenant/dashboards?limit=' + pageLink.limit;
if (angular.isDefined(pageLink.textSearch)) {
@ -76,6 +76,7 @@ function DashboardService($rootScope, $http, $q, $location, customerService) {
url += '&textOffset=' + pageLink.textOffset;
}
$http.get(url, null).then(function success(response) {
if (applyCustomersInfo) {
customerService.applyAssignedCustomersInfo(response.data.data).then(
function success(data) {
response.data.data = data;
@ -85,13 +86,16 @@ function DashboardService($rootScope, $http, $q, $location, customerService) {
deferred.reject();
}
);
} else {
deferred.resolve(response.data);
}
}, function fail() {
deferred.reject();
});
return deferred.promise;
}
function getCustomerDashboards(customerId, pageLink) {
function getCustomerDashboards(customerId, pageLink, applyCustomersInfo) {
var deferred = $q.defer();
var url = '/api/customer/' + customerId + '/dashboards?limit=' + pageLink.limit;
if (angular.isDefined(pageLink.textSearch)) {
@ -104,6 +108,7 @@ function DashboardService($rootScope, $http, $q, $location, customerService) {
url += '&textOffset=' + pageLink.textOffset;
}
$http.get(url, null).then(function success(response) {
if (applyCustomersInfo) {
customerService.applyAssignedCustomerInfo(response.data.data, customerId).then(
function success(data) {
response.data.data = data;
@ -113,6 +118,9 @@ function DashboardService($rootScope, $http, $q, $location, customerService) {
deferred.reject();
}
);
} else {
deferred.resolve(response.data);
}
}, function fail() {
deferred.reject();
});

View File

@ -267,9 +267,9 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device
break;
case types.entityType.dashboard:
if (user.authority === 'CUSTOMER_USER') {
promise = dashboardService.getCustomerDashboards(customerId, pageLink);
promise = dashboardService.getCustomerDashboards(customerId, pageLink, false);
} else {
promise = dashboardService.getTenantDashboards(pageLink);
promise = dashboardService.getTenantDashboards(pageLink, false);
}
break;
case types.entityType.user:

View File

@ -674,12 +674,15 @@ export default class Subscription {
alarmsUpdated(alarms, apply) {
this.notifyDataLoaded();
var updated = !angular.equals(this.alarms, alarms);
this.alarms = alarms;
if (this.subscriptionTimewindow && this.subscriptionTimewindow.realtimeWindowMs) {
this.updateTimewindow();
}
if (updated) {
this.onDataUpdated(apply);
}
}
updateLegend(dataIndex, data, apply) {
var dataKey = this.legendData.keys[dataIndex].dataKey;

View File

@ -265,9 +265,9 @@ function UserService($http, $q, $rootScope, adminService, dashboardService, logi
var pageLink = {limit: 100};
var fetchDashboardsPromise;
if (currentUser.authority === 'TENANT_ADMIN') {
fetchDashboardsPromise = dashboardService.getTenantDashboards(pageLink);
fetchDashboardsPromise = dashboardService.getTenantDashboards(pageLink, false);
} else {
fetchDashboardsPromise = dashboardService.getCustomerDashboards(currentUser.customerId, pageLink);
fetchDashboardsPromise = dashboardService.getCustomerDashboards(currentUser.customerId, pageLink, false);
}
fetchDashboardsPromise.then(
function success(result) {

View File

@ -48,7 +48,7 @@ function DashboardAutocomplete($compile, $templateCache, $q, dashboardService, u
var promise;
if (scope.dashboardsScope === 'customer' || userService.getAuthority() === 'CUSTOMER_USER') {
if (scope.customerId) {
promise = dashboardService.getCustomerDashboards(scope.customerId, pageLink);
promise = dashboardService.getCustomerDashboards(scope.customerId, pageLink, false);
} else {
promise = $q.when({data: []});
}
@ -60,7 +60,7 @@ function DashboardAutocomplete($compile, $templateCache, $q, dashboardService, u
promise = $q.when({data: []});
}
} else {
promise = dashboardService.getTenantDashboards(pageLink);
promise = dashboardService.getTenantDashboards(pageLink, false);
}
}

View File

@ -48,12 +48,12 @@ function DashboardSelect($compile, $templateCache, $q, $mdMedia, $mdPanel, $docu
var promise;
if (scope.dashboardsScope === 'customer' || userService.getAuthority() === 'CUSTOMER_USER') {
if (scope.customerId && scope.customerId != types.id.nullUid) {
promise = dashboardService.getCustomerDashboards(scope.customerId, pageLink);
promise = dashboardService.getCustomerDashboards(scope.customerId, pageLink, false);
} else {
promise = $q.when({data: []});
}
} else {
promise = dashboardService.getTenantDashboards(pageLink);
promise = dashboardService.getTenantDashboards(pageLink, false);
}
promise.then(function success(result) {

View File

@ -15,7 +15,6 @@
*/
import './dashboard.scss';
import $ from 'jquery';
import 'javascript-detect-element-resize/detect-element-resize';
import angularGridster from 'angular-gridster';
import thingsboardTypes from '../common/types.constant';
@ -94,8 +93,8 @@ function DashboardController($scope, $rootScope, $element, $timeout, $mdMedia, $
var highlightedWidget = null;
var selectedWidget = null;
var gridsterParent = $('#gridster-parent', $element);
var gridsterElement = angular.element($('#gridster-child', gridsterParent));
var gridsterParent = angular.element('#gridster-parent', $element);
var gridsterElement = angular.element('#gridster-child', gridsterParent);
var vm = this;
@ -228,15 +227,15 @@ function DashboardController($scope, $rootScope, $element, $timeout, $mdMedia, $
}
};
addResizeListener(gridsterParent[0], onGirdsterParentResize); // eslint-disable-line no-undef
addResizeListener(gridsterParent[0], onGridsterParentResize); // eslint-disable-line no-undef
$scope.$on("$destroy", function () {
removeResizeListener(gridsterParent[0], onGirdsterParentResize); // eslint-disable-line no-undef
removeResizeListener(gridsterParent[0], onGridsterParentResize); // eslint-disable-line no-undef
});
watchWidgets();
function onGirdsterParentResize() {
function onGridsterParentResize() {
if (gridsterParent.height() && autofillHeight()) {
updateMobileOpts();
}
@ -244,6 +243,10 @@ function DashboardController($scope, $rootScope, $element, $timeout, $mdMedia, $
function watchWidgets() {
$scope.widgetsCollectionWatch = $scope.$watchCollection('vm.widgets', function () {
if (vm.skipInitialWidgetsWatch) {
$timeout(function() { vm.skipInitialWidgetsWatch = false; });
return;
}
var ids = [];
for (var i=0;i<vm.widgets.length;i++) {
var widget = vm.widgets[i];
@ -524,6 +527,7 @@ function DashboardController($scope, $rootScope, $element, $timeout, $mdMedia, $
}
return res;
});
vm.skipInitialWidgetsWatch = true;
watchWidgets();
}
@ -714,9 +718,9 @@ function DashboardController($scope, $rootScope, $element, $timeout, $mdMedia, $
function scrollToWidget(widget, delay) {
if (vm.gridster) {
var item = $('.gridster-item', vm.gridster.$element)[vm.widgets.indexOf(widget)];
var item = angular.element('.gridster-item', vm.gridster.$element)[vm.widgets.indexOf(widget)];
if (item) {
var height = $(item).outerHeight(true);
var height = angular.element(item).outerHeight(true);
var rectHeight = gridsterParent.height();
var offset = (rectHeight - height) / 2;
var scrollTop = item.offsetTop;

View File

@ -55,7 +55,7 @@
ng-show="!vm.isEdit"
ng-click="action.onAction($event)"
class="md-icon-button">
<md-tooltip md-direction="top">
<md-tooltip md-direction="{{vm.isWidgetExpanded ? 'bottom' : 'top'}}">
{{action.displayName}}
</md-tooltip>
<ng-md-icon size="20" icon="{{action.icon}}"></ng-md-icon>
@ -65,7 +65,7 @@
ng-show="!vm.isEdit && action.show"
ng-click="action.onAction($event)"
class="md-icon-button">
<md-tooltip md-direction="top">
<md-tooltip md-direction="{{vm.isWidgetExpanded ? 'bottom' : 'top'}}">
{{ action.name | translate }}
</md-tooltip>
<ng-md-icon size="20" icon="{{action.icon}}"></ng-md-icon>
@ -114,7 +114,8 @@
isEdit: vm.isEdit,
isMobile: vm.isMobileSize,
dashboardTimewindow: vm.dashboardTimewindow,
dashboardTimewindowApi: vm.dashboardTimewindowApi }">
dashboardTimewindowApi: vm.dashboardTimewindowApi,
dashboard: vm }">
</div>
</div>
</div>

View File

@ -186,7 +186,7 @@
<div translate ng-message="entityKeys" ng-if="widgetType === types.widgetType.latest.value" class="tb-error-message">datakey.timeseries-or-attributes-required</div>
<div translate ng-message="entityKeys" ng-if="widgetType === types.widgetType.alarm.value" class="tb-error-message">datakey.alarm-fields-required</div>
</div>
<div class="md-caption" style="color: rgba(0,0,0,0.57);" ng-if="maxDataKeys != -1"
<div class="md-caption" style="color: rgba(0,0,0,0.57);" ng-if="maxDataKeys > -1"
translate="datakey.maximum-timeseries-or-attributes"
translate-values="{count: maxDataKeys}"
translate-interpolation="messageformat"

View File

@ -132,7 +132,7 @@
<div translate ng-message="datasourceKeys" ng-if="widgetType !== types.widgetType.alarm.value" class="tb-error-message">datakey.function-types-required</div>
<div translate ng-message="datasourceKeys" ng-if="widgetType === types.widgetType.alarm.value" class="tb-error-message">datakey.alarm-fields-required</div>
</div>
<div class="md-caption" style="color: rgba(0,0,0,0.57);" ng-if="maxDataKeys != -1"
<div class="md-caption" style="color: rgba(0,0,0,0.57);" ng-if="maxDataKeys > -1"
translate="datakey.maximum-function-types"
translate-values="{count: maxDataKeys}"
translate-interpolation="messageformat"

View File

@ -22,7 +22,7 @@ import Subscription from '../../api/subscription';
/*@ngInject*/
export default function WidgetController($scope, $state, $timeout, $window, $element, $q, $log, $injector, $filter, $compile, tbRaf, types, utils, timeService,
datasourceService, alarmService, entityService, dashboardService, deviceService, visibleRect, isEdit, isMobile, dashboardTimewindow,
dashboardTimewindowApi, widget, aliasController, stateController, widgetInfo, widgetType) {
dashboardTimewindowApi, dashboard, widget, aliasController, stateController, widgetInfo, widgetType) {
var vm = this;
@ -67,6 +67,7 @@ export default function WidgetController($scope, $state, $timeout, $window, $ele
hideTitlePanel: false,
isEdit: isEdit,
isMobile: isMobile,
dashboard: dashboard,
widgetConfig: widget.config,
settings: widget.config.settings,
units: widget.config.units || '',

View File

@ -52,7 +52,7 @@ export default function AddDashboardsToCustomerController(dashboardService, $mdD
fetchMoreItems_: function () {
if (vm.dashboards.hasNext && !vm.dashboards.pending) {
vm.dashboards.pending = true;
dashboardService.getTenantDashboards(vm.dashboards.nextPageLink).then(
dashboardService.getTenantDashboards(vm.dashboards.nextPageLink, false).then(
function success(dashboards) {
vm.dashboards.data = vm.dashboards.data.concat(dashboards.data);
vm.dashboards.nextPageLink = dashboards.nextPageLink;

View File

@ -15,7 +15,7 @@
limitations under the License.
-->
<md-content flex tb-expand-fullscreen="vm.widgetEditMode || vm.iframeMode || forceFullscreen" expand-button-id="dashboard-expand-button"
<md-content style="padding-top: 150px;" flex tb-expand-fullscreen="vm.widgetEditMode || vm.iframeMode || forceFullscreen" expand-button-id="dashboard-expand-button"
hide-expand-button="vm.widgetEditMode || vm.iframeMode || forceFullscreen" expand-tooltip-direction="bottom" ng-if="vm.dashboard">
<section class="tb-dashboard-toolbar" ng-show="vm.showDashboardToolbar()"
ng-class="{ 'tb-dashboard-toolbar-opened': vm.toolbarOpened, 'tb-dashboard-toolbar-closed': !vm.toolbarOpened }">

View File

@ -167,7 +167,7 @@ export function DashboardsController(userService, dashboardService, customerServ
if (vm.dashboardsScope === 'tenant') {
fetchDashboardsFunction = function (pageLink) {
return dashboardService.getTenantDashboards(pageLink);
return dashboardService.getTenantDashboards(pageLink, true);
};
deleteDashboardFunction = function (dashboardId) {
return dashboardService.deleteDashboard(dashboardId);
@ -290,7 +290,7 @@ export function DashboardsController(userService, dashboardService, customerServ
});
} else if (vm.dashboardsScope === 'customer' || vm.dashboardsScope === 'customer_user') {
fetchDashboardsFunction = function (pageLink) {
return dashboardService.getCustomerDashboards(customerId, pageLink);
return dashboardService.getCustomerDashboards(customerId, pageLink, true);
};
deleteDashboardFunction = function (dashboardId) {
return dashboardService.unassignDashboardFromCustomer(dashboardId);
@ -468,7 +468,7 @@ export function DashboardsController(userService, dashboardService, customerServ
$event.stopPropagation();
}
var pageSize = 10;
dashboardService.getTenantDashboards({limit: pageSize, textSearch: ''}).then(
dashboardService.getTenantDashboards({limit: pageSize, textSearch: ''}, false).then(
function success(_dashboards) {
var dashboards = {
pageSize: pageSize,

View File

@ -22,18 +22,22 @@ export default function BreadcrumbLabel($translate) {
var labelObj;
labelObj = angular.fromJson(bLabel);
if (labelObj) {
if (!labels[labelObj.label]) {
labels[labelObj.label] = labelObj.label;
var translate = !(labelObj.translate && labelObj.translate === 'false');
var key = translate ? $translate.use() : 'orig';
if (!labels[labelObj.label]) {
labels[labelObj.label] = {};
}
if (!labels[labelObj.label][key]) {
labels[labelObj.label][key] = labelObj.label;
if (translate) {
$translate([labelObj.label]).then(
function (translations) {
labels[labelObj.label] = translations[labelObj.label];
labels[labelObj.label][key] = translations[labelObj.label];
}
)
}
}
return labels[labelObj.label];
return labels[labelObj.label][key];
} else {
return '';
}

View File

@ -22,7 +22,7 @@
<div class="md-toolbar-tools">
<md-button class="md-icon-button" aria-label="{{ 'action.search' | translate }}">
<md-icon aria-label="{{ 'action.search' | translate }}" class="material-icons">search</md-icon>
<md-tooltip md-direction="top">
<md-tooltip md-direction="{{vm.ctx.dashboard.isWidgetExpanded ? 'bottom' : 'top'}}">
{{'alarm.search' | translate}}
</md-tooltip>
</md-button>
@ -32,7 +32,7 @@
</md-input-container>
<md-button class="md-icon-button" aria-label="Close" ng-click="vm.exitFilterMode()">
<md-icon aria-label="Close" class="material-icons">close</md-icon>
<md-tooltip md-direction="top">
<md-tooltip md-direction="{{vm.ctx.dashboard.isWidgetExpanded ? 'bottom' : 'top'}}">
{{ 'action.close' | translate }}
</md-tooltip>
</md-button>
@ -46,13 +46,13 @@
<span flex></span>
<md-button ng-if="vm.allowAcknowledgment" class="md-icon-button" ng-click="vm.ackAlarms($event)">
<md-icon>done</md-icon>
<md-tooltip md-direction="top">
<md-tooltip md-direction="{{vm.ctx.dashboard.isWidgetExpanded ? 'bottom' : 'top'}}">
{{ 'alarm.acknowledge' | translate }}
</md-tooltip>
</md-button>
<md-button ng-if="vm.allowClear" class="md-icon-button" ng-click="vm.clearAlarms($event)">
<md-icon>clear</md-icon>
<md-tooltip md-direction="top">
<md-tooltip md-direction="{{vm.ctx.dashboard.isWidgetExpanded ? 'bottom' : 'top'}}">
{{ 'alarm.clear' | translate }}
</md-tooltip>
</md-button>

View File

@ -17,6 +17,8 @@ import $ from 'jquery';
import canvasGauges from 'canvas-gauges';
/*import tinycolor from 'tinycolor2';*/
/* eslint-disable angular/angularelement */
export default class TbAnalogueCompass {
constructor(ctx, canvasId) {
this.ctx = ctx;
@ -436,3 +438,5 @@ export default class TbAnalogueCompass {
};
}
}
/* eslint-enable angular/angularelement */

View File

@ -21,7 +21,7 @@
<div class="md-toolbar-tools">
<md-button class="md-icon-button" aria-label="{{ 'action.search' | translate }}">
<md-icon aria-label="{{ 'action.search' | translate }}" class="material-icons">search</md-icon>
<md-tooltip md-direction="top">
<md-tooltip md-direction="{{vm.ctx.dashboard.isWidgetExpanded ? 'bottom' : 'top'}}">
{{'entity.search' | translate}}
</md-tooltip>
</md-button>
@ -31,7 +31,7 @@
</md-input-container>
<md-button class="md-icon-button" aria-label="Close" ng-click="vm.exitFilterMode()">
<md-icon aria-label="Close" class="material-icons">close</md-icon>
<md-tooltip md-direction="top">
<md-tooltip md-direction="{{vm.ctx.dashboard.isWidgetExpanded ? 'bottom' : 'top'}}">
{{ 'action.close' | translate }}
</md-tooltip>
</md-button>

View File

@ -275,11 +275,13 @@ export default class TbMapWidgetV2 {
for (var i = 0; i < latData.length; i++) {
lat = latData[i][1];
lng = lngData[i][1];
if (angular.isDefined(lat) && lat != null && angular.isDefined(lng) && lng != null) {
latLng = tbMap.map.createLatLng(lat, lng);
if (i == 0 || !latLngs[latLngs.length - 1].equals(latLng)) {
latLngs.push(latLng);
}
}
}
if (latLngs.length > 0) {
var markerLocation = latLngs[latLngs.length - 1];
if (!location.marker) {
@ -308,6 +310,7 @@ export default class TbMapWidgetV2 {
// Create or update marker
lat = latData[latData.length - 1][1];
lng = lngData[lngData.length - 1][1];
if (angular.isDefined(lat) && lat != null && angular.isDefined(lng) && lng != null) {
latLng = tbMap.map.createLatLng(lat, lng);
if (!location.marker) {
location.marker = tbMap.map.createMarker(latLng, location.settings,
@ -325,9 +328,12 @@ export default class TbMapWidgetV2 {
}
}
}
}
if (location.marker) {
updateLocationStyle(location, dataMap);
}
}
}
return locationChanged;
}