Commit 69a0b74c6b066a37f480b27db1e9b48d9d264c94

Authored by Igor Kulikov
1 parent 8a37cf0d

TB-63: Improve alarms widget. Introduce auto-fill height setting for dashboard layout.

@@ -31,7 +31,7 @@ @@ -31,7 +31,7 @@
31 on-unassign-from-customer="vm.unassignFromCustomer(event, vm.grid.detailsConfig.currentItem, isPublic)" 31 on-unassign-from-customer="vm.unassignFromCustomer(event, vm.grid.detailsConfig.currentItem, isPublic)"
32 on-delete-asset="vm.grid.deleteItem(event, vm.grid.detailsConfig.currentItem)"></tb-asset> 32 on-delete-asset="vm.grid.deleteItem(event, vm.grid.detailsConfig.currentItem)"></tb-asset>
33 </md-tab> 33 </md-tab>
34 - <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" label="{{ 'attribute.attributes' | translate }}"> 34 + <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" md-on-select="vm.grid.triggerResize()" label="{{ 'attribute.attributes' | translate }}">
35 <tb-attribute-table flex 35 <tb-attribute-table flex
36 entity-id="vm.grid.operatingItem().id.id" 36 entity-id="vm.grid.operatingItem().id.id"
37 entity-type="{{vm.types.entityType.asset}}" 37 entity-type="{{vm.types.entityType.asset}}"
@@ -39,7 +39,7 @@ @@ -39,7 +39,7 @@
39 default-attribute-scope="{{vm.types.attributesScope.server.value}}"> 39 default-attribute-scope="{{vm.types.attributesScope.server.value}}">
40 </tb-attribute-table> 40 </tb-attribute-table>
41 </md-tab> 41 </md-tab>
42 - <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" label="{{ 'attribute.latest-telemetry' | translate }}"> 42 + <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" md-on-select="vm.grid.triggerResize()" label="{{ 'attribute.latest-telemetry' | translate }}">
43 <tb-attribute-table flex 43 <tb-attribute-table flex
44 entity-id="vm.grid.operatingItem().id.id" 44 entity-id="vm.grid.operatingItem().id.id"
45 entity-type="{{vm.types.entityType.asset}}" 45 entity-type="{{vm.types.entityType.asset}}"
@@ -48,19 +48,19 @@ @@ -48,19 +48,19 @@
48 disable-attribute-scope-selection="true"> 48 disable-attribute-scope-selection="true">
49 </tb-attribute-table> 49 </tb-attribute-table>
50 </md-tab> 50 </md-tab>
51 - <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" label="{{ 'alarm.alarms' | translate }}"> 51 + <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" md-on-select="vm.grid.triggerResize()" label="{{ 'alarm.alarms' | translate }}">
52 <tb-alarm-table flex entity-type="vm.types.entityType.asset" 52 <tb-alarm-table flex entity-type="vm.types.entityType.asset"
53 entity-id="vm.grid.operatingItem().id.id"> 53 entity-id="vm.grid.operatingItem().id.id">
54 </tb-alarm-table> 54 </tb-alarm-table>
55 </md-tab> 55 </md-tab>
56 - <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" label="{{ 'asset.events' | translate }}"> 56 + <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" md-on-select="vm.grid.triggerResize()" label="{{ 'asset.events' | translate }}">
57 <tb-event-table flex entity-type="vm.types.entityType.asset" 57 <tb-event-table flex entity-type="vm.types.entityType.asset"
58 entity-id="vm.grid.operatingItem().id.id" 58 entity-id="vm.grid.operatingItem().id.id"
59 tenant-id="vm.grid.operatingItem().tenantId.id" 59 tenant-id="vm.grid.operatingItem().tenantId.id"
60 default-event-type="{{vm.types.eventType.error.value}}"> 60 default-event-type="{{vm.types.eventType.error.value}}">
61 </tb-event-table> 61 </tb-event-table>
62 </md-tab> 62 </md-tab>
63 - <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" label="{{ 'relation.relations' | translate }}"> 63 + <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" md-on-select="vm.grid.triggerResize()" label="{{ 'relation.relations' | translate }}">
64 <tb-relation-table flex 64 <tb-relation-table flex
65 entity-id="vm.grid.operatingItem().id.id" 65 entity-id="vm.grid.operatingItem().id.id"
66 entity-type="{{vm.types.entityType.asset}}"> 66 entity-type="{{vm.types.entityType.asset}}">
@@ -394,7 +394,6 @@ export default angular.module('thingsboard.types', []) @@ -394,7 +394,6 @@ export default angular.module('thingsboard.types', [])
394 cards: "cards" 394 cards: "cards"
395 }, 395 },
396 translate: { 396 translate: {
397 - dashboardStatePrefix: "dashboardState.state.",  
398 customTranslationsPrefix: "custom." 397 customTranslationsPrefix: "custom."
399 } 398 }
400 } 399 }
@@ -135,7 +135,8 @@ function Utils($mdColorPalette, $rootScope, $window, $translate, types) { @@ -135,7 +135,8 @@ function Utils($mdColorPalette, $rootScope, $window, $translate, types) {
135 isLocalUrl: isLocalUrl, 135 isLocalUrl: isLocalUrl,
136 validateDatasources: validateDatasources, 136 validateDatasources: validateDatasources,
137 createKey: createKey, 137 createKey: createKey,
138 - createLabelFromDatasource: createLabelFromDatasource 138 + createLabelFromDatasource: createLabelFromDatasource,
  139 + insertVariable: insertVariable
139 } 140 }
140 141
141 return service; 142 return service;
@@ -407,4 +408,18 @@ function Utils($mdColorPalette, $rootScope, $window, $translate, types) { @@ -407,4 +408,18 @@ function Utils($mdColorPalette, $rootScope, $window, $translate, types) {
407 return label; 408 return label;
408 } 409 }
409 410
  411 + function insertVariable(pattern, name, value) {
  412 + var result = angular.copy(pattern);
  413 + var match = varsRegex.exec(pattern);
  414 + while (match !== null) {
  415 + var variable = match[0];
  416 + var variableName = match[1];
  417 + if (variableName === name) {
  418 + result = result.split(variable).join(value);
  419 + }
  420 + match = varsRegex.exec(pattern);
  421 + }
  422 + return result;
  423 + }
  424 +
410 } 425 }
@@ -58,6 +58,7 @@ function Dashboard() { @@ -58,6 +58,7 @@ function Dashboard() {
58 columns: '=', 58 columns: '=',
59 margins: '=', 59 margins: '=',
60 isEdit: '=', 60 isEdit: '=',
  61 + autofillHeight: '=',
61 isMobile: '=', 62 isMobile: '=',
62 isMobileDisabled: '=?', 63 isMobileDisabled: '=?',
63 isEditActionEnabled: '=', 64 isEditActionEnabled: '=',
@@ -102,6 +103,8 @@ function DashboardController($scope, $rootScope, $element, $timeout, $mdMedia, $ @@ -102,6 +103,8 @@ function DashboardController($scope, $rootScope, $element, $timeout, $mdMedia, $
102 103
103 vm.isMobileDisabled = angular.isDefined(vm.isMobileDisabled) ? vm.isMobileDisabled : false; 104 vm.isMobileDisabled = angular.isDefined(vm.isMobileDisabled) ? vm.isMobileDisabled : false;
104 105
  106 + vm.isMobileSize = false;
  107 +
105 if (!('dashboardTimewindow' in vm)) { 108 if (!('dashboardTimewindow' in vm)) {
106 vm.dashboardTimewindow = timeService.defaultTimewindow(); 109 vm.dashboardTimewindow = timeService.defaultTimewindow();
107 } 110 }
@@ -178,6 +181,7 @@ function DashboardController($scope, $rootScope, $element, $timeout, $mdMedia, $ @@ -178,6 +181,7 @@ function DashboardController($scope, $rootScope, $element, $timeout, $mdMedia, $
178 vm.widgetPadding = widgetPadding; 181 vm.widgetPadding = widgetPadding;
179 vm.showWidgetTitle = showWidgetTitle; 182 vm.showWidgetTitle = showWidgetTitle;
180 vm.showWidgetTitlePanel = showWidgetTitlePanel; 183 vm.showWidgetTitlePanel = showWidgetTitlePanel;
  184 + vm.showWidgetActions = showWidgetActions;
181 vm.widgetTitleStyle = widgetTitleStyle; 185 vm.widgetTitleStyle = widgetTitleStyle;
182 vm.widgetTitle = widgetTitle; 186 vm.widgetTitle = widgetTitle;
183 vm.widgetActions = widgetActions; 187 vm.widgetActions = widgetActions;
@@ -271,12 +275,15 @@ function DashboardController($scope, $rootScope, $element, $timeout, $mdMedia, $ @@ -271,12 +275,15 @@ function DashboardController($scope, $rootScope, $element, $timeout, $mdMedia, $
271 275
272 function updateMobileOpts() { 276 function updateMobileOpts() {
273 var isMobileDisabled = vm.isMobileDisabled === true; 277 var isMobileDisabled = vm.isMobileDisabled === true;
274 - var isMobile = vm.isMobile === true && !isMobileDisabled; 278 + var isMobile = vm.isMobile === true && !isMobileDisabled || vm.autofillHeight;
275 var mobileBreakPoint = isMobileDisabled ? 0 : (isMobile ? 20000 : 960); 279 var mobileBreakPoint = isMobileDisabled ? 0 : (isMobile ? 20000 : 960);
  280 +
276 if (!isMobile && !isMobileDisabled) { 281 if (!isMobile && !isMobileDisabled) {
277 isMobile = !$mdMedia('gt-sm'); 282 isMobile = !$mdMedia('gt-sm');
278 } 283 }
279 - var rowHeight = isMobile ? 70 : 'match'; 284 +
  285 + var rowHeight = detectRowSize(isMobile);
  286 +
280 if (vm.gridsterOpts.isMobile != isMobile) { 287 if (vm.gridsterOpts.isMobile != isMobile) {
281 vm.gridsterOpts.isMobile = isMobile; 288 vm.gridsterOpts.isMobile = isMobile;
282 vm.gridsterOpts.mobileModeEnabled = isMobile; 289 vm.gridsterOpts.mobileModeEnabled = isMobile;
@@ -287,6 +294,17 @@ function DashboardController($scope, $rootScope, $element, $timeout, $mdMedia, $ @@ -287,6 +294,17 @@ function DashboardController($scope, $rootScope, $element, $timeout, $mdMedia, $
287 if (vm.gridsterOpts.rowHeight != rowHeight) { 294 if (vm.gridsterOpts.rowHeight != rowHeight) {
288 vm.gridsterOpts.rowHeight = rowHeight; 295 vm.gridsterOpts.rowHeight = rowHeight;
289 } 296 }
  297 +
  298 + vm.isMobileSize = checkIsMobileSize();
  299 + }
  300 +
  301 + function checkIsMobileSize() {
  302 + var isMobileDisabled = vm.isMobileDisabled === true;
  303 + var isMobileSize = vm.isMobile === true && !isMobileDisabled;
  304 + if (!isMobileSize && !isMobileDisabled) {
  305 + isMobileSize = !$mdMedia('gt-sm');
  306 + }
  307 + return isMobileSize;
290 } 308 }
291 309
292 $scope.$watch(function() { return $mdMedia('gt-sm'); }, function() { 310 $scope.$watch(function() { return $mdMedia('gt-sm'); }, function() {
@@ -297,6 +315,34 @@ function DashboardController($scope, $rootScope, $element, $timeout, $mdMedia, $ @@ -297,6 +315,34 @@ function DashboardController($scope, $rootScope, $element, $timeout, $mdMedia, $
297 updateMobileOpts(); 315 updateMobileOpts();
298 }); 316 });
299 317
  318 + $scope.$watch('vm.autofillHeight', function () {
  319 + if (vm.autofillHeight) {
  320 + //if (gridsterParent.height()) {
  321 + // updateMobileOpts();
  322 + //} else {
  323 + if ($scope.parentHeighWatcher) {
  324 + $scope.parentHeighWatcher();
  325 + }
  326 + if (gridsterParent.height()) {
  327 + updateMobileOpts();
  328 + }
  329 + $scope.parentHeighWatcher = $scope.$watch(function() { return gridsterParent.height(); },
  330 + function(newHeight) {
  331 + if (newHeight) {
  332 + updateMobileOpts();
  333 + }
  334 + }
  335 + );
  336 + } else {
  337 + if ($scope.parentHeighWatcher) {
  338 + $scope.parentHeighWatcher();
  339 + $scope.parentHeighWatcher = null;
  340 + }
  341 +
  342 + updateMobileOpts();
  343 + }
  344 + });
  345 +
300 $scope.$watch('vm.isMobileDisabled', function () { 346 $scope.$watch('vm.isMobileDisabled', function () {
301 updateMobileOpts(); 347 updateMobileOpts();
302 }); 348 });
@@ -333,6 +379,12 @@ function DashboardController($scope, $rootScope, $element, $timeout, $mdMedia, $ @@ -333,6 +379,12 @@ function DashboardController($scope, $rootScope, $element, $timeout, $mdMedia, $
333 $scope.$broadcast('toggleDashboardEditMode', vm.isEdit); 379 $scope.$broadcast('toggleDashboardEditMode', vm.isEdit);
334 }); 380 });
335 381
  382 + $scope.$watch('vm.isMobileSize', function (newVal, prevVal) {
  383 + if (!angular.equals(newVal, prevVal)) {
  384 + $scope.$broadcast('mobileModeChanged', vm.isMobileSize);
  385 + }
  386 + });
  387 +
336 $scope.$on('gridster-resized', function (event, sizes, theGridster) { 388 $scope.$on('gridster-resized', function (event, sizes, theGridster) {
337 if (checkIsLocalGridsterElement(theGridster)) { 389 if (checkIsLocalGridsterElement(theGridster)) {
338 vm.gridster = theGridster; 390 vm.gridster = theGridster;
@@ -345,13 +397,12 @@ function DashboardController($scope, $rootScope, $element, $timeout, $mdMedia, $ @@ -345,13 +397,12 @@ function DashboardController($scope, $rootScope, $element, $timeout, $mdMedia, $
345 $scope.$on('gridster-mobile-changed', function (event, theGridster) { 397 $scope.$on('gridster-mobile-changed', function (event, theGridster) {
346 if (checkIsLocalGridsterElement(theGridster)) { 398 if (checkIsLocalGridsterElement(theGridster)) {
347 vm.gridster = theGridster; 399 vm.gridster = theGridster;
348 - var rowHeight = vm.gridster.isMobile ? 70 : 'match'; 400 + var rowHeight = detectRowSize(vm.gridster.isMobile);
349 if (vm.gridsterOpts.rowHeight != rowHeight) { 401 if (vm.gridsterOpts.rowHeight != rowHeight) {
350 vm.gridsterOpts.rowHeight = rowHeight; 402 vm.gridsterOpts.rowHeight = rowHeight;
351 updateGridsterParams(); 403 updateGridsterParams();
352 } 404 }
353 -  
354 - $scope.$broadcast('mobileModeChanged', vm.gridster.isMobile); 405 + vm.isMobileSize = checkIsMobileSize();
355 406
356 //TODO: widgets visibility 407 //TODO: widgets visibility
357 /*$timeout(function () { 408 /*$timeout(function () {
@@ -360,6 +411,21 @@ function DashboardController($scope, $rootScope, $element, $timeout, $mdMedia, $ @@ -360,6 +411,21 @@ function DashboardController($scope, $rootScope, $element, $timeout, $mdMedia, $
360 } 411 }
361 }); 412 });
362 413
  414 + function detectRowSize(isMobile) {
  415 + var rowHeight = isMobile ? 70 : 'match';
  416 + if (vm.autofillHeight) {
  417 + var viewportHeight = gridsterParent.height();
  418 + var totalRows = 0;
  419 + for (var i = 0; i < vm.widgets.length; i++) {
  420 + var w = vm.widgets[i];
  421 + var sizeY = widgetSizeY(w);
  422 + totalRows += sizeY;
  423 + }
  424 + rowHeight = (viewportHeight - (vm.gridsterOpts.margins[1])) / totalRows;
  425 + }
  426 + return rowHeight;
  427 + }
  428 +
363 function widgetOrder(widget) { 429 function widgetOrder(widget) {
364 var order; 430 var order;
365 if (vm.widgetLayouts && vm.widgetLayouts[widget.id]) { 431 if (vm.widgetLayouts && vm.widgetLayouts[widget.id]) {
@@ -650,7 +716,7 @@ function DashboardController($scope, $rootScope, $element, $timeout, $mdMedia, $ @@ -650,7 +716,7 @@ function DashboardController($scope, $rootScope, $element, $timeout, $mdMedia, $
650 } 716 }
651 717
652 function widgetSizeY(widget) { 718 function widgetSizeY(widget) {
653 - if (vm.gridsterOpts.isMobile) { 719 + if (vm.gridsterOpts.isMobile && !vm.autofillHeight) {
654 var mobileHeight; 720 var mobileHeight;
655 if (vm.widgetLayouts && vm.widgetLayouts[widget.id]) { 721 if (vm.widgetLayouts && vm.widgetLayouts[widget.id]) {
656 mobileHeight = vm.widgetLayouts[widget.id].mobileHeight; 722 mobileHeight = vm.widgetLayouts[widget.id].mobileHeight;
@@ -673,7 +739,7 @@ function DashboardController($scope, $rootScope, $element, $timeout, $mdMedia, $ @@ -673,7 +739,7 @@ function DashboardController($scope, $rootScope, $element, $timeout, $mdMedia, $
673 } 739 }
674 740
675 function setWidgetSizeY(widget, sizeY) { 741 function setWidgetSizeY(widget, sizeY) {
676 - if (!vm.gridsterOpts.isMobile) { 742 + if (!vm.gridsterOpts.isMobile && !vm.autofillHeight) {
677 if (vm.widgetLayouts && vm.widgetLayouts[widget.id]) { 743 if (vm.widgetLayouts && vm.widgetLayouts[widget.id]) {
678 vm.widgetLayouts[widget.id].sizeY = sizeY; 744 vm.widgetLayouts[widget.id].sizeY = sizeY;
679 } else { 745 } else {
@@ -759,6 +825,15 @@ function DashboardController($scope, $rootScope, $element, $timeout, $mdMedia, $ @@ -759,6 +825,15 @@ function DashboardController($scope, $rootScope, $element, $timeout, $mdMedia, $
759 } 825 }
760 } 826 }
761 827
  828 + function showWidgetActions(widget) {
  829 + var ctx = widgetContext(widget);
  830 + if (ctx && ctx.hideTitlePanel) {
  831 + return false;
  832 + } else {
  833 + return true;
  834 + }
  835 + }
  836 +
762 function widgetTitleStyle(widget) { 837 function widgetTitleStyle(widget) {
763 if (angular.isDefined(widget.config.titleStyle)) { 838 if (angular.isDefined(widget.config.titleStyle)) {
764 return widget.config.titleStyle; 839 return widget.config.titleStyle;
@@ -23,7 +23,7 @@ @@ -23,7 +23,7 @@
23 </md-content> 23 </md-content>
24 <md-menu md-position-mode="target target" tb-mousepoint-menu> 24 <md-menu md-position-mode="target target" tb-mousepoint-menu>
25 <md-content id="gridster-parent" class="tb-dashboard-content" flex layout-wrap ng-click="" tb-contextmenu="vm.openDashboardContextMenu($event, $mdOpenMousepointMenu)"> 25 <md-content id="gridster-parent" class="tb-dashboard-content" flex layout-wrap ng-click="" tb-contextmenu="vm.openDashboardContextMenu($event, $mdOpenMousepointMenu)">
26 - <div ng-class="vm.dashboardClass" id="gridster-background" style="height: auto; min-height: 100%;"> 26 + <div ng-class="vm.dashboardClass" id="gridster-background" style="height: auto; min-height: 100%; display: inline;">
27 <div id="gridster-child" gridster="vm.gridsterOpts"> 27 <div id="gridster-child" gridster="vm.gridsterOpts">
28 <ul> 28 <ul>
29 <li gridster-item="vm.widgetItemMap" class="tb-noselect" ng-repeat="widget in vm.widgets"> 29 <li gridster-item="vm.widgetItemMap" class="tb-noselect" ng-repeat="widget in vm.widgets">
@@ -50,7 +50,7 @@ @@ -50,7 +50,7 @@
50 <span ng-show="vm.showWidgetTitle(widget)" ng-style="vm.widgetTitleStyle(widget)" class="md-subhead">{{vm.widgetTitle(widget)}}</span> 50 <span ng-show="vm.showWidgetTitle(widget)" ng-style="vm.widgetTitleStyle(widget)" class="md-subhead">{{vm.widgetTitle(widget)}}</span>
51 <tb-timewindow aggregation="{{vm.hasAggregation(widget)}}" ng-if="vm.hasTimewindow(widget)" ng-model="widget.config.timewindow"></tb-timewindow> 51 <tb-timewindow aggregation="{{vm.hasAggregation(widget)}}" ng-if="vm.hasTimewindow(widget)" ng-model="widget.config.timewindow"></tb-timewindow>
52 </div> 52 </div>
53 - <div class="tb-widget-actions" layout="row" layout-align="start center" ng-show="vm.showWidgetTitlePanel(widget)" tb-mousedown="$event.stopPropagation()"> 53 + <div class="tb-widget-actions" layout="row" layout-align="start center" ng-show="vm.showWidgetActions(widget)" tb-mousedown="$event.stopPropagation()">
54 <md-button ng-repeat="action in vm.widgetActions(widget)" 54 <md-button ng-repeat="action in vm.widgetActions(widget)"
55 aria-label="{{ action.name | translate }}" 55 aria-label="{{ action.name | translate }}"
56 ng-show="!vm.isEdit && action.show" 56 ng-show="!vm.isEdit && action.show"
@@ -103,6 +103,7 @@ @@ -103,6 +103,7 @@
103 aliasController: vm.aliasController, 103 aliasController: vm.aliasController,
104 stateController: vm.stateController, 104 stateController: vm.stateController,
105 isEdit: vm.isEdit, 105 isEdit: vm.isEdit,
  106 + isMobile: vm.isMobileSize,
106 stDiff: vm.stDiff, 107 stDiff: vm.stDiff,
107 dashboardTimewindow: vm.dashboardTimewindow, 108 dashboardTimewindow: vm.dashboardTimewindow,
108 dashboardTimewindowApi: vm.dashboardTimewindowApi }"> 109 dashboardTimewindowApi: vm.dashboardTimewindowApi }">
@@ -124,7 +124,7 @@ function Grid() { @@ -124,7 +124,7 @@ function Grid() {
124 } 124 }
125 125
126 /*@ngInject*/ 126 /*@ngInject*/
127 -function GridController($scope, $state, $mdDialog, $document, $q, $timeout, $translate, $mdMedia, $templateCache) { 127 +function GridController($scope, $state, $mdDialog, $document, $q, $timeout, $translate, $mdMedia, $templateCache, $window) {
128 128
129 var vm = this; 129 var vm = this;
130 130
@@ -155,6 +155,7 @@ function GridController($scope, $state, $mdDialog, $document, $q, $timeout, $tra @@ -155,6 +155,7 @@ function GridController($scope, $state, $mdDialog, $document, $q, $timeout, $tra
155 vm.refreshList = refreshList; 155 vm.refreshList = refreshList;
156 vm.saveItem = saveItem; 156 vm.saveItem = saveItem;
157 vm.toggleItemSelection = toggleItemSelection; 157 vm.toggleItemSelection = toggleItemSelection;
  158 + vm.triggerResize = triggerResize;
158 159
159 $scope.$watch(function () { 160 $scope.$watch(function () {
160 return $mdMedia('xs') || $mdMedia('sm'); 161 return $mdMedia('xs') || $mdMedia('sm');
@@ -600,6 +601,11 @@ function GridController($scope, $state, $mdDialog, $document, $q, $timeout, $tra @@ -600,6 +601,11 @@ function GridController($scope, $state, $mdDialog, $document, $q, $timeout, $tra
600 } 601 }
601 } 602 }
602 603
  604 + function triggerResize() {
  605 + var w = angular.element($window);
  606 + w.triggerHandler('resize');
  607 + }
  608 +
603 function moveToTop() { 609 function moveToTop() {
604 moveToIndex(0, true); 610 moveToIndex(0, true);
605 } 611 }
@@ -21,7 +21,7 @@ import Subscription from '../api/subscription'; @@ -21,7 +21,7 @@ import Subscription from '../api/subscription';
21 21
22 /*@ngInject*/ 22 /*@ngInject*/
23 export default function WidgetController($scope, $timeout, $window, $element, $q, $log, $injector, $filter, $compile, tbRaf, types, utils, timeService, 23 export default function WidgetController($scope, $timeout, $window, $element, $q, $log, $injector, $filter, $compile, tbRaf, types, utils, timeService,
24 - datasourceService, alarmService, entityService, deviceService, visibleRect, isEdit, stDiff, dashboardTimewindow, 24 + datasourceService, alarmService, entityService, deviceService, visibleRect, isEdit, isMobile, stDiff, dashboardTimewindow,
25 dashboardTimewindowApi, widget, aliasController, stateController, widgetInfo, widgetType) { 25 dashboardTimewindowApi, widget, aliasController, stateController, widgetInfo, widgetType) {
26 26
27 var vm = this; 27 var vm = this;
@@ -50,7 +50,7 @@ export default function WidgetController($scope, $timeout, $window, $element, $q @@ -50,7 +50,7 @@ export default function WidgetController($scope, $timeout, $window, $element, $q
50 height: 0, 50 height: 0,
51 hideTitlePanel: false, 51 hideTitlePanel: false,
52 isEdit: isEdit, 52 isEdit: isEdit,
53 - isMobile: false, 53 + isMobile: isMobile,
54 widgetConfig: widget.config, 54 widgetConfig: widget.config,
55 settings: widget.config.settings, 55 settings: widget.config.settings,
56 units: widget.config.units || '', 56 units: widget.config.units || '',
@@ -618,7 +618,6 @@ export default function WidgetController($scope, $timeout, $window, $element, $q @@ -618,7 +618,6 @@ export default function WidgetController($scope, $timeout, $window, $element, $q
618 618
619 function gridsterItemInitialized(item) { 619 function gridsterItemInitialized(item) {
620 if (item && item.gridster) { 620 if (item && item.gridster) {
621 - widgetContext.isMobile = item.gridster.isMobile;  
622 gridsterItemInited = true; 621 gridsterItemInited = true;
623 onInit(); 622 onInit();
624 // gridsterItemElement = $(item.$element); 623 // gridsterItemElement = $(item.$element);
@@ -31,7 +31,7 @@ @@ -31,7 +31,7 @@
31 on-manage-dashboards="vm.openCustomerDashboards(event, vm.grid.detailsConfig.currentItem)" 31 on-manage-dashboards="vm.openCustomerDashboards(event, vm.grid.detailsConfig.currentItem)"
32 on-delete-customer="vm.grid.deleteItem(event, vm.grid.detailsConfig.currentItem)"></tb-customer> 32 on-delete-customer="vm.grid.deleteItem(event, vm.grid.detailsConfig.currentItem)"></tb-customer>
33 </md-tab> 33 </md-tab>
34 - <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" label="{{ 'attribute.attributes' | translate }}"> 34 + <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" md-on-select="vm.grid.triggerResize()" label="{{ 'attribute.attributes' | translate }}">
35 <tb-attribute-table flex 35 <tb-attribute-table flex
36 entity-id="vm.grid.operatingItem().id.id" 36 entity-id="vm.grid.operatingItem().id.id"
37 entity-type="{{vm.types.entityType.customer}}" 37 entity-type="{{vm.types.entityType.customer}}"
@@ -39,7 +39,7 @@ @@ -39,7 +39,7 @@
39 default-attribute-scope="{{vm.types.attributesScope.server.value}}"> 39 default-attribute-scope="{{vm.types.attributesScope.server.value}}">
40 </tb-attribute-table> 40 </tb-attribute-table>
41 </md-tab> 41 </md-tab>
42 - <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" label="{{ 'attribute.latest-telemetry' | translate }}"> 42 + <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" md-on-select="vm.grid.triggerResize()" label="{{ 'attribute.latest-telemetry' | translate }}">
43 <tb-attribute-table flex 43 <tb-attribute-table flex
44 entity-id="vm.grid.operatingItem().id.id" 44 entity-id="vm.grid.operatingItem().id.id"
45 entity-type="{{vm.types.entityType.customer}}" 45 entity-type="{{vm.types.entityType.customer}}"
@@ -48,19 +48,19 @@ @@ -48,19 +48,19 @@
48 disable-attribute-scope-selection="true"> 48 disable-attribute-scope-selection="true">
49 </tb-attribute-table> 49 </tb-attribute-table>
50 </md-tab> 50 </md-tab>
51 - <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" label="{{ 'alarm.alarms' | translate }}"> 51 + <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" md-on-select="vm.grid.triggerResize()" label="{{ 'alarm.alarms' | translate }}">
52 <tb-alarm-table flex entity-type="vm.types.entityType.customer" 52 <tb-alarm-table flex entity-type="vm.types.entityType.customer"
53 entity-id="vm.grid.operatingItem().id.id"> 53 entity-id="vm.grid.operatingItem().id.id">
54 </tb-alarm-table> 54 </tb-alarm-table>
55 </md-tab> 55 </md-tab>
56 - <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" label="{{ 'customer.events' | translate }}"> 56 + <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" md-on-select="vm.grid.triggerResize()" label="{{ 'customer.events' | translate }}">
57 <tb-event-table flex entity-type="vm.types.entityType.customer" 57 <tb-event-table flex entity-type="vm.types.entityType.customer"
58 entity-id="vm.grid.operatingItem().id.id" 58 entity-id="vm.grid.operatingItem().id.id"
59 tenant-id="vm.grid.operatingItem().tenantId.id" 59 tenant-id="vm.grid.operatingItem().tenantId.id"
60 default-event-type="{{vm.types.eventType.error.value}}"> 60 default-event-type="{{vm.types.eventType.error.value}}">
61 </tb-event-table> 61 </tb-event-table>
62 </md-tab> 62 </md-tab>
63 - <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" label="{{ 'relation.relations' | translate }}"> 63 + <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" md-on-select="vm.grid.triggerResize()" label="{{ 'relation.relations' | translate }}">
64 <tb-relation-table flex 64 <tb-relation-table flex
65 entity-id="vm.grid.operatingItem().id.id" 65 entity-id="vm.grid.operatingItem().id.id"
66 entity-type="{{vm.types.entityType.customer}}"> 66 entity-type="{{vm.types.entityType.customer}}">
@@ -68,6 +68,7 @@ export default function DashboardSettingsController($scope, $mdDialog, statesCon @@ -68,6 +68,7 @@ export default function DashboardSettingsController($scope, $mdDialog, statesCon
68 vm.gridSettings.color = vm.gridSettings.color || 'rgba(0,0,0,0.870588)'; 68 vm.gridSettings.color = vm.gridSettings.color || 'rgba(0,0,0,0.870588)';
69 vm.gridSettings.columns = vm.gridSettings.columns || 24; 69 vm.gridSettings.columns = vm.gridSettings.columns || 24;
70 vm.gridSettings.margins = vm.gridSettings.margins || [10, 10]; 70 vm.gridSettings.margins = vm.gridSettings.margins || [10, 10];
  71 + vm.gridSettings.autoFillHeight = angular.isDefined(vm.gridSettings.autoFillHeight) ? vm.gridSettings.autoFillHeight : false;
71 vm.hMargin = vm.gridSettings.margins[0]; 72 vm.hMargin = vm.gridSettings.margins[0];
72 vm.vMargin = vm.gridSettings.margins[1]; 73 vm.vMargin = vm.gridSettings.margins[1];
73 vm.gridSettings.backgroundSizeMode = vm.gridSettings.backgroundSizeMode || '100%'; 74 vm.gridSettings.backgroundSizeMode = vm.gridSettings.backgroundSizeMode || '100%';
@@ -121,6 +121,9 @@ @@ -121,6 +121,9 @@
121 </div> 121 </div>
122 </md-input-container> 122 </md-input-container>
123 </div> 123 </div>
  124 + <md-checkbox flex aria-label="{{ 'dashboard.autofill-height' | translate }}"
  125 + ng-model="vm.gridSettings.autoFillHeight">{{ 'dashboard.autofill-height' | translate }}
  126 + </md-checkbox>
124 <div flex 127 <div flex
125 ng-required="false" 128 ng-required="false"
126 md-color-picker 129 md-color-picker
@@ -49,6 +49,7 @@ @@ -49,6 +49,7 @@
49 state-controller="vm.dashboardCtx.stateController" 49 state-controller="vm.dashboardCtx.stateController"
50 dashboard-timewindow="vm.dashboardCtx.dashboardTimewindow" 50 dashboard-timewindow="vm.dashboardCtx.dashboardTimewindow"
51 is-edit="vm.isEdit" 51 is-edit="vm.isEdit"
  52 + autofill-height="vm.layoutCtx.gridSettings.autoFillHeight && !vm.isEdit"
52 is-mobile="vm.isMobile" 53 is-mobile="vm.isMobile"
53 is-mobile-disabled="vm.widgetEditMode" 54 is-mobile-disabled="vm.widgetEditMode"
54 is-edit-action-enabled="vm.isEdit" 55 is-edit-action-enabled="vm.isEdit"
@@ -53,12 +53,6 @@ export default function DashboardStateDialogController($scope, $mdDialog, $filte @@ -53,12 +53,6 @@ export default function DashboardStateDialogController($scope, $mdDialog, $filte
53 if (!vm.stateIdTouched && vm.isAdd) { 53 if (!vm.stateIdTouched && vm.isAdd) {
54 vm.state.id = vm.state.name.toLowerCase().replace(/\W/g,"_"); 54 vm.state.id = vm.state.name.toLowerCase().replace(/\W/g,"_");
55 } 55 }
56 - var result = $filter('filter')(vm.allStates, {name: vm.state.name}, true);  
57 - if (result && result.length && result[0].id !== vm.prevStateId) {  
58 - $scope.theForm.name.$setValidity('stateExists', false);  
59 - } else {  
60 - $scope.theForm.name.$setValidity('stateExists', true);  
61 - }  
62 } 56 }
63 57
64 function checkStateId() { 58 function checkStateId() {
@@ -37,18 +37,15 @@ @@ -37,18 +37,15 @@
37 <input name="name" required ng-model="vm.state.name"> 37 <input name="name" required ng-model="vm.state.name">
38 <div ng-messages="theForm.name.$error"> 38 <div ng-messages="theForm.name.$error">
39 <div ng-message="required" translate>dashboard.state-name-required</div> 39 <div ng-message="required" translate>dashboard.state-name-required</div>
40 - <div ng-message="stateExists" translate>dashboard.state-name-exists</div>  
41 </div> 40 </div>
42 </md-input-container> 41 </md-input-container>
43 <md-input-container class="md-block"> 42 <md-input-container class="md-block">
44 <label translate>dashboard.state-id</label> 43 <label translate>dashboard.state-id</label>
45 - <input name="stateId" ng-model="vm.state.id"  
46 - ng-change="vm.stateIdTouched = true"  
47 - ng-pattern="/^[a-zA-Z0-9_]*$/"> 44 + <input name="stateId" required ng-model="vm.state.id"
  45 + ng-change="vm.stateIdTouched = true">
48 <div ng-messages="theForm.stateId.$error"> 46 <div ng-messages="theForm.stateId.$error">
49 <div ng-message="required" translate>dashboard.state-id-required</div> 47 <div ng-message="required" translate>dashboard.state-id-required</div>
50 <div ng-message="stateExists" translate>dashboard.state-id-exists</div> 48 <div ng-message="stateExists" translate>dashboard.state-id-exists</div>
51 - <div ng-message="pattern" translate>dashboard.invalid-state-id-format</div>  
52 </div> 49 </div>
53 </md-input-container> 50 </md-input-container>
54 <md-checkbox flex aria-label="{{ 'dashboard.is-root-state' | translate }}" 51 <md-checkbox flex aria-label="{{ 'dashboard.is-root-state' | translate }}"
@@ -97,10 +97,10 @@ export default function DefaultStateController($scope, $location, $state, $state @@ -97,10 +97,10 @@ export default function DefaultStateController($scope, $location, $state, $state
97 97
98 function getStateName(id, state) { 98 function getStateName(id, state) {
99 var result = ''; 99 var result = '';
100 - var translationId = types.translate.dashboardStatePrefix + id; 100 + var translationId = types.translate.customTranslationsPrefix + state.name;
101 var translation = $translate.instant(translationId); 101 var translation = $translate.instant(translationId);
102 if (translation != translationId) { 102 if (translation != translationId) {
103 - result = translation; 103 + result = translation + '';
104 } else { 104 } else {
105 result = state.name; 105 result = state.name;
106 } 106 }
@@ -17,7 +17,7 @@ @@ -17,7 +17,7 @@
17 import './entity-state-controller.scss'; 17 import './entity-state-controller.scss';
18 18
19 /*@ngInject*/ 19 /*@ngInject*/
20 -export default function EntityStateController($scope, $location, $state, $stateParams, $q, $translate, types, dashboardUtils, entityService) { 20 +export default function EntityStateController($scope, $location, $state, $stateParams, $q, $translate, utils, types, dashboardUtils, entityService) {
21 21
22 var vm = this; 22 var vm = this;
23 23
@@ -106,18 +106,17 @@ export default function EntityStateController($scope, $location, $state, $stateP @@ -106,18 +106,17 @@ export default function EntityStateController($scope, $location, $state, $stateP
106 function getStateName(index) { 106 function getStateName(index) {
107 var result = ''; 107 var result = '';
108 if (vm.stateObject[index]) { 108 if (vm.stateObject[index]) {
  109 + var stateName = vm.states[vm.stateObject[index].id].name;
  110 + var translationId = types.translate.customTranslationsPrefix + stateName;
  111 + var translation = $translate.instant(translationId);
  112 + if (translation != translationId) {
  113 + stateName = translation + '';
  114 + }
109 var params = vm.stateObject[index].params; 115 var params = vm.stateObject[index].params;
110 if (params && params.entityName) { 116 if (params && params.entityName) {
111 - result = params.entityName; 117 + result = utils.insertVariable(stateName, 'entityName', params.entityName);
112 } else { 118 } else {
113 - var id = vm.stateObject[index].id;  
114 - var translationId = types.translate.dashboardStatePrefix + id;  
115 - var translation = $translate.instant(translationId);  
116 - if (translation != translationId) {  
117 - result = translation;  
118 - } else {  
119 - result = vm.states[vm.stateObject[index].id].name;  
120 - } 119 + result = stateName;
121 } 120 }
122 } 121 }
123 return result; 122 return result;
@@ -32,7 +32,7 @@ @@ -32,7 +32,7 @@
32 on-manage-credentials="vm.manageCredentials(event, vm.grid.detailsConfig.currentItem)" 32 on-manage-credentials="vm.manageCredentials(event, vm.grid.detailsConfig.currentItem)"
33 on-delete-device="vm.grid.deleteItem(event, vm.grid.detailsConfig.currentItem)"></tb-device> 33 on-delete-device="vm.grid.deleteItem(event, vm.grid.detailsConfig.currentItem)"></tb-device>
34 </md-tab> 34 </md-tab>
35 - <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" label="{{ 'attribute.attributes' | translate }}"> 35 + <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" md-on-select="vm.grid.triggerResize()" label="{{ 'attribute.attributes' | translate }}">
36 <tb-attribute-table flex 36 <tb-attribute-table flex
37 entity-id="vm.grid.operatingItem().id.id" 37 entity-id="vm.grid.operatingItem().id.id"
38 entity-type="{{vm.types.entityType.device}}" 38 entity-type="{{vm.types.entityType.device}}"
@@ -40,7 +40,7 @@ @@ -40,7 +40,7 @@
40 default-attribute-scope="{{vm.types.attributesScope.client.value}}"> 40 default-attribute-scope="{{vm.types.attributesScope.client.value}}">
41 </tb-attribute-table> 41 </tb-attribute-table>
42 </md-tab> 42 </md-tab>
43 - <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" label="{{ 'attribute.latest-telemetry' | translate }}"> 43 + <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" md-on-select="vm.grid.triggerResize()" label="{{ 'attribute.latest-telemetry' | translate }}">
44 <tb-attribute-table flex 44 <tb-attribute-table flex
45 entity-id="vm.grid.operatingItem().id.id" 45 entity-id="vm.grid.operatingItem().id.id"
46 entity-type="{{vm.types.entityType.device}}" 46 entity-type="{{vm.types.entityType.device}}"
@@ -49,19 +49,19 @@ @@ -49,19 +49,19 @@
49 disable-attribute-scope-selection="true"> 49 disable-attribute-scope-selection="true">
50 </tb-attribute-table> 50 </tb-attribute-table>
51 </md-tab> 51 </md-tab>
52 - <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" label="{{ 'alarm.alarms' | translate }}"> 52 + <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" md-on-select="vm.grid.triggerResize()" label="{{ 'alarm.alarms' | translate }}">
53 <tb-alarm-table flex entity-type="vm.types.entityType.device" 53 <tb-alarm-table flex entity-type="vm.types.entityType.device"
54 entity-id="vm.grid.operatingItem().id.id"> 54 entity-id="vm.grid.operatingItem().id.id">
55 </tb-alarm-table> 55 </tb-alarm-table>
56 </md-tab> 56 </md-tab>
57 - <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" label="{{ 'device.events' | translate }}"> 57 + <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" md-on-select="vm.grid.triggerResize()" label="{{ 'device.events' | translate }}">
58 <tb-event-table flex entity-type="vm.types.entityType.device" 58 <tb-event-table flex entity-type="vm.types.entityType.device"
59 entity-id="vm.grid.operatingItem().id.id" 59 entity-id="vm.grid.operatingItem().id.id"
60 tenant-id="vm.grid.operatingItem().tenantId.id" 60 tenant-id="vm.grid.operatingItem().tenantId.id"
61 default-event-type="{{vm.types.eventType.error.value}}"> 61 default-event-type="{{vm.types.eventType.error.value}}">
62 </tb-event-table> 62 </tb-event-table>
63 </md-tab> 63 </md-tab>
64 - <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" label="{{ 'relation.relations' | translate }}"> 64 + <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" md-on-select="vm.grid.triggerResize()" label="{{ 'relation.relations' | translate }}">
65 <tb-relation-table flex 65 <tb-relation-table flex
66 entity-id="vm.grid.operatingItem().id.id" 66 entity-id="vm.grid.operatingItem().id.id"
67 entity-type="{{vm.types.entityType.device}}"> 67 entity-type="{{vm.types.entityType.device}}">
@@ -431,6 +431,7 @@ export default angular.module('thingsboard.locale', []) @@ -431,6 +431,7 @@ export default angular.module('thingsboard.locale', [])
431 "vertical-margin-required": "Vertical margin value is required.", 431 "vertical-margin-required": "Vertical margin value is required.",
432 "min-vertical-margin-message": "Only 0 is allowed as minimum vertical margin value.", 432 "min-vertical-margin-message": "Only 0 is allowed as minimum vertical margin value.",
433 "max-vertical-margin-message": "Only 50 is allowed as maximum vertical margin value.", 433 "max-vertical-margin-message": "Only 50 is allowed as maximum vertical margin value.",
  434 + "autofill-height": "Auto fill layout height",
434 "display-title": "Display dashboard title", 435 "display-title": "Display dashboard title",
435 "toolbar-always-open": "Keep toolbar opened", 436 "toolbar-always-open": "Keep toolbar opened",
436 "title-color": "Title color", 437 "title-color": "Title color",
@@ -472,11 +473,9 @@ export default angular.module('thingsboard.locale', []) @@ -472,11 +473,9 @@ export default angular.module('thingsboard.locale', [])
472 "state": "Dashboard state", 473 "state": "Dashboard state",
473 "state-name": "Name", 474 "state-name": "Name",
474 "state-name-required": "Dashboard state name is required.", 475 "state-name-required": "Dashboard state name is required.",
475 - "state-name-exists": "Dashboard state with the same name is already exists.",  
476 "state-id": "State Id", 476 "state-id": "State Id",
477 "state-id-required": "Dashboard state id is required.", 477 "state-id-required": "Dashboard state id is required.",
478 "state-id-exists": "Dashboard state with the same id is already exists.", 478 "state-id-exists": "Dashboard state with the same id is already exists.",
479 - "invalid-state-id-format": "Only alphanumeric characters and underscore are allowed.",  
480 "is-root-state": "Root state", 479 "is-root-state": "Root state",
481 "delete-state-title": "Delete dashboard state", 480 "delete-state-title": "Delete dashboard state",
482 "delete-state-text": "Are you sure you want delete dashboard state with name '{{stateName}}'?", 481 "delete-state-text": "Are you sure you want delete dashboard state with name '{{stateName}}'?",
@@ -1169,9 +1168,6 @@ export default angular.module('thingsboard.locale', []) @@ -1169,9 +1168,6 @@ export default angular.module('thingsboard.locale', [])
1169 "es_ES": "Spanish" 1168 "es_ES": "Spanish"
1170 }, 1169 },
1171 "custom": { 1170 "custom": {
1172 - "alarms": {  
1173 - "title": "Super ${entityName}"  
1174 - }  
1175 } 1171 }
1176 } 1172 }
1177 } 1173 }
@@ -18,8 +18,7 @@ @@ -18,8 +18,7 @@
18 export default function ThingsboardMissingTranslateHandler($log, types) { 18 export default function ThingsboardMissingTranslateHandler($log, types) {
19 19
20 return function (translationId) { 20 return function (translationId) {
21 - if (translationId && !translationId.startsWith(types.translate.dashboardStatePrefix) &&  
22 - !translationId.startsWith(types.translate.customTranslationsPrefix)) { 21 + if (translationId && !translationId.startsWith(types.translate.customTranslationsPrefix)) {
23 $log.warn('Translation for ' + translationId + ' doesn\'t exist'); 22 $log.warn('Translation for ' + translationId + ' doesn\'t exist');
24 } 23 }
25 }; 24 };
@@ -31,7 +31,7 @@ @@ -31,7 +31,7 @@
31 on-export-plugin="vm.exportPlugin(event, vm.grid.detailsConfig.currentItem)" 31 on-export-plugin="vm.exportPlugin(event, vm.grid.detailsConfig.currentItem)"
32 on-delete-plugin="vm.grid.deleteItem(event, vm.grid.detailsConfig.currentItem)"></tb-plugin> 32 on-delete-plugin="vm.grid.deleteItem(event, vm.grid.detailsConfig.currentItem)"></tb-plugin>
33 </md-tab> 33 </md-tab>
34 - <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode && vm.isPluginEditable(vm.grid.operatingItem())" label="{{ 'attribute.attributes' | translate }}"> 34 + <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode && vm.isPluginEditable(vm.grid.operatingItem())" md-on-select="vm.grid.triggerResize()" label="{{ 'attribute.attributes' | translate }}">
35 <tb-attribute-table flex 35 <tb-attribute-table flex
36 entity-id="vm.grid.operatingItem().id.id" 36 entity-id="vm.grid.operatingItem().id.id"
37 entity-type="{{vm.types.entityType.plugin}}" 37 entity-type="{{vm.types.entityType.plugin}}"
@@ -39,7 +39,7 @@ @@ -39,7 +39,7 @@
39 default-attribute-scope="{{vm.types.attributesScope.server.value}}"> 39 default-attribute-scope="{{vm.types.attributesScope.server.value}}">
40 </tb-attribute-table> 40 </tb-attribute-table>
41 </md-tab> 41 </md-tab>
42 - <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode && vm.isPluginEditable(vm.grid.operatingItem())" label="{{ 'attribute.latest-telemetry' | translate }}"> 42 + <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode && vm.isPluginEditable(vm.grid.operatingItem())" md-on-select="vm.grid.triggerResize()" label="{{ 'attribute.latest-telemetry' | translate }}">
43 <tb-attribute-table flex 43 <tb-attribute-table flex
44 entity-id="vm.grid.operatingItem().id.id" 44 entity-id="vm.grid.operatingItem().id.id"
45 entity-type="{{vm.types.entityType.plugin}}" 45 entity-type="{{vm.types.entityType.plugin}}"
@@ -48,19 +48,19 @@ @@ -48,19 +48,19 @@
48 disable-attribute-scope-selection="true"> 48 disable-attribute-scope-selection="true">
49 </tb-attribute-table> 49 </tb-attribute-table>
50 </md-tab> 50 </md-tab>
51 - <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode && vm.isPluginEditable(vm.grid.operatingItem())" label="{{ 'alarm.alarms' | translate }}"> 51 + <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode && vm.isPluginEditable(vm.grid.operatingItem())" md-on-select="vm.grid.triggerResize()" label="{{ 'alarm.alarms' | translate }}">
52 <tb-alarm-table flex entity-type="vm.types.entityType.plugin" 52 <tb-alarm-table flex entity-type="vm.types.entityType.plugin"
53 entity-id="vm.grid.operatingItem().id.id"> 53 entity-id="vm.grid.operatingItem().id.id">
54 </tb-alarm-table> 54 </tb-alarm-table>
55 </md-tab> 55 </md-tab>
56 - <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode && vm.isPluginEditable(vm.grid.operatingItem())" label="{{ 'plugin.events' | translate }}"> 56 + <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode && vm.isPluginEditable(vm.grid.operatingItem())" md-on-select="vm.grid.triggerResize()" label="{{ 'plugin.events' | translate }}">
57 <tb-event-table flex entity-type="vm.types.entityType.plugin" 57 <tb-event-table flex entity-type="vm.types.entityType.plugin"
58 entity-id="vm.grid.operatingItem().id.id" 58 entity-id="vm.grid.operatingItem().id.id"
59 tenant-id="vm.grid.operatingItem().tenantId.id" 59 tenant-id="vm.grid.operatingItem().tenantId.id"
60 default-event-type="{{vm.types.eventType.lcEvent.value}}"> 60 default-event-type="{{vm.types.eventType.lcEvent.value}}">
61 </tb-event-table> 61 </tb-event-table>
62 </md-tab> 62 </md-tab>
63 - <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode && vm.isPluginEditable(vm.grid.operatingItem())" label="{{ 'relation.relations' | translate }}"> 63 + <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode && vm.isPluginEditable(vm.grid.operatingItem())" md-on-select="vm.grid.triggerResize()" label="{{ 'relation.relations' | translate }}">
64 <tb-relation-table flex 64 <tb-relation-table flex
65 entity-id="vm.grid.operatingItem().id.id" 65 entity-id="vm.grid.operatingItem().id.id"
66 entity-type="{{vm.types.entityType.plugin}}"> 66 entity-type="{{vm.types.entityType.plugin}}">
@@ -31,7 +31,7 @@ @@ -31,7 +31,7 @@
31 on-export-rule="vm.exportRule(event, vm.grid.detailsConfig.currentItem)" 31 on-export-rule="vm.exportRule(event, vm.grid.detailsConfig.currentItem)"
32 on-delete-rule="vm.grid.deleteItem(event, vm.grid.detailsConfig.currentItem)"></tb-rule> 32 on-delete-rule="vm.grid.deleteItem(event, vm.grid.detailsConfig.currentItem)"></tb-rule>
33 </md-tab> 33 </md-tab>
34 - <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode && vm.isRuleEditable(vm.grid.operatingItem())" label="{{ 'attribute.attributes' | translate }}"> 34 + <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode && vm.isRuleEditable(vm.grid.operatingItem())" md-on-select="vm.grid.triggerResize()" label="{{ 'attribute.attributes' | translate }}">
35 <tb-attribute-table flex 35 <tb-attribute-table flex
36 entity-id="vm.grid.operatingItem().id.id" 36 entity-id="vm.grid.operatingItem().id.id"
37 entity-type="{{vm.types.entityType.rule}}" 37 entity-type="{{vm.types.entityType.rule}}"
@@ -39,7 +39,7 @@ @@ -39,7 +39,7 @@
39 default-attribute-scope="{{vm.types.attributesScope.server.value}}"> 39 default-attribute-scope="{{vm.types.attributesScope.server.value}}">
40 </tb-attribute-table> 40 </tb-attribute-table>
41 </md-tab> 41 </md-tab>
42 - <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode && vm.isRuleEditable(vm.grid.operatingItem())" label="{{ 'attribute.latest-telemetry' | translate }}"> 42 + <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode && vm.isRuleEditable(vm.grid.operatingItem())" md-on-select="vm.grid.triggerResize()" label="{{ 'attribute.latest-telemetry' | translate }}">
43 <tb-attribute-table flex 43 <tb-attribute-table flex
44 entity-id="vm.grid.operatingItem().id.id" 44 entity-id="vm.grid.operatingItem().id.id"
45 entity-type="{{vm.types.entityType.rule}}" 45 entity-type="{{vm.types.entityType.rule}}"
@@ -48,19 +48,19 @@ @@ -48,19 +48,19 @@
48 disable-attribute-scope-selection="true"> 48 disable-attribute-scope-selection="true">
49 </tb-attribute-table> 49 </tb-attribute-table>
50 </md-tab> 50 </md-tab>
51 - <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode && vm.isRuleEditable(vm.grid.operatingItem())" label="{{ 'alarm.alarms' | translate }}"> 51 + <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode && vm.isRuleEditable(vm.grid.operatingItem())" md-on-select="vm.grid.triggerResize()" label="{{ 'alarm.alarms' | translate }}">
52 <tb-alarm-table flex entity-type="vm.types.entityType.rule" 52 <tb-alarm-table flex entity-type="vm.types.entityType.rule"
53 entity-id="vm.grid.operatingItem().id.id"> 53 entity-id="vm.grid.operatingItem().id.id">
54 </tb-alarm-table> 54 </tb-alarm-table>
55 </md-tab> 55 </md-tab>
56 - <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode && vm.isRuleEditable(vm.grid.operatingItem())" label="{{ 'rule.events' | translate }}"> 56 + <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode && vm.isRuleEditable(vm.grid.operatingItem())" md-on-select="vm.grid.triggerResize()" label="{{ 'rule.events' | translate }}">
57 <tb-event-table flex entity-type="vm.types.entityType.rule" 57 <tb-event-table flex entity-type="vm.types.entityType.rule"
58 entity-id="vm.grid.operatingItem().id.id" 58 entity-id="vm.grid.operatingItem().id.id"
59 tenant-id="vm.grid.operatingItem().tenantId.id" 59 tenant-id="vm.grid.operatingItem().tenantId.id"
60 default-event-type="{{vm.types.eventType.lcEvent.value}}"> 60 default-event-type="{{vm.types.eventType.lcEvent.value}}">
61 </tb-event-table> 61 </tb-event-table>
62 </md-tab> 62 </md-tab>
63 - <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode && vm.isRuleEditable(vm.grid.operatingItem())" label="{{ 'relation.relations' | translate }}"> 63 + <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode && vm.isRuleEditable(vm.grid.operatingItem())" md-on-select="vm.grid.triggerResize()" label="{{ 'relation.relations' | translate }}">
64 <tb-relation-table flex 64 <tb-relation-table flex
65 entity-id="vm.grid.operatingItem().id.id" 65 entity-id="vm.grid.operatingItem().id.id"
66 entity-type="{{vm.types.entityType.rule}}"> 66 entity-type="{{vm.types.entityType.rule}}">
@@ -29,7 +29,7 @@ @@ -29,7 +29,7 @@
29 on-manage-users="vm.openTenantUsers(event, vm.grid.detailsConfig.currentItem)" 29 on-manage-users="vm.openTenantUsers(event, vm.grid.detailsConfig.currentItem)"
30 on-delete-tenant="vm.grid.deleteItem(event, vm.grid.detailsConfig.currentItem)"></tb-tenant> 30 on-delete-tenant="vm.grid.deleteItem(event, vm.grid.detailsConfig.currentItem)"></tb-tenant>
31 </md-tab> 31 </md-tab>
32 - <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" label="{{ 'attribute.attributes' | translate }}"> 32 + <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" md-on-select="vm.grid.triggerResize()" label="{{ 'attribute.attributes' | translate }}">
33 <tb-attribute-table flex 33 <tb-attribute-table flex
34 entity-id="vm.grid.operatingItem().id.id" 34 entity-id="vm.grid.operatingItem().id.id"
35 entity-type="{{vm.types.entityType.tenant}}" 35 entity-type="{{vm.types.entityType.tenant}}"
@@ -37,7 +37,7 @@ @@ -37,7 +37,7 @@
37 default-attribute-scope="{{vm.types.attributesScope.server.value}}"> 37 default-attribute-scope="{{vm.types.attributesScope.server.value}}">
38 </tb-attribute-table> 38 </tb-attribute-table>
39 </md-tab> 39 </md-tab>
40 - <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" label="{{ 'attribute.latest-telemetry' | translate }}"> 40 + <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" md-on-select="vm.grid.triggerResize()" label="{{ 'attribute.latest-telemetry' | translate }}">
41 <tb-attribute-table flex 41 <tb-attribute-table flex
42 entity-id="vm.grid.operatingItem().id.id" 42 entity-id="vm.grid.operatingItem().id.id"
43 entity-type="{{vm.types.entityType.tenant}}" 43 entity-type="{{vm.types.entityType.tenant}}"
@@ -46,19 +46,19 @@ @@ -46,19 +46,19 @@
46 disable-attribute-scope-selection="true"> 46 disable-attribute-scope-selection="true">
47 </tb-attribute-table> 47 </tb-attribute-table>
48 </md-tab> 48 </md-tab>
49 - <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" label="{{ 'alarm.alarms' | translate }}"> 49 + <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" md-on-select="vm.grid.triggerResize()" label="{{ 'alarm.alarms' | translate }}">
50 <tb-alarm-table flex entity-type="vm.types.entityType.tenant" 50 <tb-alarm-table flex entity-type="vm.types.entityType.tenant"
51 entity-id="vm.grid.operatingItem().id.id"> 51 entity-id="vm.grid.operatingItem().id.id">
52 </tb-alarm-table> 52 </tb-alarm-table>
53 </md-tab> 53 </md-tab>
54 - <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" label="{{ 'tenant.events' | translate }}"> 54 + <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" md-on-select="vm.grid.triggerResize()" label="{{ 'tenant.events' | translate }}">
55 <tb-event-table flex entity-type="vm.types.entityType.tenant" 55 <tb-event-table flex entity-type="vm.types.entityType.tenant"
56 entity-id="vm.grid.operatingItem().id.id" 56 entity-id="vm.grid.operatingItem().id.id"
57 tenant-id="vm.types.id.nullUid" 57 tenant-id="vm.types.id.nullUid"
58 default-event-type="{{vm.types.eventType.error.value}}"> 58 default-event-type="{{vm.types.eventType.error.value}}">
59 </tb-event-table> 59 </tb-event-table>
60 </md-tab> 60 </md-tab>
61 - <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" label="{{ 'relation.relations' | translate }}"> 61 + <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" md-on-select="vm.grid.triggerResize()" label="{{ 'relation.relations' | translate }}">
62 <tb-relation-table flex 62 <tb-relation-table flex
63 entity-id="vm.grid.operatingItem().id.id" 63 entity-id="vm.grid.operatingItem().id.id"
64 entity-type="{{vm.types.entityType.tenant}}"> 64 entity-type="{{vm.types.entityType.tenant}}">
@@ -210,6 +210,9 @@ function AlarmsTableWidgetController($element, $scope, $filter, $mdMedia, $mdDia @@ -210,6 +210,9 @@ function AlarmsTableWidgetController($element, $scope, $filter, $mdMedia, $mdDia
210 var cssString = 'table.md-table th.md-column {\n'+ 210 var cssString = 'table.md-table th.md-column {\n'+
211 'color: ' + mdDarkSecondary + ';\n'+ 211 'color: ' + mdDarkSecondary + ';\n'+
212 '}\n'+ 212 '}\n'+
  213 + 'table.md-table th.md-column.md-checkbox-column md-checkbox:not(.md-checked) .md-icon {\n'+
  214 + 'border-color: ' + mdDarkSecondary + ';\n'+
  215 + '}\n'+
213 'table.md-table th.md-column md-icon.md-sort-icon {\n'+ 216 'table.md-table th.md-column md-icon.md-sort-icon {\n'+
214 'color: ' + mdDarkDisabled + ';\n'+ 217 'color: ' + mdDarkDisabled + ';\n'+
215 '}\n'+ 218 '}\n'+
@@ -220,6 +223,9 @@ function AlarmsTableWidgetController($element, $scope, $filter, $mdMedia, $mdDia @@ -220,6 +223,9 @@ function AlarmsTableWidgetController($element, $scope, $filter, $mdMedia, $mdDia
220 'color: ' + mdDark + ';\n'+ 223 'color: ' + mdDark + ';\n'+
221 'border-top: 1px '+mdDarkDivider+' solid;\n'+ 224 'border-top: 1px '+mdDarkDivider+' solid;\n'+
222 '}\n'+ 225 '}\n'+
  226 + 'table.md-table td.md-cell.md-checkbox-cell md-checkbox:not(.md-checked) .md-icon {\n'+
  227 + 'border-color: ' + mdDarkSecondary + ';\n'+
  228 + '}\n'+
223 'table.md-table td.md-cell.md-placeholder {\n'+ 229 'table.md-table td.md-cell.md-placeholder {\n'+
224 'color: ' + mdDarkDisabled + ';\n'+ 230 'color: ' + mdDarkDisabled + ';\n'+
225 '}\n'+ 231 '}\n'+
@@ -324,8 +324,14 @@ pre.tb-highlight { @@ -324,8 +324,14 @@ pre.tb-highlight {
324 tr { 324 tr {
325 &.md-row:not([disabled]) { 325 &.md-row:not([disabled]) {
326 outline: none; 326 outline: none;
  327 + &:hover {
  328 + background-color: rgba(221, 221, 221, 0.3) !important;
  329 + }
  330 + &.md-selected {
  331 + background-color: rgba(221, 221, 221, 0.5) !important;
  332 + }
327 &.tb-current, &.tb-current:hover{ 333 &.tb-current, &.tb-current:hover{
328 - background-color: #dddddd !important; 334 + background-color: rgba(221, 221, 221, 0.65) !important;
329 } 335 }
330 } 336 }
331 } 337 }