Browse Source

UI: Improve dashboard toolbar. Implement entity copy function.

pull/154/head
Igor Kulikov 9 years ago
parent
commit
ffc7a57e59
  1. 29
      ui/src/app/api/entity.service.js
  2. 1
      ui/src/app/common/dashboard-utils.service.js
  3. 51
      ui/src/app/components/expand-fullscreen.directive.js
  4. 4
      ui/src/app/dashboard/dashboard-settings.controller.js
  5. 3
      ui/src/app/dashboard/dashboard-settings.tpl.html
  6. 88
      ui/src/app/dashboard/dashboard-toolbar.directive.js
  7. 114
      ui/src/app/dashboard/dashboard-toolbar.scss
  8. 35
      ui/src/app/dashboard/dashboard-toolbar.tpl.html
  9. 17
      ui/src/app/dashboard/dashboard.controller.js
  10. 80
      ui/src/app/dashboard/dashboard.scss
  11. 190
      ui/src/app/dashboard/dashboard.tpl.html
  12. 2
      ui/src/app/dashboard/index.js
  13. 1
      ui/src/app/locale/locale.constant.js
  14. 2
      ui/src/scss/constants.scss

29
ui/src/app/api/entity.service.js

@ -36,7 +36,8 @@ function EntityService($http, $q, $filter, $translate, userService, deviceServic
saveRelatedEntity: saveRelatedEntity,
getRelatedEntity: getRelatedEntity,
deleteRelatedEntity: deleteRelatedEntity,
moveEntity: moveEntity
moveEntity: moveEntity,
copyEntity: copyEntity
};
return service;
@ -626,6 +627,32 @@ function EntityService($http, $q, $filter, $translate, userService, deviceServic
return deferred.promise;
}
function copyEntity(entity, targetParentId, keys) {
var deferred = $q.defer();
if (!entity.id && !entity.id.id) {
deferred.reject();
} else {
getRelatedEntity(entity.id, keys).then(
function success(relatedEntity) {
delete relatedEntity.id.id;
relatedEntity.name = entity.name;
saveRelatedEntity(relatedEntity, targetParentId, keys).then(
function success(savedEntity) {
deferred.resolve(savedEntity);
},
function fail() {
deferred.reject();
}
);
},
function fail() {
deferred.reject();
}
);
}
return deferred.promise;
}
function saveEntityPromise(entity) {
var entityType = entity.id.entityType;
if (!entity.id.id) {

1
ui/src/app/common/dashboard-utils.service.js

@ -179,6 +179,7 @@ function DashboardUtils(types, utils, timeService) {
dashboard.configuration.settings.showEntitiesSelect = true;
dashboard.configuration.settings.showDashboardTimewindow = true;
dashboard.configuration.settings.showDashboardExport = true;
dashboard.configuration.settings.toolbarAlwaysOpen = false;
} else {
if (angular.isUndefined(dashboard.configuration.settings.stateControllerId)) {
dashboard.configuration.settings.stateControllerId = 'default';

51
ui/src/app/components/expand-fullscreen.directive.js

@ -24,7 +24,7 @@ export default angular.module('thingsboard.directives.expandFullscreen', [])
/* eslint-disable angular/angularelement */
/*@ngInject*/
function ExpandFullscreen($compile, $document) {
function ExpandFullscreen($compile, $document, $timeout) {
var uniqueId = 1;
var linker = function (scope, element, attrs) {
@ -97,10 +97,6 @@ function ExpandFullscreen($compile, $document) {
scope.expanded = !scope.expanded;
}
var expandButton = null;
if (attrs.expandButtonId) {
expandButton = $('#' + attrs.expandButtonId, element)[0];
}
var buttonSize;
if (attrs.expandButtonSize) {
buttonSize = attrs.expandButtonSize;
@ -115,27 +111,38 @@ function ExpandFullscreen($compile, $document) {
'options=\'{"easing": "circ-in-out", "duration": 375, "rotation": "none"}\'>' +
'</ng-md-icon>';
if (expandButton) {
expandButton = angular.element(expandButton);
if (scope.hideExpandButton()) {
expandButton.remove();
} else {
expandButton.attr('md-ink-ripple', 'false');
expandButton.append(html);
if (attrs.expandButtonId) {
$timeout(function() {
var expandButton = $('#' + attrs.expandButtonId, element)[0];
renderExpandButton(expandButton);
});
} else {
renderExpandButton();
}
function renderExpandButton(expandButton) {
if (expandButton) {
expandButton = angular.element(expandButton);
if (scope.hideExpandButton()) {
expandButton.remove();
} else {
expandButton.attr('md-ink-ripple', 'false');
expandButton.append(html);
$compile(expandButton.contents())(scope);
$compile(expandButton.contents())(scope);
expandButton.on("click", scope.toggleExpand);
}
} else if (!scope.hideExpandButton()) {
var button = angular.element('<md-button class="tb-fullscreen-button-style tb-fullscreen-button-pos md-icon-button" ' +
'md-ink-ripple="false" ng-click="toggleExpand($event)">' +
html +
'</md-button>');
expandButton.on("click", scope.toggleExpand);
}
} else if (!scope.hideExpandButton()) {
var button = angular.element('<md-button class="tb-fullscreen-button-style tb-fullscreen-button-pos md-icon-button" ' +
'md-ink-ripple="false" ng-click="toggleExpand($event)">' +
html +
'</md-button>');
$compile(button)(scope);
$compile(button)(scope);
element.prepend(button);
element.prepend(button);
}
}
}

4
ui/src/app/dashboard/dashboard-settings.controller.js

@ -57,6 +57,10 @@ export default function DashboardSettingsController($scope, $mdDialog, statesCon
if (angular.isUndefined(vm.settings.showDashboardExport)) {
vm.settings.showDashboardExport = true;
}
if (angular.isUndefined(vm.settings.toolbarAlwaysOpen)) {
vm.settings.toolbarAlwaysOpen = false;
}
}
if (vm.gridSettings) {

3
ui/src/app/dashboard/dashboard-settings.tpl.html

@ -41,6 +41,9 @@
</md-select>
</md-input-container>
<div layout="row" layout-align="start center">
<md-checkbox flex aria-label="{{ 'dashboard.toolbar-always-open' | translate }}"
ng-model="vm.settings.toolbarAlwaysOpen">{{ 'dashboard.toolbar-always-open' | translate }}
</md-checkbox>
<md-checkbox flex aria-label="{{ 'dashboard.display-title' | translate }}"
ng-model="vm.settings.showTitle">{{ 'dashboard.display-title' | translate }}
</md-checkbox>

88
ui/src/app/dashboard/dashboard-toolbar.directive.js

@ -0,0 +1,88 @@
/*
* Copyright © 2016-2017 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.
*/
import './dashboard-toolbar.scss';
import 'javascript-detect-element-resize/detect-element-resize';
/* eslint-disable import/no-unresolved, import/default */
import dashboardToolbarTemplate from './dashboard-toolbar.tpl.html';
/* eslint-enable import/no-unresolved, import/default */
/*@ngInject*/
export default function DashboardToolbar() {
return {
restrict: "E",
scope: true,
transclude: true,
bindToController: {
toolbarOpened: '=',
forceFullscreen: '=',
onTriggerClick: '&'
},
controller: DashboardToolbarController,
controllerAs: 'vm',
templateUrl: dashboardToolbarTemplate
};
}
/* eslint-disable angular/angularelement */
/*@ngInject*/
function DashboardToolbarController($scope, $element, $timeout, mdFabToolbarAnimation) {
let vm = this;
vm.mdFabToolbarElement = angular.element($element[0].querySelector('md-fab-toolbar'));
$timeout(function() {
vm.mdFabBackgroundElement = angular.element(vm.mdFabToolbarElement[0].querySelector('.md-fab-toolbar-background'));
vm.mdFabTriggerElement = angular.element(vm.mdFabToolbarElement[0].querySelector('md-fab-trigger button'));
});
addResizeListener(vm.mdFabToolbarElement[0], triggerFabResize); // eslint-disable-line no-undef
$scope.$on("$destroy", function () {
removeResizeListener(vm.mdFabToolbarElement[0], triggerFabResize); // eslint-disable-line no-undef
});
function triggerFabResize() {
var ctrl = vm.mdFabToolbarElement.controller('mdFabToolbar');
if (ctrl.isOpen) {
if (!vm.mdFabBackgroundElement[0].offsetWidth) {
mdFabToolbarAnimation.addClass(vm.mdFabToolbarElement, 'md-is-open', function () {
});
} else {
var color = window.getComputedStyle(vm.mdFabTriggerElement[0]).getPropertyValue('background-color'); //eslint-disable-line
var width = vm.mdFabToolbarElement[0].offsetWidth;
var scale = 2 * (width / vm.mdFabTriggerElement[0].offsetWidth);
vm.mdFabBackgroundElement[0].style.backgroundColor = color;
vm.mdFabBackgroundElement[0].style.borderRadius = width + 'px';
var transform = vm.mdFabBackgroundElement[0].style.transform;
var targetTransform = 'scale(' + scale + ')';
if (!transform || !angular.equals(transform, targetTransform)) {
vm.mdFabBackgroundElement[0].style.transform = targetTransform;
}
}
}
}
}

114
ui/src/app/dashboard/dashboard-toolbar.scss

@ -0,0 +1,114 @@
/**
* Copyright © 2016-2017 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.
*/
@import "~compass-sass-mixins/lib/compass";
@import '../../scss/constants';
tb-dashboard-toolbar {
md-fab-toolbar {
&.md-is-open {
md-fab-trigger {
.md-button {
&.md-fab {
opacity: 1;
@include transition(opacity .3s cubic-bezier(.55,0,.55,.2));
.md-fab-toolbar-background {
background-color: $primary-default !important;
}
}
}
}
}
md-fab-trigger {
.md-button {
&.md-fab {
line-height: 36px;
width: 36px;
height: 36px;
margin: 4px 0 0 4px;
opacity: 0.5;
@include transition(opacity .3s cubic-bezier(.55,0,.55,.2) .2s);
md-icon {
position: absolute;
top: 25%;
margin: 0;
line-height: 18px;
height: 18px;
width: 18px;
min-height: 18px;
min-width: 18px;
}
}
}
}
&.is-fullscreen {
&.md-is-open {
md-fab-trigger {
.md-button {
&.md-fab {
.md-fab-toolbar-background {
transition-delay: 0ms !important;
transition-duration: 0ms !important;
}
}
}
}
}
.md-fab-toolbar-wrapper {
height: 64px;
md-toolbar {
min-height: 64px;
height: 64px;
}
}
}
.md-fab-toolbar-wrapper {
height: 50px;
md-toolbar {
min-height: 50px;
height: 50px;
md-fab-actions {
font-size: 16px;
margin-top: 0px;
.close-action {
margin-right: -18px;
}
.md-fab-action-item {
width: 100%;
height: 46px;
.tb-dashboard-action-panels {
height: 46px;
flex-direction: row-reverse;
.tb-dashboard-action-panel {
height: 46px;
flex-direction: row-reverse;
div {
height: 46px;
}
md-select {
pointer-events: all;
}
tb-states-component {
pointer-events: all;
}
}
}
}
}
}
}
}
}

35
ui/src/app/dashboard/dashboard-toolbar.tpl.html

@ -0,0 +1,35 @@
<!--
Copyright © 2016-2017 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-fab-toolbar md-open="vm.toolbarOpened"
md-direction="left"
ng-class="{'is-fullscreen': vm.forceFullscreen, 'md-whiteframe-z1': vm.forceFullscreen}">
<md-fab-trigger class="align-with-text">
<md-button aria-label="menu" class="md-fab md-primary" ng-click="vm.onTriggerClick()">
<md-tooltip ng-show="!vm.toolbarOpened" md-direction="bottom">
{{ 'dashboard.open-toolbar' | translate }}
</md-tooltip>
<md-icon aria-label="dashboard-toolbar" class="material-icons">more_horiz</md-icon>
</md-button>
</md-fab-trigger>
<md-toolbar>
<md-fab-actions class="md-toolbar-tools">
<div ng-transclude></div>
</md-fab-actions>
</md-toolbar>
</md-fab-toolbar>

17
ui/src/app/dashboard/dashboard.controller.js

@ -63,7 +63,9 @@ export default function DashboardController(types, dashboardUtils, widgetService
}
Object.defineProperty(vm, 'toolbarOpened', {
get: function() { return !vm.widgetEditMode && ($scope.forceFullscreen || vm.isToolbarOpened || vm.isEdit || vm.showRightLayoutSwitch()); },
get: function() {
return !vm.widgetEditMode &&
(toolbarAlwaysOpen() || $scope.forceFullscreen || vm.isToolbarOpened || vm.isEdit || vm.showRightLayoutSwitch()); },
set: function() { }
});
@ -103,9 +105,11 @@ export default function DashboardController(types, dashboardUtils, widgetService
}
vm.showCloseToolbar = function() {
return !$scope.forceFullscreen && !vm.isEdit && !vm.showRightLayoutSwitch();
return !vm.toolbarAlwaysOpen() && !$scope.forceFullscreen && !vm.isEdit && !vm.showRightLayoutSwitch();
}
vm.toolbarAlwaysOpen = toolbarAlwaysOpen;
vm.showRightLayoutSwitch = function() {
return vm.isMobile && vm.layouts.right.show;
}
@ -738,6 +742,15 @@ export default function DashboardController(types, dashboardUtils, widgetService
return link;
}
function toolbarAlwaysOpen() {
if (vm.dashboard && vm.dashboard.configuration.settings &&
angular.isDefined(vm.dashboard.configuration.settings.toolbarAlwaysOpen)) {
return vm.dashboard.configuration.settings.toolbarAlwaysOpen;
} else {
return false;
}
}
function displayTitle() {
if (vm.dashboard && vm.dashboard.configuration.settings &&
angular.isDefined(vm.dashboard.configuration.settings.showTitle)) {

80
ui/src/app/dashboard/dashboard.scss

@ -68,87 +68,23 @@ section.tb-dashboard-toolbar {
pointer-events: none;
&.tb-dashboard-toolbar-opened {
right: 0px;
@include transition(right .3s cubic-bezier(.55,0,.55,.2));
// @include transition(right .3s cubic-bezier(.55,0,.55,.2));
}
&.tb-dashboard-toolbar-closed {
right: 18px;
@include transition(right .3s cubic-bezier(.55,0,.55,.2) .2s);
}
md-fab-toolbar {
&.md-is-open {
md-fab-trigger {
.md-button {
&.md-fab {
opacity: 1;
@include transition(opacity .3s cubic-bezier(.55,0,.55,.2));
}
}
}
}
md-fab-trigger {
.md-button {
&.md-fab {
line-height: 36px;
width: 36px;
height: 36px;
margin: 4px 0 0 4px;
opacity: 0.5;
@include transition(opacity .3s cubic-bezier(.55,0,.55,.2) .2s);
md-icon {
position: absolute;
top: 25%;
margin: 0;
line-height: 18px;
height: 18px;
width: 18px;
min-height: 18px;
min-width: 18px;
}
}
}
}
.md-fab-toolbar-wrapper {
height: 50px;
md-toolbar {
min-height: 46px;
height: 46px;
md-fab-actions {
font-size: 16px;
margin-top: 0px;
.close-action {
margin-right: -18px;
}
.md-fab-action-item {
width: 100%;
height: 46px;
.tb-dashboard-action-panels {
height: 46px;
flex-direction: row-reverse;
.tb-dashboard-action-panel {
height: 46px;
flex-direction: row-reverse;
div {
height: 46px;
}
md-select {
pointer-events: all;
}
tb-states-component {
pointer-events: all;
}
}
}
}
}
}
}
}
}
.tb-dashboard-container {
&.tb-dashboard-toolbar-opened {
margin-top: 50px;
@include transition(margin-top .3s cubic-bezier(.55,0,.55,.2));
&.is-fullscreen {
margin-top: 64px;
}
&:not(.is-fullscreen) {
margin-top: 50px;
@include transition(margin-top .3s cubic-bezier(.55,0,.55,.2));
}
}
&.tb-dashboard-toolbar-closed {
margin-top: 0px;

190
ui/src/app/dashboard/dashboard.tpl.html

@ -19,110 +19,98 @@
hide-expand-button="vm.widgetEditMode || vm.iframeMode || forceFullscreen" expand-tooltip-direction="bottom">
<section class="tb-dashboard-toolbar" ng-show="vm.showDashboardToolbar()"
ng-class="{ 'tb-dashboard-toolbar-opened': vm.toolbarOpened, 'tb-dashboard-toolbar-closed': !vm.toolbarOpened }">
<md-fab-toolbar ng-show="!vm.widgetEditMode" md-open="vm.toolbarOpened"
md-direction="left">
<md-fab-trigger class="align-with-text">
<md-button aria-label="menu" class="md-fab md-primary" ng-click="vm.openToolbar()">
<md-tooltip ng-show="!vm.toolbarOpened" md-direction="bottom">
{{ 'dashboard.open-toolbar' | translate }}
</md-tooltip>
<md-icon aria-label="dashboard-toolbar" class="material-icons">more_horiz</md-icon>
</md-button>
</md-fab-trigger>
<md-toolbar>
<md-fab-actions class="md-toolbar-tools">
<div class="tb-dashboard-action-panels" flex layout="row" layout-align="start center">
<div class="tb-dashboard-action-panel" flex="50" layout="row" layout-align="start center">
<md-button ng-show="vm.showCloseToolbar()" aria-label="close-toolbar" class="md-icon-button close-action" ng-click="vm.closeToolbar()">
<md-tooltip md-direction="bottom">
{{ 'dashboard.close-toolbar' | translate }}
</md-tooltip>
<md-icon aria-label="close-toolbar" class="material-icons">arrow_forward</md-icon>
</md-button>
<md-button ng-show="vm.showRightLayoutSwitch()" aria-label="switch-layouts" class="md-icon-button" ng-click="vm.toggleLayouts()">
<ng-md-icon icon="{{vm.isRightLayoutOpened ? 'arrow_back' : 'menu'}}" options='{"easing": "circ-in-out", "duration": 375, "rotation": "none"}'></ng-md-icon>
<md-tooltip md-direction="bottom">
{{ (vm.isRightLayoutOpened ? 'dashboard.hide-details' : 'dashboard.show-details') | translate }}
</md-tooltip>
</md-button>
<md-button id="dashboard-expand-button"
aria-label="{{ 'fullscreen.fullscreen' | translate }}"
class="md-icon-button">
</md-button>
<tb-user-menu ng-if="!vm.isPublicUser() && forceFullscreen" display-user-info="true">
</tb-user-menu>
<md-button ng-show="vm.isEdit || vm.displayExport()"
aria-label="{{ 'action.export' | translate }}" class="md-icon-button"
ng-click="vm.exportDashboard($event)">
<md-tooltip md-direction="bottom">
{{ 'dashboard.export' | translate }}
</md-tooltip>
<md-icon aria-label="{{ 'action.export' | translate }}" class="material-icons">file_download</md-icon>
</md-button>
<tb-timewindow ng-show="vm.isEdit || vm.displayDashboardTimewindow()"
is-toolbar
direction="left"
tooltip-direction="bottom" aggregation
ng-model="vm.dashboardCtx.dashboardTimewindow">
</tb-timewindow>
<tb-aliases-entity-select ng-show="!vm.isEdit && vm.displayEntitiesSelect()"
tooltip-direction="bottom"
ng-model="vm.dashboardCtx.aliasesInfo.entityAliases"
entity-aliases-info="vm.dashboardCtx.aliasesInfo.entityAliasesInfo">
</tb-aliases-entity-select>
<md-button ng-show="vm.isEdit" aria-label="{{ 'entity.aliases' | translate }}" class="md-icon-button"
ng-click="vm.openEntityAliases($event)">
<md-tooltip md-direction="bottom">
{{ 'entity.aliases' | translate }}
</md-tooltip>
<md-icon aria-label="{{ 'entity.aliases' | translate }}" class="material-icons">devices_other</md-icon>
</md-button>
<md-button ng-show="vm.isEdit" aria-label="{{ 'dashboard.settings' | translate }}" class="md-icon-button"
ng-click="vm.openDashboardSettings($event)">
<md-tooltip md-direction="bottom">
{{ 'dashboard.settings' | translate }}
</md-tooltip>
<md-icon aria-label="{{ 'dashboard.settings' | translate }}" class="material-icons">settings</md-icon>
</md-button>
<tb-dashboard-select ng-show="!vm.isEdit && !vm.widgetEditMode && vm.displayDashboardsSelect()"
ng-model="vm.currentDashboardId"
dashboards-scope="{{vm.currentDashboardScope}}"
customer-id="vm.currentCustomerId">
</tb-dashboard-select>
</div>
<div class="tb-dashboard-action-panel" flex="50" layout="row" layout-align="end center">
<div layout="row" layout-align="start center" ng-show="vm.isEdit">
<md-button aria-label="{{ 'dashboard.manage-states' | translate }}" class="md-icon-button"
ng-click="vm.manageDashboardStates($event)">
<md-tooltip md-direction="bottom">
{{ 'dashboard.manage-states' | translate }}
</md-tooltip>
<md-icon aria-label="{{ 'dashboard.manage-states' | translate }}" class="material-icons">layers</md-icon>
</md-button>
<md-button aria-label="{{ 'layout.manage' | translate }}" class="md-icon-button"
ng-click="vm.manageDashboardLayouts($event)">
<md-tooltip md-direction="bottom">
{{ 'layout.manage' | translate }}
</md-tooltip>
<md-icon aria-label="{{ 'layout.manage' | translate }}" class="material-icons">view_compact</md-icon>
</md-button>
</div>
<div layout="row" layout-align="start center">
<tb-states-component ng-if="vm.isEdit" states-controller-id="'default'"
dashboard-ctrl="vm" states="vm.dashboardConfiguration.states">
</tb-states-component>
<tb-states-component ng-if="!vm.isEdit" states-controller-id="vm.dashboardConfiguration.settings.stateControllerId"
dashboard-ctrl="vm" states="vm.dashboardConfiguration.states">
</tb-states-component>
</div>
</div>
<tb-dashboard-toolbar ng-show="!vm.widgetEditMode" force-fullscreen="forceFullscreen"
toolbar-opened="vm.toolbarOpened" on-trigger-click="vm.openToolbar()">
<div class="tb-dashboard-action-panels" flex layout="row" layout-align="start center">
<div class="tb-dashboard-action-panel" flex="50" layout="row" layout-align="start center">
<md-button ng-show="vm.showCloseToolbar()" aria-label="close-toolbar" class="md-icon-button close-action" ng-click="vm.closeToolbar()">
<md-tooltip md-direction="bottom">
{{ 'dashboard.close-toolbar' | translate }}
</md-tooltip>
<md-icon aria-label="close-toolbar" class="material-icons">arrow_forward</md-icon>
</md-button>
<md-button ng-show="vm.showRightLayoutSwitch()" aria-label="switch-layouts" class="md-icon-button" ng-click="vm.toggleLayouts()">
<ng-md-icon icon="{{vm.isRightLayoutOpened ? 'arrow_back' : 'menu'}}" options='{"easing": "circ-in-out", "duration": 375, "rotation": "none"}'></ng-md-icon>
<md-tooltip md-direction="bottom">
{{ (vm.isRightLayoutOpened ? 'dashboard.hide-details' : 'dashboard.show-details') | translate }}
</md-tooltip>
</md-button>
<md-button id="dashboard-expand-button"
aria-label="{{ 'fullscreen.fullscreen' | translate }}"
class="md-icon-button">
</md-button>
<tb-user-menu ng-if="!vm.isPublicUser() && forceFullscreen" display-user-info="true">
</tb-user-menu>
<md-button ng-show="vm.isEdit || vm.displayExport()"
aria-label="{{ 'action.export' | translate }}" class="md-icon-button"
ng-click="vm.exportDashboard($event)">
<md-tooltip md-direction="bottom">
{{ 'dashboard.export' | translate }}
</md-tooltip>
<md-icon aria-label="{{ 'action.export' | translate }}" class="material-icons">file_download</md-icon>
</md-button>
<tb-timewindow ng-show="vm.isEdit || vm.displayDashboardTimewindow()"
is-toolbar
direction="left"
tooltip-direction="bottom" aggregation
ng-model="vm.dashboardCtx.dashboardTimewindow">
</tb-timewindow>
<tb-aliases-entity-select ng-show="!vm.isEdit && vm.displayEntitiesSelect()"
tooltip-direction="bottom"
ng-model="vm.dashboardCtx.aliasesInfo.entityAliases"
entity-aliases-info="vm.dashboardCtx.aliasesInfo.entityAliasesInfo">
</tb-aliases-entity-select>
<md-button ng-show="vm.isEdit" aria-label="{{ 'entity.aliases' | translate }}" class="md-icon-button"
ng-click="vm.openEntityAliases($event)">
<md-tooltip md-direction="bottom">
{{ 'entity.aliases' | translate }}
</md-tooltip>
<md-icon aria-label="{{ 'entity.aliases' | translate }}" class="material-icons">devices_other</md-icon>
</md-button>
<md-button ng-show="vm.isEdit" aria-label="{{ 'dashboard.settings' | translate }}" class="md-icon-button"
ng-click="vm.openDashboardSettings($event)">
<md-tooltip md-direction="bottom">
{{ 'dashboard.settings' | translate }}
</md-tooltip>
<md-icon aria-label="{{ 'dashboard.settings' | translate }}" class="material-icons">settings</md-icon>
</md-button>
<tb-dashboard-select ng-show="!vm.isEdit && !vm.widgetEditMode && vm.displayDashboardsSelect()"
ng-model="vm.currentDashboardId"
dashboards-scope="{{vm.currentDashboardScope}}"
customer-id="vm.currentCustomerId">
</tb-dashboard-select>
</div>
<div class="tb-dashboard-action-panel" flex="50" layout="row" layout-align="end center">
<div layout="row" layout-align="start center" ng-show="vm.isEdit">
<md-button aria-label="{{ 'dashboard.manage-states' | translate }}" class="md-icon-button"
ng-click="vm.manageDashboardStates($event)">
<md-tooltip md-direction="bottom">
{{ 'dashboard.manage-states' | translate }}
</md-tooltip>
<md-icon aria-label="{{ 'dashboard.manage-states' | translate }}" class="material-icons">layers</md-icon>
</md-button>
<md-button aria-label="{{ 'layout.manage' | translate }}" class="md-icon-button"
ng-click="vm.manageDashboardLayouts($event)">
<md-tooltip md-direction="bottom">
{{ 'layout.manage' | translate }}
</md-tooltip>
<md-icon aria-label="{{ 'layout.manage' | translate }}" class="material-icons">view_compact</md-icon>
</md-button>
</div>
</md-fab-actions>
</md-toolbar>
</md-fab-toolbar>
<div layout="row" layout-align="start center">
<tb-states-component ng-if="vm.isEdit" states-controller-id="'default'"
dashboard-ctrl="vm" states="vm.dashboardConfiguration.states">
</tb-states-component>
<tb-states-component ng-if="!vm.isEdit" states-controller-id="vm.dashboardConfiguration.settings.stateControllerId"
dashboard-ctrl="vm" states="vm.dashboardConfiguration.states">
</tb-states-component>
</div>
</div>
</div>
</tb-dashboard-toolbar>
</section>
<section class="tb-dashboard-container tb-absolute-fill"
ng-class="{ 'tb-dashboard-toolbar-opened': vm.toolbarOpened, 'tb-dashboard-toolbar-closed': !vm.toolbarOpened }">
ng-class="{ 'is-fullscreen': forceFullscreen, 'tb-dashboard-toolbar-opened': vm.toolbarOpened, 'tb-dashboard-toolbar-closed': !vm.toolbarOpened }">
<section ng-show="!loading && vm.dashboardConfigurationError()" layout-align="center center"
ng-style="{'color': vm.dashboard.configuration.settings.titleColor}"
ng-class="{'tb-padded' : !vm.widgetEditMode}"

2
ui/src/app/dashboard/index.js

@ -45,6 +45,7 @@ import AddDashboardsToCustomerController from './add-dashboards-to-customer.cont
import AddWidgetController from './add-widget.controller';
import DashboardDirective from './dashboard.directive';
import EditWidgetDirective from './edit-widget.directive';
import DashboardToolbar from './dashboard-toolbar.directive';
export default angular.module('thingsboard.dashboard', [
uiRouter,
@ -78,4 +79,5 @@ export default angular.module('thingsboard.dashboard', [
.controller('AddWidgetController', AddWidgetController)
.directive('tbDashboardDetails', DashboardDirective)
.directive('tbEditWidget', EditWidgetDirective)
.directive('tbDashboardToolbar', DashboardToolbar)
.name;

1
ui/src/app/locale/locale.constant.js

@ -328,6 +328,7 @@ export default angular.module('thingsboard.locale', [])
"min-vertical-margin-message": "Only 0 is allowed as minimum vertical margin value.",
"max-vertical-margin-message": "Only 50 is allowed as maximum vertical margin value.",
"display-title": "Display dashboard title",
"toolbar-always-open": "Keep toolbar opened",
"title-color": "Title color",
"display-dashboards-selection": "Display dashboards selection",
"display-entities-selection": "Display entities selection",

2
ui/src/scss/constants.scss

@ -20,10 +20,12 @@
$gray: #eee;
$primary-palette-color: 'indigo';
$default: '500';
$hue-1: '300';
$hue-2: '800';
$hue-3: 'a100';
$primary-default: #305680; //material-color($primary-palette-color, $default);
$primary-hue-1: material-color($primary-palette-color, $hue-1);
$primary-hue-2: material-color($primary-palette-color, $hue-2);
$primary-hue-3: rgb(207, 216, 220);

Loading…
Cancel
Save