Browse Source

Alarms and Entities table widgets improvements.

pull/1065/merge
Igor Kulikov 8 years ago
parent
commit
8ea7058da4
  1. 8
      ui/src/app/api/subscription.js
  2. 10
      ui/src/app/locale/locale.constant-en_US.json
  3. 31
      ui/src/app/widget/lib/alarm-status-filter-panel.scss
  4. 28
      ui/src/app/widget/lib/alarm-status-filter-panel.tpl.html
  5. 190
      ui/src/app/widget/lib/alarms-table-widget.js
  6. 30
      ui/src/app/widget/lib/alarms-table-widget.scss
  7. 40
      ui/src/app/widget/lib/alarms-table-widget.tpl.html
  8. 31
      ui/src/app/widget/lib/display-columns-panel.scss
  9. 24
      ui/src/app/widget/lib/display-columns-panel.tpl.html
  10. 79
      ui/src/app/widget/lib/entities-table-widget.js
  11. 30
      ui/src/app/widget/lib/entities-table-widget.scss
  12. 27
      ui/src/app/widget/lib/entities-table-widget.tpl.html

8
ui/src/app/api/subscription.js

@ -267,6 +267,14 @@ export default class Subscription {
} else {
this.startWatchingTimewindow();
}
registration = this.ctx.$scope.$watch(function () {
return subscription.alarmSearchStatus;
}, function (newAlarmSearchStatus, prevAlarmSearchStatus) {
if (!angular.equals(newAlarmSearchStatus, prevAlarmSearchStatus)) {
subscription.update();
}
}, true);
this.registrations.push(registration);
}
initDataSubscription() {

10
ui/src/app/locale/locale.constant-en_US.json

@ -133,8 +133,13 @@
"min-polling-interval-message": "At least 1 sec polling interval is allowed.",
"aknowledge-alarms-title": "Acknowledge { count, plural, 1 {1 alarm} other {# alarms} }",
"aknowledge-alarms-text": "Are you sure you want to acknowledge { count, plural, 1 {1 alarm} other {# alarms} }?",
"aknowledge-alarm-title": "Acknowledge Alarm",
"aknowledge-alarm-text": "Are you sure you want to acknowledge Alarm?",
"clear-alarms-title": "Clear { count, plural, 1 {1 alarm} other {# alarms} }",
"clear-alarms-text": "Are you sure you want to clear { count, plural, 1 {1 alarm} other {# alarms} }?"
"clear-alarms-text": "Are you sure you want to clear { count, plural, 1 {1 alarm} other {# alarms} }?",
"clear-alarm-title": "Clear Alarm",
"clear-alarm-text": "Are you sure you want to clear Alarm?",
"alarm-status-filter": "Alarm Status Filter"
},
"alias": {
"add": "Add alias",
@ -748,7 +753,8 @@
"entity-name": "Entity name",
"details": "Entity details",
"no-entities-prompt": "No entities found",
"no-data": "No data to display"
"no-data": "No data to display",
"columns-to-display": "Columns to Display"
},
"event": {
"event-type": "Event type",

31
ui/src/app/widget/lib/alarm-status-filter-panel.scss

@ -0,0 +1,31 @@
/**
* Copyright © 2016-2018 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
.tb-alarm-status-filter-panel {
min-width: 300px;
overflow: hidden;
background: #fff;
border-radius: 4px;
box-shadow:
0 7px 8px -4px rgba(0, 0, 0, .2),
0 13px 19px 2px rgba(0, 0, 0, .14),
0 5px 24px 4px rgba(0, 0, 0, .12);
md-content {
overflow: hidden;
background-color: #fff;
}
}

28
ui/src/app/widget/lib/alarm-status-filter-panel.tpl.html

@ -0,0 +1,28 @@
<!--
Copyright © 2016-2018 The Thingsboard Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<md-content style="height: 100%" flex layout="column" class="md-padding">
<label class="tb-title" translate>alarm.alarm-status-filter</label>
<md-radio-group ng-model="vm.subscription.alarmSearchStatus" class="md-primary">
<md-radio-button ng-value="searchStatus"
aria-label="{{ ('alarm.search-status.' + searchStatus) | translate }}"
class="md-primary md-align-top-left md-radio-interactive" ng-repeat="searchStatus in vm.types.alarmSearchStatus">
{{ ('alarm.search-status.' + searchStatus) | translate }}
</md-radio-button>
</md-radio-group>
</md-content>

190
ui/src/app/widget/lib/alarms-table-widget.js

@ -14,11 +14,15 @@
* limitations under the License.
*/
import './alarms-table-widget.scss';
import './display-columns-panel.scss';
import './alarm-status-filter-panel.scss';
/* eslint-disable import/no-unresolved, import/default */
import alarmsTableWidgetTemplate from './alarms-table-widget.tpl.html';
import alarmDetailsDialogTemplate from '../../alarm/alarm-details-dialog.tpl.html';
import displayColumnsPanelTemplate from './display-columns-panel.tpl.html';
import alarmStatusFilterPanelTemplate from './alarm-status-filter-panel.tpl.html';
/* eslint-enable import/no-unresolved, import/default */
@ -45,7 +49,7 @@ function AlarmsTableWidget() {
}
/*@ngInject*/
function AlarmsTableWidgetController($element, $scope, $filter, $mdMedia, $mdDialog, $document, $translate, $q, $timeout, alarmService, utils, types) {
function AlarmsTableWidgetController($element, $scope, $filter, $mdMedia, $mdDialog, $mdPanel, $document, $translate, $q, $timeout, alarmService, utils, types) {
var vm = this;
vm.stylesInfo = {};
@ -60,6 +64,7 @@ function AlarmsTableWidgetController($element, $scope, $filter, $mdMedia, $mdDia
vm.selectedAlarms = []
vm.alarmSource = null;
vm.alarmSearchStatus = null;
vm.allAlarms = [];
vm.currentAlarm = null;
@ -95,14 +100,20 @@ function AlarmsTableWidgetController($element, $scope, $filter, $mdMedia, $mdDia
vm.onPaginate = onPaginate;
vm.onRowClick = onRowClick;
vm.onActionButtonClick = onActionButtonClick;
vm.actionEnabled = actionEnabled;
vm.isCurrent = isCurrent;
vm.openAlarmDetails = openAlarmDetails;
vm.ackAlarms = ackAlarms;
vm.ackAlarm = ackAlarm;
vm.clearAlarms = clearAlarms;
vm.clearAlarm = clearAlarm;
vm.cellStyle = cellStyle;
vm.cellContent = cellContent;
vm.editAlarmStatusFilter = editAlarmStatusFilter;
vm.editColumnsToDisplay = editColumnsToDisplay;
$scope.$watch('vm.ctx', function() {
if (vm.ctx) {
vm.settings = vm.ctx.settings;
@ -158,7 +169,41 @@ function AlarmsTableWidgetController($element, $scope, $filter, $mdMedia, $mdDia
vm.ctx.widgetActions = [ vm.searchAction ];
vm.actionCellDescriptors = vm.ctx.actionsApi.getActionDescriptors('actionCellButton');
vm.displayDetails = angular.isDefined(vm.settings.displayDetails) ? vm.settings.displayDetails : true;
vm.allowAcknowledgment = angular.isDefined(vm.settings.allowAcknowledgment) ? vm.settings.allowAcknowledgment : true;
vm.allowClear = angular.isDefined(vm.settings.allowClear) ? vm.settings.allowClear : true;
if (vm.displayDetails) {
vm.actionCellDescriptors.push(
{
displayName: $translate.instant('alarm.details'),
icon: 'more_horiz',
details: true
}
);
}
if (vm.allowAcknowledgment) {
vm.actionCellDescriptors.push(
{
displayName: $translate.instant('alarm.acknowledge'),
icon: 'done',
acknowledge: true
}
);
}
if (vm.allowClear) {
vm.actionCellDescriptors.push(
{
displayName: $translate.instant('alarm.clear'),
icon: 'clear',
clear: true
}
);
}
vm.actionCellDescriptors = vm.actionCellDescriptors.concat(vm.ctx.actionsApi.getActionDescriptors('actionCellButton'));
if (vm.settings.alarmsTitle && vm.settings.alarmsTitle.length) {
vm.alarmsTitle = utils.customTranslation(vm.settings.alarmsTitle, vm.settings.alarmsTitle);
@ -170,9 +215,6 @@ function AlarmsTableWidgetController($element, $scope, $filter, $mdMedia, $mdDia
vm.enableSelection = angular.isDefined(vm.settings.enableSelection) ? vm.settings.enableSelection : 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.allowAcknowledgment = angular.isDefined(vm.settings.allowAcknowledgment) ? vm.settings.allowAcknowledgment : true;
vm.allowClear = angular.isDefined(vm.settings.allowClear) ? vm.settings.allowClear : true;
if (!vm.allowAcknowledgment && !vm.allowClear) {
vm.enableSelection = false;
}
@ -305,16 +347,35 @@ function AlarmsTableWidgetController($element, $scope, $filter, $mdMedia, $mdDia
}
function onActionButtonClick($event, alarm, actionDescriptor) {
if ($event) {
$event.stopPropagation();
if (actionDescriptor.details) {
vm.openAlarmDetails($event, alarm);
} else if (actionDescriptor.acknowledge) {
vm.ackAlarm($event, alarm);
} else if (actionDescriptor.clear) {
vm.clearAlarm($event, alarm);
} else {
if ($event) {
$event.stopPropagation();
}
var entityId;
var entityName;
if (alarm && alarm.originator) {
entityId = alarm.originator;
entityName = alarm.originatorName;
}
vm.ctx.actionsApi.handleWidgetAction($event, actionDescriptor, entityId, entityName, {alarm: alarm});
}
var entityId;
var entityName;
if (alarm && alarm.originator) {
entityId = alarm.originator;
entityName = alarm.originatorName;
}
function actionEnabled(alarm, actionDescriptor) {
if (actionDescriptor.acknowledge) {
return (alarm.status == types.alarmStatus.activeUnack ||
alarm.status == types.alarmStatus.clearedUnack);
} else if (actionDescriptor.clear) {
return (alarm.status == types.alarmStatus.activeAck ||
alarm.status == types.alarmStatus.activeUnack);
}
vm.ctx.actionsApi.handleWidgetAction($event, actionDescriptor, entityId, entityName, { alarm: alarm });
return true;
}
function isCurrent(alarm) {
@ -387,6 +448,25 @@ function AlarmsTableWidgetController($element, $scope, $filter, $mdMedia, $mdDia
}
}
function ackAlarm($event, alarm) {
if ($event) {
$event.stopPropagation();
}
var confirm = $mdDialog.confirm()
.targetEvent($event)
.title($translate.instant('alarm.aknowledge-alarm-title'))
.htmlContent($translate.instant('alarm.aknowledge-alarm-text'))
.ariaLabel($translate.instant('alarm.acknowledge'))
.cancel($translate.instant('action.no'))
.ok($translate.instant('action.yes'));
$mdDialog.show(confirm).then(function () {
alarmService.ackAlarm(alarm.id.id).then(function () {
vm.selectedAlarms = [];
vm.subscription.update();
});
});
}
function clearAlarms($event) {
if ($event) {
$event.stopPropagation();
@ -420,6 +500,24 @@ function AlarmsTableWidgetController($element, $scope, $filter, $mdMedia, $mdDia
}
}
function clearAlarm($event, alarm) {
if ($event) {
$event.stopPropagation();
}
var confirm = $mdDialog.confirm()
.targetEvent($event)
.title($translate.instant('alarm.clear-alarm-title'))
.htmlContent($translate.instant('alarm.clear-alarm-text'))
.ariaLabel($translate.instant('alarm.clear'))
.cancel($translate.instant('action.no'))
.ok($translate.instant('action.yes'));
$mdDialog.show(confirm).then(function () {
alarmService.clearAlarm(alarm.id.id).then(function () {
vm.selectedAlarms = [];
vm.subscription.update();
});
});
}
function updateAlarms(preserveSelections) {
if (!preserveSelections) {
@ -558,6 +656,54 @@ function AlarmsTableWidgetController($element, $scope, $filter, $mdMedia, $mdDia
}
}
function editAlarmStatusFilter($event) {
var element = angular.element($event.target);
var position = $mdPanel.newPanelPosition()
.relativeTo(element)
.addPanelPosition($mdPanel.xPosition.ALIGN_END, $mdPanel.yPosition.BELOW);
var config = {
attachTo: angular.element($document[0].body),
controller: AlarmStatusFilterPanelController,
controllerAs: 'vm',
templateUrl: alarmStatusFilterPanelTemplate,
panelClass: 'tb-alarm-status-filter-panel',
position: position,
fullscreen: false,
locals: {
'subscription': vm.subscription
},
openFrom: $event,
clickOutsideToClose: true,
escapeToClose: true,
focusOnOpen: false
};
$mdPanel.open(config);
}
function editColumnsToDisplay($event) {
var element = angular.element($event.target);
var position = $mdPanel.newPanelPosition()
.relativeTo(element)
.addPanelPosition($mdPanel.xPosition.ALIGN_END, $mdPanel.yPosition.BELOW);
var config = {
attachTo: angular.element($document[0].body),
controller: DisplayColumnsPanelController,
controllerAs: 'vm',
templateUrl: displayColumnsPanelTemplate,
panelClass: 'tb-display-columns-panel',
position: position,
fullscreen: false,
locals: {
'columns': vm.alarmSource.dataKeys
},
openFrom: $event,
clickOutsideToClose: true,
escapeToClose: true,
focusOnOpen: false
};
$mdPanel.open(config);
}
function updateAlarmSource() {
vm.ctx.widgetTitle = utils.createLabelFromDatasource(vm.alarmSource, vm.alarmsTitle);
@ -570,6 +716,7 @@ function AlarmsTableWidgetController($element, $scope, $filter, $mdMedia, $mdDia
var dataKey = vm.alarmSource.dataKeys[d];
dataKey.title = utils.customTranslation(dataKey.label, dataKey.label);
dataKey.display = true;
var keySettings = dataKey.settings;
@ -618,4 +765,19 @@ function AlarmsTableWidgetController($element, $scope, $filter, $mdMedia, $mdDia
}
}
}
}
/*@ngInject*/
function DisplayColumnsPanelController(columns) { //eslint-disable-line
var vm = this;
vm.columns = columns;
}
/*@ngInject*/
function AlarmStatusFilterPanelController(subscription, types) { //eslint-disable-line
var vm = this;
vm.types = types;
vm.subscription = subscription;
}

30
ui/src/app/widget/lib/alarms-table-widget.scss

@ -44,6 +44,27 @@
&.tb-data-table {
table.md-table,
table.md-table.md-row-select {
th.md-column {
&.tb-action-cell {
.md-button {
/* stylelint-disable-next-line selector-max-class */
&.md-icon-button {
width: 36px;
height: 36px;
padding: 6px;
margin: 0;
/* stylelint-disable-next-line selector-max-class */
md-icon {
width: 24px;
height: 24px;
font-size: 24px !important;
line-height: 24px !important;
}
}
}
}
}
tbody {
tr {
td {
@ -51,6 +72,15 @@
width: 36px;
min-width: 36px;
max-width: 36px;
.md-button[disabled] {
&.md-icon-button {
/* stylelint-disable-next-line selector-max-class */
md-icon {
color: rgba(0, 0, 0, .38);
}
}
}
}
}
}

40
ui/src/app/widget/lib/alarms-table-widget.tpl.html

@ -62,33 +62,45 @@
<table md-table md-row-select="vm.enableSelection" multiple="" ng-model="vm.selectedAlarms">
<thead md-head md-order="vm.query.order" md-on-reorder="vm.onReorder">
<tr md-row>
<th md-column md-order-by="{{ key.name }}" ng-repeat="key in vm.alarmSource.dataKeys"><span>{{ key.title }}</span></th>
<th md-column ng-if="vm.displayDetails"><span>&nbsp</span></th>
<th md-column ng-if="vm.actionCellDescriptors.length"><span>&nbsp</span></th>
<th ng-if="key.display" md-column md-order-by="{{ key.name }}" ng-repeat="key in vm.alarmSource.dataKeys"><span>{{ key.title }}</span></th>
<th md-column class="tb-action-cell" layout="row" layout-align="end center">
<md-button class="md-icon-button"
aria-label="{{'alarm.alarm-status-filter' | translate}}"
ng-click="vm.editAlarmStatusFilter($event)">
<md-icon aria-label="{{'alarm.alarm-status-filter' | translate}}"
class="material-icons">filter_list
</md-icon>
<md-tooltip md-direction="top">
{{'alarm.alarm-status-filter' | translate}}
</md-tooltip>
</md-button>
<md-button class="md-icon-button"
aria-label="{{'entity.columns-to-display' | translate}}"
ng-click="vm.editColumnsToDisplay($event)">
<md-icon aria-label="{{'entity.columns-to-display' | translate}}"
class="material-icons">view_column
</md-icon>
<md-tooltip md-direction="top">
{{'entity.columns-to-display' | translate}}
</md-tooltip>
</md-button>
</th>
</tr>
</thead>
<tbody md-body>
<tr ng-show="vm.alarms.length" md-row md-select="alarm"
md-select-id="id.id" md-auto-select="false" ng-repeat="alarm in vm.alarms"
ng-click="vm.onRowClick($event, alarm)" ng-class="{'tb-current': vm.isCurrent(alarm)}">
<td md-cell flex ng-repeat="key in vm.alarmSource.dataKeys"
<td ng-if="key.display" md-cell flex ng-repeat="key in vm.alarmSource.dataKeys"
ng-style="vm.cellStyle(alarm, key)"
ng-bind-html="vm.cellContent(alarm, key)">
</td>
<td md-cell ng-if="vm.displayDetails" class="tb-action-cell">
<md-button class="md-icon-button" aria-label="{{ 'alarm.details' | translate }}"
ng-click="vm.openAlarmDetails($event, alarm)" ng-disabled="$root.loading">
<md-icon aria-label="{{ 'alarm.details' | translate }}" class="material-icons">more_horiz</md-icon>
<md-tooltip md-direction="top">
{{ 'alarm.details' | translate }}
</md-tooltip>
</md-button>
</td>
<td md-cell ng-if="vm.actionCellDescriptors.length" class="tb-action-cell"
<td md-cell class="tb-action-cell"
ng-style="{minWidth: vm.actionCellDescriptors.length*36+'px',
maxWidth: vm.actionCellDescriptors.length*36+'px',
width: vm.actionCellDescriptors.length*36+'px'}">
<md-button class="md-icon-button" ng-repeat="actionDescriptor in vm.actionCellDescriptors"
ng-disabled="!vm.actionEnabled(alarm, actionDescriptor)"
aria-label="{{ actionDescriptor.displayName }}"
ng-click="vm.onActionButtonClick($event, alarm, actionDescriptor)" ng-disabled="$root.loading">
<md-icon aria-label="{{ actionDescriptor.displayName }}" class="material-icons">{{actionDescriptor.icon}}</md-icon>

31
ui/src/app/widget/lib/display-columns-panel.scss

@ -0,0 +1,31 @@
/**
* Copyright © 2016-2018 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
.tb-display-columns-panel {
min-width: 300px;
overflow: hidden;
background: #fff;
border-radius: 4px;
box-shadow:
0 7px 8px -4px rgba(0, 0, 0, .2),
0 13px 19px 2px rgba(0, 0, 0, .14),
0 5px 24px 4px rgba(0, 0, 0, .12);
md-content {
overflow: hidden;
background-color: #fff;
}
}

24
ui/src/app/widget/lib/display-columns-panel.tpl.html

@ -0,0 +1,24 @@
<!--
Copyright © 2016-2018 The Thingsboard Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<md-content style="height: 100%" flex layout="column" class="md-padding">
<label class="tb-title" translate>entity.columns-to-display</label>
<md-checkbox aria-label="{{ 'entity.columns-to-display' | translate }}" ng-repeat="column in vm.columns"
ng-model="column.display">{{ column.title }}
</md-checkbox>
</md-content>

79
ui/src/app/widget/lib/entities-table-widget.js

@ -14,11 +14,13 @@
* limitations under the License.
*/
import './entities-table-widget.scss';
import './display-columns-panel.scss';
/* eslint-disable import/no-unresolved, import/default */
import entitiesTableWidgetTemplate from './entities-table-widget.tpl.html';
//import entityDetailsDialogTemplate from './entitiy-details-dialog.tpl.html';
import displayColumnsPanelTemplate from './display-columns-panel.tpl.html';
/* eslint-enable import/no-unresolved, import/default */
@ -45,7 +47,7 @@ function EntitiesTableWidget() {
}
/*@ngInject*/
function EntitiesTableWidgetController($element, $scope, $filter, $mdMedia, $translate, $timeout, utils, types) {
function EntitiesTableWidgetController($element, $scope, $filter, $mdMedia, $mdPanel, $document, $translate, $timeout, utils, types) {
var vm = this;
vm.stylesInfo = {};
@ -98,6 +100,8 @@ function EntitiesTableWidgetController($element, $scope, $filter, $mdMedia, $tra
vm.cellStyle = cellStyle;
vm.cellContent = cellContent;
vm.editColumnsToDisplay = editColumnsToDisplay;
$scope.$watch('vm.ctx', function() {
if (vm.ctx && vm.ctx.defaultSubscription) {
vm.settings = vm.ctx.settings;
@ -414,12 +418,37 @@ function EntitiesTableWidgetController($element, $scope, $filter, $mdMedia, $tra
}
}
function editColumnsToDisplay($event) {
var element = angular.element($event.target);
var position = $mdPanel.newPanelPosition()
.relativeTo(element)
.addPanelPosition($mdPanel.xPosition.ALIGN_END, $mdPanel.yPosition.BELOW);
var config = {
attachTo: angular.element($document[0].body),
controller: DisplayColumnsPanelController,
controllerAs: 'vm',
templateUrl: displayColumnsPanelTemplate,
panelClass: 'tb-display-columns-panel',
position: position,
fullscreen: false,
locals: {
'columns': vm.columns
},
openFrom: $event,
clickOutsideToClose: true,
escapeToClose: true,
focusOnOpen: false
};
$mdPanel.open(config);
}
function updateDatasources() {
vm.stylesInfo = {};
vm.contentsInfo = {};
vm.columnWidth = {};
vm.dataKeys = [];
vm.columns = [];
vm.allEntities = [];
var datasource;
@ -429,6 +458,42 @@ function EntitiesTableWidgetController($element, $scope, $filter, $mdMedia, $tra
vm.ctx.widgetTitle = utils.createLabelFromDatasource(datasource, vm.entitiesTitle);
if (vm.displayEntityName) {
vm.columns.push(
{
name: 'entityName',
label: 'entityName',
title: vm.entityNameColumnTitle,
display: true
}
);
vm.contentsInfo['entityName'] = {
useCellContentFunction: false
};
vm.stylesInfo['entityName'] = {
useCellStyleFunction: false
};
vm.columnWidth['entityName'] = '0px';
}
if (vm.displayEntityType) {
vm.columns.push(
{
name: 'entityType',
label: 'entityType',
title: $translate.instant('entity.entity-type'),
display: true
}
);
vm.contentsInfo['entityType'] = {
useCellContentFunction: false
};
vm.stylesInfo['entityType'] = {
useCellStyleFunction: false
};
vm.columnWidth['entityType'] = '0px';
}
for (var d = 0; d < datasource.dataKeys.length; d++ ) {
dataKey = angular.copy(datasource.dataKeys[d]);
if (dataKey.type == types.dataKeyType.function) {
@ -482,6 +547,9 @@ function EntitiesTableWidgetController($element, $scope, $filter, $mdMedia, $tra
var columnWidth = angular.isDefined(keySettings.columnWidth) ? keySettings.columnWidth : '0px';
vm.columnWidth[dataKey.label] = columnWidth;
dataKey.display = true;
vm.columns.push(dataKey);
}
for (var i=0;i<vm.datasources.length;i++) {
@ -511,4 +579,11 @@ function EntitiesTableWidgetController($element, $scope, $filter, $mdMedia, $tra
}
}
}
/*@ngInject*/
function DisplayColumnsPanelController(columns) { //eslint-disable-line
var vm = this;
vm.columns = columns;
}

30
ui/src/app/widget/lib/entities-table-widget.scss

@ -44,6 +44,27 @@
&.tb-data-table {
table.md-table,
table.md-table.md-row-select {
th.md-column {
&.tb-action-cell {
.md-button {
/* stylelint-disable-next-line selector-max-class */
&.md-icon-button {
width: 36px;
height: 36px;
padding: 6px;
margin: 0;
/* stylelint-disable-next-line selector-max-class */
md-icon {
width: 24px;
height: 24px;
font-size: 24px !important;
line-height: 24px !important;
}
}
}
}
}
tbody {
tr {
td {
@ -51,6 +72,15 @@
width: 36px;
min-width: 36px;
max-width: 36px;
.md-button[disabled] {
&.md-icon-button {
/* stylelint-disable-next-line selector-max-class */
md-icon {
color: rgba(0, 0, 0, .38);
}
}
}
}
}
}

27
ui/src/app/widget/lib/entities-table-widget.tpl.html

@ -41,23 +41,30 @@
<table md-table>
<thead md-head md-order="vm.query.order" md-on-reorder="vm.onReorder">
<tr md-row>
<th md-column ng-if="vm.displayEntityName" md-order-by="entityName"><span>{{vm.entityNameColumnTitle}}</span></th>
<th md-column ng-if="vm.displayEntityType" md-order-by="entityType"><span translate>entity.entity-type</span></th>
<th md-column md-order-by="{{ key.name }}" ng-repeat="key in vm.dataKeys"><span>{{ key.title }}</span></th>
<th md-column ng-if="vm.actionCellDescriptors.length"><span>&nbsp</span></th>
<th ng-if="column.display" md-column md-order-by="{{ column.name }}" ng-repeat="column in vm.columns"><span>{{ column.title }}</span></th>
<th md-column class="tb-action-cell" layout="row" layout-align="end center">
<md-button class="md-icon-button"
aria-label="{{'entity.columns-to-display' | translate}}"
ng-click="vm.editColumnsToDisplay($event)">
<md-icon aria-label="{{'entity.columns-to-display' | translate}}"
class="material-icons">view_column
</md-icon>
<md-tooltip md-direction="top">
{{'entity.columns-to-display' | translate}}
</md-tooltip>
</md-button>
</th>
</tr>
</thead>
<tbody md-body>
<tr ng-show="vm.entities.length" md-row md-select="entity"
md-select-id="id.id" md-auto-select="false" ng-repeat="entity in vm.entities"
ng-click="vm.onRowClick($event, entity)" ng-class="{'tb-current': vm.isCurrent(entity)}">
<td md-cell flex ng-if="vm.displayEntityName">{{entity.entityName}}</td>
<td md-cell flex ng-if="vm.displayEntityType">{{entity.entityType}}</td>
<td md-cell flex ng-repeat="key in vm.dataKeys"
ng-style="vm.cellStyle(entity, key)"
ng-bind-html="vm.cellContent(entity, key)">
<td ng-if="column.display" md-cell flex ng-repeat="column in vm.columns"
ng-style="vm.cellStyle(entity, column)"
ng-bind-html="vm.cellContent(entity, column)">
</td>
<td md-cell ng-if="vm.actionCellDescriptors.length" class="tb-action-cell"
<td md-cell class="tb-action-cell"
ng-style="{minWidth: vm.actionCellDescriptors.length*36+'px',
maxWidth: vm.actionCellDescriptors.length*36+'px',
width: vm.actionCellDescriptors.length*36+'px'}">

Loading…
Cancel
Save