Merge pull request #170 from thingsboard/feature/TB-63

TB-63: Improve alarm widget layout.
This commit is contained in:
Igor Kulikov 2017-06-15 13:46:07 +03:00 committed by GitHub
commit 09ca1caf96
9 changed files with 139 additions and 42 deletions

View File

@ -395,7 +395,7 @@ export default angular.module('thingsboard.types', [])
}, },
translate: { translate: {
dashboardStatePrefix: "dashboardState.state.", dashboardStatePrefix: "dashboardState.state.",
keyLabelPrefix: "key.label." customTranslationsPrefix: "custom."
} }
} }
).name; ).name;

View File

@ -177,7 +177,10 @@ function DashboardController($scope, $rootScope, $element, $timeout, $mdMedia, $
vm.widgetBackgroundColor = widgetBackgroundColor; vm.widgetBackgroundColor = widgetBackgroundColor;
vm.widgetPadding = widgetPadding; vm.widgetPadding = widgetPadding;
vm.showWidgetTitle = showWidgetTitle; vm.showWidgetTitle = showWidgetTitle;
vm.showWidgetTitlePanel = showWidgetTitlePanel;
vm.widgetTitleStyle = widgetTitleStyle; vm.widgetTitleStyle = widgetTitleStyle;
vm.widgetTitle = widgetTitle;
vm.widgetActions = widgetActions;
vm.dropWidgetShadow = dropWidgetShadow; vm.dropWidgetShadow = dropWidgetShadow;
vm.enableWidgetFullscreen = enableWidgetFullscreen; vm.enableWidgetFullscreen = enableWidgetFullscreen;
vm.hasTimewindow = hasTimewindow; vm.hasTimewindow = hasTimewindow;
@ -747,6 +750,15 @@ function DashboardController($scope, $rootScope, $element, $timeout, $mdMedia, $
} }
} }
function showWidgetTitlePanel(widget) {
var ctx = widgetContext(widget);
if (ctx && ctx.hideTitlePanel) {
return false;
} else {
return showWidgetTitle(widget) || hasTimewindow(widget);
}
}
function widgetTitleStyle(widget) { function widgetTitleStyle(widget) {
if (angular.isDefined(widget.config.titleStyle)) { if (angular.isDefined(widget.config.titleStyle)) {
return widget.config.titleStyle; return widget.config.titleStyle;
@ -755,6 +767,33 @@ function DashboardController($scope, $rootScope, $element, $timeout, $mdMedia, $
} }
} }
function widgetTitle(widget) {
var ctx = widgetContext(widget);
if (ctx && ctx.widgetTitle
&& ctx.widgetTitle.length) {
return ctx.widgetTitle;
} else {
return widget.config.title;
}
}
function widgetActions(widget) {
var ctx = widgetContext(widget);
if (ctx && ctx.widgetActions && ctx.widgetActions.length) {
return ctx.widgetActions;
} else {
return [];
}
}
function widgetContext(widget) {
var context;
if (widget.$ctx) {
context = widget.$ctx();
}
return context;
}
function dropWidgetShadow(widget) { function dropWidgetShadow(widget) {
if (angular.isDefined(widget.config.dropShadow)) { if (angular.isDefined(widget.config.dropShadow)) {
return widget.config.dropShadow; return widget.config.dropShadow;

View File

@ -37,7 +37,8 @@
class="tb-widget" class="tb-widget"
ng-class="{'tb-highlighted': vm.isHighlighted(widget), ng-class="{'tb-highlighted': vm.isHighlighted(widget),
'tb-not-highlighted': vm.isNotHighlighted(widget), 'tb-not-highlighted': vm.isNotHighlighted(widget),
'md-whiteframe-4dp': vm.dropWidgetShadow(widget)}" 'md-whiteframe-4dp': vm.dropWidgetShadow(widget),
'tb-has-timewindow': vm.hasTimewindow(widget)}"
tb-mousedown="vm.widgetMouseDown($event, widget)" tb-mousedown="vm.widgetMouseDown($event, widget)"
ng-click="vm.widgetClicked($event, widget)" ng-click="vm.widgetClicked($event, widget)"
tb-contextmenu="vm.openWidgetContextMenu($event, widget, $mdOpenMousepointMenu)" tb-contextmenu="vm.openWidgetContextMenu($event, widget, $mdOpenMousepointMenu)"
@ -45,11 +46,21 @@
color: vm.widgetColor(widget), color: vm.widgetColor(widget),
backgroundColor: vm.widgetBackgroundColor(widget), backgroundColor: vm.widgetBackgroundColor(widget),
padding: vm.widgetPadding(widget)}"> padding: vm.widgetPadding(widget)}">
<div class="tb-widget-title" layout="column" layout-align="center start" ng-show="vm.showWidgetTitle(widget) || vm.hasTimewindow(widget)"> <div class="tb-widget-title" layout="column" layout-align="center start" ng-show="vm.showWidgetTitlePanel(widget)">
<span ng-show="vm.showWidgetTitle(widget)" ng-style="vm.widgetTitleStyle(widget)" class="md-subhead">{{widget.config.title}}</span> <span ng-show="vm.showWidgetTitle(widget)" ng-style="vm.widgetTitleStyle(widget)" class="md-subhead">{{vm.widgetTitle(widget)}}</span>
<tb-timewindow aggregation="{{vm.hasAggregation(widget)}}" ng-if="vm.hasTimewindow(widget)" ng-model="widget.config.timewindow"></tb-timewindow> <tb-timewindow aggregation="{{vm.hasAggregation(widget)}}" ng-if="vm.hasTimewindow(widget)" ng-model="widget.config.timewindow"></tb-timewindow>
</div> </div>
<div class="tb-widget-actions" layout="row" layout-align="start center" tb-mousedown="$event.stopPropagation()"> <div class="tb-widget-actions" layout="row" layout-align="start center" ng-show="vm.showWidgetTitlePanel(widget)" tb-mousedown="$event.stopPropagation()">
<md-button ng-repeat="action in vm.widgetActions(widget)"
aria-label="{{ action.name | translate }}"
ng-show="!vm.isEdit && action.show"
ng-click="action.onAction($event)"
class="md-icon-button">
<md-tooltip md-direction="top">
{{ action.name | translate }}
</md-tooltip>
<ng-md-icon size="20" icon="{{action.icon}}"></ng-md-icon>
</md-button>
<md-button id="expand-button" <md-button id="expand-button"
ng-show="!vm.isEdit && vm.enableWidgetFullscreen(widget)" ng-show="!vm.isEdit && vm.enableWidgetFullscreen(widget)"
aria-label="{{ 'fullscreen.fullscreen' | translate }}" aria-label="{{ 'fullscreen.fullscreen' | translate }}"

View File

@ -48,6 +48,7 @@ export default function WidgetController($scope, $timeout, $window, $element, $q
$containerParent: null, $containerParent: null,
width: 0, width: 0,
height: 0, height: 0,
hideTitlePanel: false,
isEdit: isEdit, isEdit: isEdit,
isMobile: false, isMobile: false,
widgetConfig: widget.config, widgetConfig: widget.config,
@ -121,6 +122,10 @@ export default function WidgetController($scope, $timeout, $window, $element, $q
aliasController: aliasController aliasController: aliasController
}; };
widget.$ctx = function() {
return widgetContext;
}
var widgetTypeInstance; var widgetTypeInstance;
vm.useCustomDatasources = false; vm.useCustomDatasources = false;

View File

@ -1167,6 +1167,11 @@ export default angular.module('thingsboard.locale', [])
"zh_CN": "Chinese", "zh_CN": "Chinese",
"ru_RU": "Russian", "ru_RU": "Russian",
"es_ES": "Spanish" "es_ES": "Spanish"
},
"custom": {
"alarms": {
"title": "Super ${entityName}"
}
} }
} }
} }

View File

@ -19,7 +19,7 @@ export default function ThingsboardMissingTranslateHandler($log, types) {
return function (translationId) { return function (translationId) {
if (translationId && !translationId.startsWith(types.translate.dashboardStatePrefix) && if (translationId && !translationId.startsWith(types.translate.dashboardStatePrefix) &&
!translationId.startsWith(types.translate.keyLabelPrefix)) { !translationId.startsWith(types.translate.customTranslationsPrefix)) {
$log.warn('Translation for ' + translationId + ' doesn\'t exist'); $log.warn('Translation for ' + translationId + ' doesn\'t exist');
} }
}; };

View File

@ -37,8 +37,7 @@ function AlarmsTableWidget() {
scope: true, scope: true,
bindToController: { bindToController: {
tableId: '=', tableId: '=',
config: '=', ctx: '='
subscription: '='
}, },
controller: AlarmsTableWidgetController, controller: AlarmsTableWidgetController,
controllerAs: 'vm', controllerAs: 'vm',
@ -66,9 +65,7 @@ function AlarmsTableWidgetController($element, $scope, $filter, $mdMedia, $mdDia
vm.currentAlarm = null; vm.currentAlarm = null;
vm.alarmsTitle = $translate.instant('alarm.alarms');
vm.enableSelection = true; vm.enableSelection = true;
vm.enableSearch = true;
vm.displayDetails = true; vm.displayDetails = true;
vm.allowAcknowledgment = true; vm.allowAcknowledgment = true;
vm.allowClear = true; vm.allowClear = true;
@ -83,6 +80,15 @@ function AlarmsTableWidgetController($element, $scope, $filter, $mdMedia, $mdDia
search: null search: null
}; };
vm.searchAction = {
name: 'action.search',
show: true,
onAction: function() {
vm.enterFilterMode();
},
icon: 'search'
};
vm.enterFilterMode = enterFilterMode; vm.enterFilterMode = enterFilterMode;
vm.exitFilterMode = exitFilterMode; vm.exitFilterMode = exitFilterMode;
vm.onReorder = onReorder; vm.onReorder = onReorder;
@ -96,11 +102,14 @@ function AlarmsTableWidgetController($element, $scope, $filter, $mdMedia, $mdDia
vm.cellStyle = cellStyle; vm.cellStyle = cellStyle;
vm.cellContent = cellContent; vm.cellContent = cellContent;
$scope.$watch('vm.config', function() { $scope.$watch('vm.ctx', function() {
if (vm.config) { if (vm.ctx) {
vm.settings = vm.config.settings; vm.settings = vm.ctx.settings;
vm.widgetConfig = vm.config.widgetConfig; vm.widgetConfig = vm.ctx.widgetConfig;
vm.subscription = vm.ctx.defaultSubscription;
vm.alarmSource = vm.subscription.alarmSource;
initializeConfig(); initializeConfig();
updateAlarmSource();
} }
}); });
@ -110,13 +119,6 @@ function AlarmsTableWidgetController($element, $scope, $filter, $mdMedia, $mdDia
} }
}); });
$scope.$watch('vm.subscription', function() {
if (vm.subscription) {
vm.alarmSource = vm.subscription.alarmSource;
updateAlarmSource();
}
});
$scope.$on('alarms-table-data-updated', function(event, tableId) { $scope.$on('alarms-table-data-updated', function(event, tableId) {
if (vm.tableId == tableId) { if (vm.tableId == tableId) {
if (vm.subscription) { if (vm.subscription) {
@ -140,13 +142,37 @@ function AlarmsTableWidgetController($element, $scope, $filter, $mdMedia, $mdDia
} }
}); });
$scope.$watch('vm.selectedAlarms.length', function (newLength) {
var selectionMode = newLength ? true : false;
if (vm.ctx) {
if (selectionMode) {
vm.ctx.hideTitlePanel = true;
} else if (vm.query.search == null) {
vm.ctx.hideTitlePanel = false;
}
}
});
function initializeConfig() { function initializeConfig() {
vm.ctx.widgetActions = [ vm.searchAction ];
if (vm.settings.alarmsTitle && vm.settings.alarmsTitle.length) { if (vm.settings.alarmsTitle && vm.settings.alarmsTitle.length) {
var translationId = types.translate.customTranslationsPrefix + vm.settings.alarmsTitle;
var translation = $translate.instant(translationId);
if (translation != translationId) {
vm.alarmsTitle = translation + '';
} else {
vm.alarmsTitle = vm.settings.alarmsTitle; vm.alarmsTitle = vm.settings.alarmsTitle;
} }
} else {
vm.alarmsTitle = $translate.instant('alarm.alarms');
}
vm.ctx.widgetTitle = vm.alarmsTitle;
vm.enableSelection = angular.isDefined(vm.settings.enableSelection) ? vm.settings.enableSelection : true; vm.enableSelection = angular.isDefined(vm.settings.enableSelection) ? vm.settings.enableSelection : true;
vm.enableSearch = angular.isDefined(vm.settings.enableSearch) ? vm.settings.enableSearch : true; vm.searchAction.show = angular.isDefined(vm.settings.enableSearch) ? vm.settings.enableSearch : true;
vm.displayDetails = angular.isDefined(vm.settings.displayDetails) ? vm.settings.displayDetails : true; vm.displayDetails = angular.isDefined(vm.settings.displayDetails) ? vm.settings.displayDetails : true;
vm.allowAcknowledgment = angular.isDefined(vm.settings.allowAcknowledgment) ? vm.settings.allowAcknowledgment : true; vm.allowAcknowledgment = angular.isDefined(vm.settings.allowAcknowledgment) ? vm.settings.allowAcknowledgment : true;
vm.allowClear = angular.isDefined(vm.settings.allowClear) ? vm.settings.allowClear : true; vm.allowClear = angular.isDefined(vm.settings.allowClear) ? vm.settings.allowClear : true;
@ -233,11 +259,13 @@ function AlarmsTableWidgetController($element, $scope, $filter, $mdMedia, $mdDia
function enterFilterMode () { function enterFilterMode () {
vm.query.search = ''; vm.query.search = '';
vm.ctx.hideTitlePanel = true;
} }
function exitFilterMode () { function exitFilterMode () {
vm.query.search = null; vm.query.search = null;
updateAlarms(); updateAlarms();
vm.ctx.hideTitlePanel = false;
} }
function onReorder () { function onReorder () {
@ -496,9 +524,7 @@ function AlarmsTableWidgetController($element, $scope, $filter, $mdMedia, $mdDia
function updateAlarmSource() { function updateAlarmSource() {
if (vm.settings.alarmsTitle && vm.settings.alarmsTitle.length) { vm.ctx.widgetTitle = utils.createLabelFromDatasource(vm.alarmSource, vm.alarmsTitle);
vm.alarmsTitle = utils.createLabelFromDatasource(vm.alarmSource, vm.settings.alarmsTitle);
}
vm.stylesInfo = {}; vm.stylesInfo = {};
vm.contentsInfo = {}; vm.contentsInfo = {};
@ -507,10 +533,10 @@ function AlarmsTableWidgetController($element, $scope, $filter, $mdMedia, $mdDia
for (var d = 0; d < vm.alarmSource.dataKeys.length; d++ ) { for (var d = 0; d < vm.alarmSource.dataKeys.length; d++ ) {
var dataKey = vm.alarmSource.dataKeys[d]; var dataKey = vm.alarmSource.dataKeys[d];
var translationId = types.translate.keyLabelPrefix + dataKey.label; var translationId = types.translate.customTranslationsPrefix + dataKey.label;
var translation = $translate.instant(translationId); var translation = $translate.instant(translationId);
if (translation != translationId) { if (translation != translationId) {
dataKey.title = translation; dataKey.title = translation + '';
} else { } else {
dataKey.title = dataKey.label; dataKey.title = dataKey.label;
} }

View File

@ -14,8 +14,32 @@
* limitations under the License. * limitations under the License.
*/ */
.tb-has-timewindow {
.tb-alarms-table {
md-toolbar {
min-height: 60px;
max-height: 60px;
&.md-table-toolbar {
.md-toolbar-tools {
max-height: 60px;
}
}
}
}
}
.tb-alarms-table { .tb-alarms-table {
margin-top: 15px;
md-toolbar {
min-height: 39px;
max-height: 39px;
&.md-table-toolbar {
.md-toolbar-tools {
max-height: 39px;
}
}
}
&.tb-data-table { &.tb-data-table {
table.md-table, table.md-table.md-row-select { table.md-table, table.md-table.md-row-select {
tbody { tbody {

View File

@ -17,19 +17,6 @@
--> -->
<div class="tb-absolute-fill tb-alarms-table tb-data-table" layout="column"> <div class="tb-absolute-fill tb-alarms-table tb-data-table" layout="column">
<div ng-show="vm.showData" flex class="tb-absolute-fill" layout="column"> <div ng-show="vm.showData" flex class="tb-absolute-fill" layout="column">
<md-toolbar class="md-table-toolbar md-default" ng-show="!vm.selectedAlarms.length
&& vm.query.search === null">
<div class="md-toolbar-tools">
<span>{{ vm.alarmsTitle }}</span>
<span flex></span>
<md-button ng-if="vm.enableSearch" class="md-icon-button" ng-click="vm.enterFilterMode()">
<md-icon>search</md-icon>
<md-tooltip md-direction="top">
{{ 'action.search' | translate }}
</md-tooltip>
</md-button>
</div>
</md-toolbar>
<md-toolbar class="md-table-toolbar md-default" ng-show="!vm.selectedAlarms.length && <md-toolbar class="md-table-toolbar md-default" ng-show="!vm.selectedAlarms.length &&
vm.query.search != null"> vm.query.search != null">
<div class="md-toolbar-tools"> <div class="md-toolbar-tools">