Commit 8a37cf0d0de1a762805844f48e7c2436240a88ee

Authored by Igor Kulikov
1 parent eda21c94

TB-63: Improve alarm widget layout.

@@ -395,7 +395,7 @@ export default angular.module('thingsboard.types', []) @@ -395,7 +395,7 @@ export default angular.module('thingsboard.types', [])
395 }, 395 },
396 translate: { 396 translate: {
397 dashboardStatePrefix: "dashboardState.state.", 397 dashboardStatePrefix: "dashboardState.state.",
398 - keyLabelPrefix: "key.label." 398 + customTranslationsPrefix: "custom."
399 } 399 }
400 } 400 }
401 ).name; 401 ).name;
@@ -177,7 +177,10 @@ function DashboardController($scope, $rootScope, $element, $timeout, $mdMedia, $ @@ -177,7 +177,10 @@ function DashboardController($scope, $rootScope, $element, $timeout, $mdMedia, $
177 vm.widgetBackgroundColor = widgetBackgroundColor; 177 vm.widgetBackgroundColor = widgetBackgroundColor;
178 vm.widgetPadding = widgetPadding; 178 vm.widgetPadding = widgetPadding;
179 vm.showWidgetTitle = showWidgetTitle; 179 vm.showWidgetTitle = showWidgetTitle;
  180 + vm.showWidgetTitlePanel = showWidgetTitlePanel;
180 vm.widgetTitleStyle = widgetTitleStyle; 181 vm.widgetTitleStyle = widgetTitleStyle;
  182 + vm.widgetTitle = widgetTitle;
  183 + vm.widgetActions = widgetActions;
181 vm.dropWidgetShadow = dropWidgetShadow; 184 vm.dropWidgetShadow = dropWidgetShadow;
182 vm.enableWidgetFullscreen = enableWidgetFullscreen; 185 vm.enableWidgetFullscreen = enableWidgetFullscreen;
183 vm.hasTimewindow = hasTimewindow; 186 vm.hasTimewindow = hasTimewindow;
@@ -747,6 +750,15 @@ function DashboardController($scope, $rootScope, $element, $timeout, $mdMedia, $ @@ -747,6 +750,15 @@ function DashboardController($scope, $rootScope, $element, $timeout, $mdMedia, $
747 } 750 }
748 } 751 }
749 752
  753 + function showWidgetTitlePanel(widget) {
  754 + var ctx = widgetContext(widget);
  755 + if (ctx && ctx.hideTitlePanel) {
  756 + return false;
  757 + } else {
  758 + return showWidgetTitle(widget) || hasTimewindow(widget);
  759 + }
  760 + }
  761 +
750 function widgetTitleStyle(widget) { 762 function widgetTitleStyle(widget) {
751 if (angular.isDefined(widget.config.titleStyle)) { 763 if (angular.isDefined(widget.config.titleStyle)) {
752 return widget.config.titleStyle; 764 return widget.config.titleStyle;
@@ -755,6 +767,33 @@ function DashboardController($scope, $rootScope, $element, $timeout, $mdMedia, $ @@ -755,6 +767,33 @@ function DashboardController($scope, $rootScope, $element, $timeout, $mdMedia, $
755 } 767 }
756 } 768 }
757 769
  770 + function widgetTitle(widget) {
  771 + var ctx = widgetContext(widget);
  772 + if (ctx && ctx.widgetTitle
  773 + && ctx.widgetTitle.length) {
  774 + return ctx.widgetTitle;
  775 + } else {
  776 + return widget.config.title;
  777 + }
  778 + }
  779 +
  780 + function widgetActions(widget) {
  781 + var ctx = widgetContext(widget);
  782 + if (ctx && ctx.widgetActions && ctx.widgetActions.length) {
  783 + return ctx.widgetActions;
  784 + } else {
  785 + return [];
  786 + }
  787 + }
  788 +
  789 + function widgetContext(widget) {
  790 + var context;
  791 + if (widget.$ctx) {
  792 + context = widget.$ctx();
  793 + }
  794 + return context;
  795 + }
  796 +
758 function dropWidgetShadow(widget) { 797 function dropWidgetShadow(widget) {
759 if (angular.isDefined(widget.config.dropShadow)) { 798 if (angular.isDefined(widget.config.dropShadow)) {
760 return widget.config.dropShadow; 799 return widget.config.dropShadow;
@@ -37,7 +37,8 @@ @@ -37,7 +37,8 @@
37 class="tb-widget" 37 class="tb-widget"
38 ng-class="{'tb-highlighted': vm.isHighlighted(widget), 38 ng-class="{'tb-highlighted': vm.isHighlighted(widget),
39 'tb-not-highlighted': vm.isNotHighlighted(widget), 39 'tb-not-highlighted': vm.isNotHighlighted(widget),
40 - 'md-whiteframe-4dp': vm.dropWidgetShadow(widget)}" 40 + 'md-whiteframe-4dp': vm.dropWidgetShadow(widget),
  41 + 'tb-has-timewindow': vm.hasTimewindow(widget)}"
41 tb-mousedown="vm.widgetMouseDown($event, widget)" 42 tb-mousedown="vm.widgetMouseDown($event, widget)"
42 ng-click="vm.widgetClicked($event, widget)" 43 ng-click="vm.widgetClicked($event, widget)"
43 tb-contextmenu="vm.openWidgetContextMenu($event, widget, $mdOpenMousepointMenu)" 44 tb-contextmenu="vm.openWidgetContextMenu($event, widget, $mdOpenMousepointMenu)"
@@ -45,11 +46,21 @@ @@ -45,11 +46,21 @@
45 color: vm.widgetColor(widget), 46 color: vm.widgetColor(widget),
46 backgroundColor: vm.widgetBackgroundColor(widget), 47 backgroundColor: vm.widgetBackgroundColor(widget),
47 padding: vm.widgetPadding(widget)}"> 48 padding: vm.widgetPadding(widget)}">
48 - <div class="tb-widget-title" layout="column" layout-align="center start" ng-show="vm.showWidgetTitle(widget) || vm.hasTimewindow(widget)">  
49 - <span ng-show="vm.showWidgetTitle(widget)" ng-style="vm.widgetTitleStyle(widget)" class="md-subhead">{{widget.config.title}}</span> 49 + <div class="tb-widget-title" layout="column" layout-align="center start" ng-show="vm.showWidgetTitlePanel(widget)">
  50 + <span ng-show="vm.showWidgetTitle(widget)" ng-style="vm.widgetTitleStyle(widget)" class="md-subhead">{{vm.widgetTitle(widget)}}</span>
50 <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>
51 </div> 52 </div>
52 - <div class="tb-widget-actions" layout="row" layout-align="start center" tb-mousedown="$event.stopPropagation()"> 53 + <div class="tb-widget-actions" layout="row" layout-align="start center" ng-show="vm.showWidgetTitlePanel(widget)" tb-mousedown="$event.stopPropagation()">
  54 + <md-button ng-repeat="action in vm.widgetActions(widget)"
  55 + aria-label="{{ action.name | translate }}"
  56 + ng-show="!vm.isEdit && action.show"
  57 + ng-click="action.onAction($event)"
  58 + class="md-icon-button">
  59 + <md-tooltip md-direction="top">
  60 + {{ action.name | translate }}
  61 + </md-tooltip>
  62 + <ng-md-icon size="20" icon="{{action.icon}}"></ng-md-icon>
  63 + </md-button>
53 <md-button id="expand-button" 64 <md-button id="expand-button"
54 ng-show="!vm.isEdit && vm.enableWidgetFullscreen(widget)" 65 ng-show="!vm.isEdit && vm.enableWidgetFullscreen(widget)"
55 aria-label="{{ 'fullscreen.fullscreen' | translate }}" 66 aria-label="{{ 'fullscreen.fullscreen' | translate }}"
@@ -48,6 +48,7 @@ export default function WidgetController($scope, $timeout, $window, $element, $q @@ -48,6 +48,7 @@ export default function WidgetController($scope, $timeout, $window, $element, $q
48 $containerParent: null, 48 $containerParent: null,
49 width: 0, 49 width: 0,
50 height: 0, 50 height: 0,
  51 + hideTitlePanel: false,
51 isEdit: isEdit, 52 isEdit: isEdit,
52 isMobile: false, 53 isMobile: false,
53 widgetConfig: widget.config, 54 widgetConfig: widget.config,
@@ -121,6 +122,10 @@ export default function WidgetController($scope, $timeout, $window, $element, $q @@ -121,6 +122,10 @@ export default function WidgetController($scope, $timeout, $window, $element, $q
121 aliasController: aliasController 122 aliasController: aliasController
122 }; 123 };
123 124
  125 + widget.$ctx = function() {
  126 + return widgetContext;
  127 + }
  128 +
124 var widgetTypeInstance; 129 var widgetTypeInstance;
125 130
126 vm.useCustomDatasources = false; 131 vm.useCustomDatasources = false;
@@ -1167,6 +1167,11 @@ export default angular.module('thingsboard.locale', []) @@ -1167,6 +1167,11 @@ export default angular.module('thingsboard.locale', [])
1167 "zh_CN": "Chinese", 1167 "zh_CN": "Chinese",
1168 "ru_RU": "Russian", 1168 "ru_RU": "Russian",
1169 "es_ES": "Spanish" 1169 "es_ES": "Spanish"
  1170 + },
  1171 + "custom": {
  1172 + "alarms": {
  1173 + "title": "Super ${entityName}"
  1174 + }
1170 } 1175 }
1171 } 1176 }
1172 } 1177 }
@@ -19,7 +19,7 @@ export default function ThingsboardMissingTranslateHandler($log, types) { @@ -19,7 +19,7 @@ export default function ThingsboardMissingTranslateHandler($log, types) {
19 19
20 return function (translationId) { 20 return function (translationId) {
21 if (translationId && !translationId.startsWith(types.translate.dashboardStatePrefix) && 21 if (translationId && !translationId.startsWith(types.translate.dashboardStatePrefix) &&
22 - !translationId.startsWith(types.translate.keyLabelPrefix)) { 22 + !translationId.startsWith(types.translate.customTranslationsPrefix)) {
23 $log.warn('Translation for ' + translationId + ' doesn\'t exist'); 23 $log.warn('Translation for ' + translationId + ' doesn\'t exist');
24 } 24 }
25 }; 25 };
@@ -37,8 +37,7 @@ function AlarmsTableWidget() { @@ -37,8 +37,7 @@ function AlarmsTableWidget() {
37 scope: true, 37 scope: true,
38 bindToController: { 38 bindToController: {
39 tableId: '=', 39 tableId: '=',
40 - config: '=',  
41 - subscription: '=' 40 + ctx: '='
42 }, 41 },
43 controller: AlarmsTableWidgetController, 42 controller: AlarmsTableWidgetController,
44 controllerAs: 'vm', 43 controllerAs: 'vm',
@@ -66,9 +65,7 @@ function AlarmsTableWidgetController($element, $scope, $filter, $mdMedia, $mdDia @@ -66,9 +65,7 @@ function AlarmsTableWidgetController($element, $scope, $filter, $mdMedia, $mdDia
66 65
67 vm.currentAlarm = null; 66 vm.currentAlarm = null;
68 67
69 - vm.alarmsTitle = $translate.instant('alarm.alarms');  
70 vm.enableSelection = true; 68 vm.enableSelection = true;
71 - vm.enableSearch = true;  
72 vm.displayDetails = true; 69 vm.displayDetails = true;
73 vm.allowAcknowledgment = true; 70 vm.allowAcknowledgment = true;
74 vm.allowClear = true; 71 vm.allowClear = true;
@@ -83,6 +80,15 @@ function AlarmsTableWidgetController($element, $scope, $filter, $mdMedia, $mdDia @@ -83,6 +80,15 @@ function AlarmsTableWidgetController($element, $scope, $filter, $mdMedia, $mdDia
83 search: null 80 search: null
84 }; 81 };
85 82
  83 + vm.searchAction = {
  84 + name: 'action.search',
  85 + show: true,
  86 + onAction: function() {
  87 + vm.enterFilterMode();
  88 + },
  89 + icon: 'search'
  90 + };
  91 +
86 vm.enterFilterMode = enterFilterMode; 92 vm.enterFilterMode = enterFilterMode;
87 vm.exitFilterMode = exitFilterMode; 93 vm.exitFilterMode = exitFilterMode;
88 vm.onReorder = onReorder; 94 vm.onReorder = onReorder;
@@ -96,11 +102,14 @@ function AlarmsTableWidgetController($element, $scope, $filter, $mdMedia, $mdDia @@ -96,11 +102,14 @@ function AlarmsTableWidgetController($element, $scope, $filter, $mdMedia, $mdDia
96 vm.cellStyle = cellStyle; 102 vm.cellStyle = cellStyle;
97 vm.cellContent = cellContent; 103 vm.cellContent = cellContent;
98 104
99 - $scope.$watch('vm.config', function() {  
100 - if (vm.config) {  
101 - vm.settings = vm.config.settings;  
102 - vm.widgetConfig = vm.config.widgetConfig; 105 + $scope.$watch('vm.ctx', function() {
  106 + if (vm.ctx) {
  107 + vm.settings = vm.ctx.settings;
  108 + vm.widgetConfig = vm.ctx.widgetConfig;
  109 + vm.subscription = vm.ctx.defaultSubscription;
  110 + vm.alarmSource = vm.subscription.alarmSource;
103 initializeConfig(); 111 initializeConfig();
  112 + updateAlarmSource();
104 } 113 }
105 }); 114 });
106 115
@@ -110,13 +119,6 @@ function AlarmsTableWidgetController($element, $scope, $filter, $mdMedia, $mdDia @@ -110,13 +119,6 @@ function AlarmsTableWidgetController($element, $scope, $filter, $mdMedia, $mdDia
110 } 119 }
111 }); 120 });
112 121
113 - $scope.$watch('vm.subscription', function() {  
114 - if (vm.subscription) {  
115 - vm.alarmSource = vm.subscription.alarmSource;  
116 - updateAlarmSource();  
117 - }  
118 - });  
119 -  
120 $scope.$on('alarms-table-data-updated', function(event, tableId) { 122 $scope.$on('alarms-table-data-updated', function(event, tableId) {
121 if (vm.tableId == tableId) { 123 if (vm.tableId == tableId) {
122 if (vm.subscription) { 124 if (vm.subscription) {
@@ -140,13 +142,37 @@ function AlarmsTableWidgetController($element, $scope, $filter, $mdMedia, $mdDia @@ -140,13 +142,37 @@ function AlarmsTableWidgetController($element, $scope, $filter, $mdMedia, $mdDia
140 } 142 }
141 }); 143 });
142 144
  145 + $scope.$watch('vm.selectedAlarms.length', function (newLength) {
  146 + var selectionMode = newLength ? true : false;
  147 + if (vm.ctx) {
  148 + if (selectionMode) {
  149 + vm.ctx.hideTitlePanel = true;
  150 + } else if (vm.query.search == null) {
  151 + vm.ctx.hideTitlePanel = false;
  152 + }
  153 + }
  154 + });
  155 +
143 function initializeConfig() { 156 function initializeConfig() {
144 157
  158 + vm.ctx.widgetActions = [ vm.searchAction ];
  159 +
145 if (vm.settings.alarmsTitle && vm.settings.alarmsTitle.length) { 160 if (vm.settings.alarmsTitle && vm.settings.alarmsTitle.length) {
146 - vm.alarmsTitle = vm.settings.alarmsTitle; 161 + var translationId = types.translate.customTranslationsPrefix + vm.settings.alarmsTitle;
  162 + var translation = $translate.instant(translationId);
  163 + if (translation != translationId) {
  164 + vm.alarmsTitle = translation + '';
  165 + } else {
  166 + vm.alarmsTitle = vm.settings.alarmsTitle;
  167 + }
  168 + } else {
  169 + vm.alarmsTitle = $translate.instant('alarm.alarms');
147 } 170 }
  171 +
  172 + vm.ctx.widgetTitle = vm.alarmsTitle;
  173 +
148 vm.enableSelection = angular.isDefined(vm.settings.enableSelection) ? vm.settings.enableSelection : true; 174 vm.enableSelection = angular.isDefined(vm.settings.enableSelection) ? vm.settings.enableSelection : true;
149 - vm.enableSearch = angular.isDefined(vm.settings.enableSearch) ? vm.settings.enableSearch : true; 175 + vm.searchAction.show = angular.isDefined(vm.settings.enableSearch) ? vm.settings.enableSearch : true;
150 vm.displayDetails = angular.isDefined(vm.settings.displayDetails) ? vm.settings.displayDetails : true; 176 vm.displayDetails = angular.isDefined(vm.settings.displayDetails) ? vm.settings.displayDetails : true;
151 vm.allowAcknowledgment = angular.isDefined(vm.settings.allowAcknowledgment) ? vm.settings.allowAcknowledgment : true; 177 vm.allowAcknowledgment = angular.isDefined(vm.settings.allowAcknowledgment) ? vm.settings.allowAcknowledgment : true;
152 vm.allowClear = angular.isDefined(vm.settings.allowClear) ? vm.settings.allowClear : true; 178 vm.allowClear = angular.isDefined(vm.settings.allowClear) ? vm.settings.allowClear : true;
@@ -233,11 +259,13 @@ function AlarmsTableWidgetController($element, $scope, $filter, $mdMedia, $mdDia @@ -233,11 +259,13 @@ function AlarmsTableWidgetController($element, $scope, $filter, $mdMedia, $mdDia
233 259
234 function enterFilterMode () { 260 function enterFilterMode () {
235 vm.query.search = ''; 261 vm.query.search = '';
  262 + vm.ctx.hideTitlePanel = true;
236 } 263 }
237 264
238 function exitFilterMode () { 265 function exitFilterMode () {
239 vm.query.search = null; 266 vm.query.search = null;
240 updateAlarms(); 267 updateAlarms();
  268 + vm.ctx.hideTitlePanel = false;
241 } 269 }
242 270
243 function onReorder () { 271 function onReorder () {
@@ -496,9 +524,7 @@ function AlarmsTableWidgetController($element, $scope, $filter, $mdMedia, $mdDia @@ -496,9 +524,7 @@ function AlarmsTableWidgetController($element, $scope, $filter, $mdMedia, $mdDia
496 524
497 function updateAlarmSource() { 525 function updateAlarmSource() {
498 526
499 - if (vm.settings.alarmsTitle && vm.settings.alarmsTitle.length) {  
500 - vm.alarmsTitle = utils.createLabelFromDatasource(vm.alarmSource, vm.settings.alarmsTitle);  
501 - } 527 + vm.ctx.widgetTitle = utils.createLabelFromDatasource(vm.alarmSource, vm.alarmsTitle);
502 528
503 vm.stylesInfo = {}; 529 vm.stylesInfo = {};
504 vm.contentsInfo = {}; 530 vm.contentsInfo = {};
@@ -507,10 +533,10 @@ function AlarmsTableWidgetController($element, $scope, $filter, $mdMedia, $mdDia @@ -507,10 +533,10 @@ function AlarmsTableWidgetController($element, $scope, $filter, $mdMedia, $mdDia
507 for (var d = 0; d < vm.alarmSource.dataKeys.length; d++ ) { 533 for (var d = 0; d < vm.alarmSource.dataKeys.length; d++ ) {
508 var dataKey = vm.alarmSource.dataKeys[d]; 534 var dataKey = vm.alarmSource.dataKeys[d];
509 535
510 - var translationId = types.translate.keyLabelPrefix + dataKey.label; 536 + var translationId = types.translate.customTranslationsPrefix + dataKey.label;
511 var translation = $translate.instant(translationId); 537 var translation = $translate.instant(translationId);
512 if (translation != translationId) { 538 if (translation != translationId) {
513 - dataKey.title = translation; 539 + dataKey.title = translation + '';
514 } else { 540 } else {
515 dataKey.title = dataKey.label; 541 dataKey.title = dataKey.label;
516 } 542 }
@@ -14,8 +14,32 @@ @@ -14,8 +14,32 @@
14 * limitations under the License. 14 * limitations under the License.
15 */ 15 */
16 16
  17 +.tb-has-timewindow {
  18 + .tb-alarms-table {
  19 + md-toolbar {
  20 + min-height: 60px;
  21 + max-height: 60px;
  22 + &.md-table-toolbar {
  23 + .md-toolbar-tools {
  24 + max-height: 60px;
  25 + }
  26 + }
  27 + }
  28 + }
  29 +}
  30 +
17 .tb-alarms-table { 31 .tb-alarms-table {
18 - margin-top: 15px; 32 +
  33 + md-toolbar {
  34 + min-height: 39px;
  35 + max-height: 39px;
  36 + &.md-table-toolbar {
  37 + .md-toolbar-tools {
  38 + max-height: 39px;
  39 + }
  40 + }
  41 + }
  42 +
19 &.tb-data-table { 43 &.tb-data-table {
20 table.md-table, table.md-table.md-row-select { 44 table.md-table, table.md-table.md-row-select {
21 tbody { 45 tbody {
@@ -17,19 +17,6 @@ @@ -17,19 +17,6 @@
17 --> 17 -->
18 <div class="tb-absolute-fill tb-alarms-table tb-data-table" layout="column"> 18 <div class="tb-absolute-fill tb-alarms-table tb-data-table" layout="column">
19 <div ng-show="vm.showData" flex class="tb-absolute-fill" layout="column"> 19 <div ng-show="vm.showData" flex class="tb-absolute-fill" layout="column">
20 - <md-toolbar class="md-table-toolbar md-default" ng-show="!vm.selectedAlarms.length  
21 - && vm.query.search === null">  
22 - <div class="md-toolbar-tools">  
23 - <span>{{ vm.alarmsTitle }}</span>  
24 - <span flex></span>  
25 - <md-button ng-if="vm.enableSearch" class="md-icon-button" ng-click="vm.enterFilterMode()">  
26 - <md-icon>search</md-icon>  
27 - <md-tooltip md-direction="top">  
28 - {{ 'action.search' | translate }}  
29 - </md-tooltip>  
30 - </md-button>  
31 - </div>  
32 - </md-toolbar>  
33 <md-toolbar class="md-table-toolbar md-default" ng-show="!vm.selectedAlarms.length && 20 <md-toolbar class="md-table-toolbar md-default" ng-show="!vm.selectedAlarms.length &&
34 vm.query.search != null"> 21 vm.query.search != null">
35 <div class="md-toolbar-tools"> 22 <div class="md-toolbar-tools">