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 395 },
396 396 translate: {
397 397 dashboardStatePrefix: "dashboardState.state.",
398   - keyLabelPrefix: "key.label."
  398 + customTranslationsPrefix: "custom."
399 399 }
400 400 }
401 401 ).name;
... ...
... ... @@ -177,7 +177,10 @@ function DashboardController($scope, $rootScope, $element, $timeout, $mdMedia, $
177 177 vm.widgetBackgroundColor = widgetBackgroundColor;
178 178 vm.widgetPadding = widgetPadding;
179 179 vm.showWidgetTitle = showWidgetTitle;
  180 + vm.showWidgetTitlePanel = showWidgetTitlePanel;
180 181 vm.widgetTitleStyle = widgetTitleStyle;
  182 + vm.widgetTitle = widgetTitle;
  183 + vm.widgetActions = widgetActions;
181 184 vm.dropWidgetShadow = dropWidgetShadow;
182 185 vm.enableWidgetFullscreen = enableWidgetFullscreen;
183 186 vm.hasTimewindow = hasTimewindow;
... ... @@ -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 762 function widgetTitleStyle(widget) {
751 763 if (angular.isDefined(widget.config.titleStyle)) {
752 764 return widget.config.titleStyle;
... ... @@ -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 797 function dropWidgetShadow(widget) {
759 798 if (angular.isDefined(widget.config.dropShadow)) {
760 799 return widget.config.dropShadow;
... ...
... ... @@ -37,7 +37,8 @@
37 37 class="tb-widget"
38 38 ng-class="{'tb-highlighted': vm.isHighlighted(widget),
39 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 42 tb-mousedown="vm.widgetMouseDown($event, widget)"
42 43 ng-click="vm.widgetClicked($event, widget)"
43 44 tb-contextmenu="vm.openWidgetContextMenu($event, widget, $mdOpenMousepointMenu)"
... ... @@ -45,11 +46,21 @@
45 46 color: vm.widgetColor(widget),
46 47 backgroundColor: vm.widgetBackgroundColor(widget),
47 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 51 <tb-timewindow aggregation="{{vm.hasAggregation(widget)}}" ng-if="vm.hasTimewindow(widget)" ng-model="widget.config.timewindow"></tb-timewindow>
51 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 64 <md-button id="expand-button"
54 65 ng-show="!vm.isEdit && vm.enableWidgetFullscreen(widget)"
55 66 aria-label="{{ 'fullscreen.fullscreen' | translate }}"
... ...
... ... @@ -48,6 +48,7 @@ export default function WidgetController($scope, $timeout, $window, $element, $q
48 48 $containerParent: null,
49 49 width: 0,
50 50 height: 0,
  51 + hideTitlePanel: false,
51 52 isEdit: isEdit,
52 53 isMobile: false,
53 54 widgetConfig: widget.config,
... ... @@ -121,6 +122,10 @@ export default function WidgetController($scope, $timeout, $window, $element, $q
121 122 aliasController: aliasController
122 123 };
123 124
  125 + widget.$ctx = function() {
  126 + return widgetContext;
  127 + }
  128 +
124 129 var widgetTypeInstance;
125 130
126 131 vm.useCustomDatasources = false;
... ...
... ... @@ -1167,6 +1167,11 @@ export default angular.module('thingsboard.locale', [])
1167 1167 "zh_CN": "Chinese",
1168 1168 "ru_RU": "Russian",
1169 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 19
20 20 return function (translationId) {
21 21 if (translationId && !translationId.startsWith(types.translate.dashboardStatePrefix) &&
22   - !translationId.startsWith(types.translate.keyLabelPrefix)) {
  22 + !translationId.startsWith(types.translate.customTranslationsPrefix)) {
23 23 $log.warn('Translation for ' + translationId + ' doesn\'t exist');
24 24 }
25 25 };
... ...
... ... @@ -37,8 +37,7 @@ function AlarmsTableWidget() {
37 37 scope: true,
38 38 bindToController: {
39 39 tableId: '=',
40   - config: '=',
41   - subscription: '='
  40 + ctx: '='
42 41 },
43 42 controller: AlarmsTableWidgetController,
44 43 controllerAs: 'vm',
... ... @@ -66,9 +65,7 @@ function AlarmsTableWidgetController($element, $scope, $filter, $mdMedia, $mdDia
66 65
67 66 vm.currentAlarm = null;
68 67
69   - vm.alarmsTitle = $translate.instant('alarm.alarms');
70 68 vm.enableSelection = true;
71   - vm.enableSearch = true;
72 69 vm.displayDetails = true;
73 70 vm.allowAcknowledgment = true;
74 71 vm.allowClear = true;
... ... @@ -83,6 +80,15 @@ function AlarmsTableWidgetController($element, $scope, $filter, $mdMedia, $mdDia
83 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 92 vm.enterFilterMode = enterFilterMode;
87 93 vm.exitFilterMode = exitFilterMode;
88 94 vm.onReorder = onReorder;
... ... @@ -96,11 +102,14 @@ function AlarmsTableWidgetController($element, $scope, $filter, $mdMedia, $mdDia
96 102 vm.cellStyle = cellStyle;
97 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 111 initializeConfig();
  112 + updateAlarmSource();
104 113 }
105 114 });
106 115
... ... @@ -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 122 $scope.$on('alarms-table-data-updated', function(event, tableId) {
121 123 if (vm.tableId == tableId) {
122 124 if (vm.subscription) {
... ... @@ -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 156 function initializeConfig() {
144 157
  158 + vm.ctx.widgetActions = [ vm.searchAction ];
  159 +
145 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 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 176 vm.displayDetails = angular.isDefined(vm.settings.displayDetails) ? vm.settings.displayDetails : true;
151 177 vm.allowAcknowledgment = angular.isDefined(vm.settings.allowAcknowledgment) ? vm.settings.allowAcknowledgment : true;
152 178 vm.allowClear = angular.isDefined(vm.settings.allowClear) ? vm.settings.allowClear : true;
... ... @@ -233,11 +259,13 @@ function AlarmsTableWidgetController($element, $scope, $filter, $mdMedia, $mdDia
233 259
234 260 function enterFilterMode () {
235 261 vm.query.search = '';
  262 + vm.ctx.hideTitlePanel = true;
236 263 }
237 264
238 265 function exitFilterMode () {
239 266 vm.query.search = null;
240 267 updateAlarms();
  268 + vm.ctx.hideTitlePanel = false;
241 269 }
242 270
243 271 function onReorder () {
... ... @@ -496,9 +524,7 @@ function AlarmsTableWidgetController($element, $scope, $filter, $mdMedia, $mdDia
496 524
497 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 529 vm.stylesInfo = {};
504 530 vm.contentsInfo = {};
... ... @@ -507,10 +533,10 @@ function AlarmsTableWidgetController($element, $scope, $filter, $mdMedia, $mdDia
507 533 for (var d = 0; d < vm.alarmSource.dataKeys.length; d++ ) {
508 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 537 var translation = $translate.instant(translationId);
512 538 if (translation != translationId) {
513   - dataKey.title = translation;
  539 + dataKey.title = translation + '';
514 540 } else {
515 541 dataKey.title = dataKey.label;
516 542 }
... ...
... ... @@ -14,8 +14,32 @@
14 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 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 43 &.tb-data-table {
20 44 table.md-table, table.md-table.md-row-select {
21 45 tbody {
... ...
... ... @@ -17,19 +17,6 @@
17 17 -->
18 18 <div class="tb-absolute-fill tb-alarms-table tb-data-table" layout="column">
19 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 20 <md-toolbar class="md-table-toolbar md-default" ng-show="!vm.selectedAlarms.length &&
34 21 vm.query.search != null">
35 22 <div class="md-toolbar-tools">
... ...