Commit ffc7a57e59b5b6d670cd65b72a15889abd884948
1 parent
34c6c30e
UI: Improve dashboard toolbar. Implement entity copy function.
Showing
14 changed files
with
419 additions
and
198 deletions
... | ... | @@ -36,7 +36,8 @@ function EntityService($http, $q, $filter, $translate, userService, deviceServic |
36 | 36 | saveRelatedEntity: saveRelatedEntity, |
37 | 37 | getRelatedEntity: getRelatedEntity, |
38 | 38 | deleteRelatedEntity: deleteRelatedEntity, |
39 | - moveEntity: moveEntity | |
39 | + moveEntity: moveEntity, | |
40 | + copyEntity: copyEntity | |
40 | 41 | }; |
41 | 42 | |
42 | 43 | return service; |
... | ... | @@ -626,6 +627,32 @@ function EntityService($http, $q, $filter, $translate, userService, deviceServic |
626 | 627 | return deferred.promise; |
627 | 628 | } |
628 | 629 | |
630 | + function copyEntity(entity, targetParentId, keys) { | |
631 | + var deferred = $q.defer(); | |
632 | + if (!entity.id && !entity.id.id) { | |
633 | + deferred.reject(); | |
634 | + } else { | |
635 | + getRelatedEntity(entity.id, keys).then( | |
636 | + function success(relatedEntity) { | |
637 | + delete relatedEntity.id.id; | |
638 | + relatedEntity.name = entity.name; | |
639 | + saveRelatedEntity(relatedEntity, targetParentId, keys).then( | |
640 | + function success(savedEntity) { | |
641 | + deferred.resolve(savedEntity); | |
642 | + }, | |
643 | + function fail() { | |
644 | + deferred.reject(); | |
645 | + } | |
646 | + ); | |
647 | + }, | |
648 | + function fail() { | |
649 | + deferred.reject(); | |
650 | + } | |
651 | + ); | |
652 | + } | |
653 | + return deferred.promise; | |
654 | + } | |
655 | + | |
629 | 656 | function saveEntityPromise(entity) { |
630 | 657 | var entityType = entity.id.entityType; |
631 | 658 | if (!entity.id.id) { | ... | ... |
... | ... | @@ -179,6 +179,7 @@ function DashboardUtils(types, utils, timeService) { |
179 | 179 | dashboard.configuration.settings.showEntitiesSelect = true; |
180 | 180 | dashboard.configuration.settings.showDashboardTimewindow = true; |
181 | 181 | dashboard.configuration.settings.showDashboardExport = true; |
182 | + dashboard.configuration.settings.toolbarAlwaysOpen = false; | |
182 | 183 | } else { |
183 | 184 | if (angular.isUndefined(dashboard.configuration.settings.stateControllerId)) { |
184 | 185 | dashboard.configuration.settings.stateControllerId = 'default'; | ... | ... |
... | ... | @@ -24,7 +24,7 @@ export default angular.module('thingsboard.directives.expandFullscreen', []) |
24 | 24 | /* eslint-disable angular/angularelement */ |
25 | 25 | |
26 | 26 | /*@ngInject*/ |
27 | -function ExpandFullscreen($compile, $document) { | |
27 | +function ExpandFullscreen($compile, $document, $timeout) { | |
28 | 28 | |
29 | 29 | var uniqueId = 1; |
30 | 30 | var linker = function (scope, element, attrs) { |
... | ... | @@ -97,10 +97,6 @@ function ExpandFullscreen($compile, $document) { |
97 | 97 | scope.expanded = !scope.expanded; |
98 | 98 | } |
99 | 99 | |
100 | - var expandButton = null; | |
101 | - if (attrs.expandButtonId) { | |
102 | - expandButton = $('#' + attrs.expandButtonId, element)[0]; | |
103 | - } | |
104 | 100 | var buttonSize; |
105 | 101 | if (attrs.expandButtonSize) { |
106 | 102 | buttonSize = attrs.expandButtonSize; |
... | ... | @@ -115,27 +111,38 @@ function ExpandFullscreen($compile, $document) { |
115 | 111 | 'options=\'{"easing": "circ-in-out", "duration": 375, "rotation": "none"}\'>' + |
116 | 112 | '</ng-md-icon>'; |
117 | 113 | |
118 | - if (expandButton) { | |
119 | - expandButton = angular.element(expandButton); | |
120 | - if (scope.hideExpandButton()) { | |
121 | - expandButton.remove(); | |
122 | - } else { | |
123 | - expandButton.attr('md-ink-ripple', 'false'); | |
124 | - expandButton.append(html); | |
114 | + if (attrs.expandButtonId) { | |
115 | + $timeout(function() { | |
116 | + var expandButton = $('#' + attrs.expandButtonId, element)[0]; | |
117 | + renderExpandButton(expandButton); | |
118 | + }); | |
119 | + } else { | |
120 | + renderExpandButton(); | |
121 | + } | |
122 | + | |
123 | + function renderExpandButton(expandButton) { | |
124 | + if (expandButton) { | |
125 | + expandButton = angular.element(expandButton); | |
126 | + if (scope.hideExpandButton()) { | |
127 | + expandButton.remove(); | |
128 | + } else { | |
129 | + expandButton.attr('md-ink-ripple', 'false'); | |
130 | + expandButton.append(html); | |
125 | 131 | |
126 | - $compile(expandButton.contents())(scope); | |
132 | + $compile(expandButton.contents())(scope); | |
127 | 133 | |
128 | - expandButton.on("click", scope.toggleExpand); | |
129 | - } | |
130 | - } else if (!scope.hideExpandButton()) { | |
131 | - var button = angular.element('<md-button class="tb-fullscreen-button-style tb-fullscreen-button-pos md-icon-button" ' + | |
132 | - 'md-ink-ripple="false" ng-click="toggleExpand($event)">' + | |
133 | - html + | |
134 | - '</md-button>'); | |
134 | + expandButton.on("click", scope.toggleExpand); | |
135 | + } | |
136 | + } else if (!scope.hideExpandButton()) { | |
137 | + var button = angular.element('<md-button class="tb-fullscreen-button-style tb-fullscreen-button-pos md-icon-button" ' + | |
138 | + 'md-ink-ripple="false" ng-click="toggleExpand($event)">' + | |
139 | + html + | |
140 | + '</md-button>'); | |
135 | 141 | |
136 | - $compile(button)(scope); | |
142 | + $compile(button)(scope); | |
137 | 143 | |
138 | - element.prepend(button); | |
144 | + element.prepend(button); | |
145 | + } | |
139 | 146 | } |
140 | 147 | } |
141 | 148 | ... | ... |
... | ... | @@ -57,6 +57,10 @@ export default function DashboardSettingsController($scope, $mdDialog, statesCon |
57 | 57 | if (angular.isUndefined(vm.settings.showDashboardExport)) { |
58 | 58 | vm.settings.showDashboardExport = true; |
59 | 59 | } |
60 | + | |
61 | + if (angular.isUndefined(vm.settings.toolbarAlwaysOpen)) { | |
62 | + vm.settings.toolbarAlwaysOpen = false; | |
63 | + } | |
60 | 64 | } |
61 | 65 | |
62 | 66 | if (vm.gridSettings) { | ... | ... |
... | ... | @@ -41,6 +41,9 @@ |
41 | 41 | </md-select> |
42 | 42 | </md-input-container> |
43 | 43 | <div layout="row" layout-align="start center"> |
44 | + <md-checkbox flex aria-label="{{ 'dashboard.toolbar-always-open' | translate }}" | |
45 | + ng-model="vm.settings.toolbarAlwaysOpen">{{ 'dashboard.toolbar-always-open' | translate }} | |
46 | + </md-checkbox> | |
44 | 47 | <md-checkbox flex aria-label="{{ 'dashboard.display-title' | translate }}" |
45 | 48 | ng-model="vm.settings.showTitle">{{ 'dashboard.display-title' | translate }} |
46 | 49 | </md-checkbox> | ... | ... |
1 | +/* | |
2 | + * Copyright © 2016-2017 The Thingsboard Authors | |
3 | + * | |
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | |
5 | + * you may not use this file except in compliance with the License. | |
6 | + * You may obtain a copy of the License at | |
7 | + * | |
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | |
9 | + * | |
10 | + * Unless required by applicable law or agreed to in writing, software | |
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | |
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
13 | + * See the License for the specific language governing permissions and | |
14 | + * limitations under the License. | |
15 | + */ | |
16 | + | |
17 | +import './dashboard-toolbar.scss'; | |
18 | + | |
19 | +import 'javascript-detect-element-resize/detect-element-resize'; | |
20 | + | |
21 | +/* eslint-disable import/no-unresolved, import/default */ | |
22 | + | |
23 | +import dashboardToolbarTemplate from './dashboard-toolbar.tpl.html'; | |
24 | + | |
25 | +/* eslint-enable import/no-unresolved, import/default */ | |
26 | + | |
27 | +/*@ngInject*/ | |
28 | +export default function DashboardToolbar() { | |
29 | + return { | |
30 | + restrict: "E", | |
31 | + scope: true, | |
32 | + transclude: true, | |
33 | + bindToController: { | |
34 | + toolbarOpened: '=', | |
35 | + forceFullscreen: '=', | |
36 | + onTriggerClick: '&' | |
37 | + }, | |
38 | + controller: DashboardToolbarController, | |
39 | + controllerAs: 'vm', | |
40 | + templateUrl: dashboardToolbarTemplate | |
41 | + }; | |
42 | +} | |
43 | + | |
44 | +/* eslint-disable angular/angularelement */ | |
45 | + | |
46 | + | |
47 | +/*@ngInject*/ | |
48 | +function DashboardToolbarController($scope, $element, $timeout, mdFabToolbarAnimation) { | |
49 | + | |
50 | + let vm = this; | |
51 | + | |
52 | + vm.mdFabToolbarElement = angular.element($element[0].querySelector('md-fab-toolbar')); | |
53 | + | |
54 | + $timeout(function() { | |
55 | + vm.mdFabBackgroundElement = angular.element(vm.mdFabToolbarElement[0].querySelector('.md-fab-toolbar-background')); | |
56 | + vm.mdFabTriggerElement = angular.element(vm.mdFabToolbarElement[0].querySelector('md-fab-trigger button')); | |
57 | + }); | |
58 | + | |
59 | + addResizeListener(vm.mdFabToolbarElement[0], triggerFabResize); // eslint-disable-line no-undef | |
60 | + | |
61 | + $scope.$on("$destroy", function () { | |
62 | + removeResizeListener(vm.mdFabToolbarElement[0], triggerFabResize); // eslint-disable-line no-undef | |
63 | + }); | |
64 | + | |
65 | + function triggerFabResize() { | |
66 | + var ctrl = vm.mdFabToolbarElement.controller('mdFabToolbar'); | |
67 | + if (ctrl.isOpen) { | |
68 | + if (!vm.mdFabBackgroundElement[0].offsetWidth) { | |
69 | + mdFabToolbarAnimation.addClass(vm.mdFabToolbarElement, 'md-is-open', function () { | |
70 | + }); | |
71 | + } else { | |
72 | + var color = window.getComputedStyle(vm.mdFabTriggerElement[0]).getPropertyValue('background-color'); //eslint-disable-line | |
73 | + | |
74 | + var width = vm.mdFabToolbarElement[0].offsetWidth; | |
75 | + var scale = 2 * (width / vm.mdFabTriggerElement[0].offsetWidth); | |
76 | + vm.mdFabBackgroundElement[0].style.backgroundColor = color; | |
77 | + vm.mdFabBackgroundElement[0].style.borderRadius = width + 'px'; | |
78 | + | |
79 | + var transform = vm.mdFabBackgroundElement[0].style.transform; | |
80 | + var targetTransform = 'scale(' + scale + ')'; | |
81 | + if (!transform || !angular.equals(transform, targetTransform)) { | |
82 | + vm.mdFabBackgroundElement[0].style.transform = targetTransform; | |
83 | + } | |
84 | + } | |
85 | + } | |
86 | + } | |
87 | +} | |
88 | + | ... | ... |
ui/src/app/dashboard/dashboard-toolbar.scss
0 → 100644
1 | +/** | |
2 | + * Copyright © 2016-2017 The Thingsboard Authors | |
3 | + * | |
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | |
5 | + * you may not use this file except in compliance with the License. | |
6 | + * You may obtain a copy of the License at | |
7 | + * | |
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | |
9 | + * | |
10 | + * Unless required by applicable law or agreed to in writing, software | |
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | |
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
13 | + * See the License for the specific language governing permissions and | |
14 | + * limitations under the License. | |
15 | + */ | |
16 | + | |
17 | +@import "~compass-sass-mixins/lib/compass"; | |
18 | +@import '../../scss/constants'; | |
19 | + | |
20 | +tb-dashboard-toolbar { | |
21 | + md-fab-toolbar { | |
22 | + &.md-is-open { | |
23 | + md-fab-trigger { | |
24 | + .md-button { | |
25 | + &.md-fab { | |
26 | + opacity: 1; | |
27 | + @include transition(opacity .3s cubic-bezier(.55,0,.55,.2)); | |
28 | + .md-fab-toolbar-background { | |
29 | + background-color: $primary-default !important; | |
30 | + } | |
31 | + } | |
32 | + } | |
33 | + } | |
34 | + } | |
35 | + md-fab-trigger { | |
36 | + .md-button { | |
37 | + &.md-fab { | |
38 | + line-height: 36px; | |
39 | + width: 36px; | |
40 | + height: 36px; | |
41 | + margin: 4px 0 0 4px; | |
42 | + opacity: 0.5; | |
43 | + @include transition(opacity .3s cubic-bezier(.55,0,.55,.2) .2s); | |
44 | + md-icon { | |
45 | + position: absolute; | |
46 | + top: 25%; | |
47 | + margin: 0; | |
48 | + line-height: 18px; | |
49 | + height: 18px; | |
50 | + width: 18px; | |
51 | + min-height: 18px; | |
52 | + min-width: 18px; | |
53 | + } | |
54 | + } | |
55 | + } | |
56 | + } | |
57 | + &.is-fullscreen { | |
58 | + &.md-is-open { | |
59 | + md-fab-trigger { | |
60 | + .md-button { | |
61 | + &.md-fab { | |
62 | + .md-fab-toolbar-background { | |
63 | + transition-delay: 0ms !important; | |
64 | + transition-duration: 0ms !important; | |
65 | + } | |
66 | + } | |
67 | + } | |
68 | + } | |
69 | + } | |
70 | + .md-fab-toolbar-wrapper { | |
71 | + height: 64px; | |
72 | + md-toolbar { | |
73 | + min-height: 64px; | |
74 | + height: 64px; | |
75 | + } | |
76 | + } | |
77 | + } | |
78 | + .md-fab-toolbar-wrapper { | |
79 | + height: 50px; | |
80 | + md-toolbar { | |
81 | + min-height: 50px; | |
82 | + height: 50px; | |
83 | + md-fab-actions { | |
84 | + font-size: 16px; | |
85 | + margin-top: 0px; | |
86 | + .close-action { | |
87 | + margin-right: -18px; | |
88 | + } | |
89 | + .md-fab-action-item { | |
90 | + width: 100%; | |
91 | + height: 46px; | |
92 | + .tb-dashboard-action-panels { | |
93 | + height: 46px; | |
94 | + flex-direction: row-reverse; | |
95 | + .tb-dashboard-action-panel { | |
96 | + height: 46px; | |
97 | + flex-direction: row-reverse; | |
98 | + div { | |
99 | + height: 46px; | |
100 | + } | |
101 | + md-select { | |
102 | + pointer-events: all; | |
103 | + } | |
104 | + tb-states-component { | |
105 | + pointer-events: all; | |
106 | + } | |
107 | + } | |
108 | + } | |
109 | + } | |
110 | + } | |
111 | + } | |
112 | + } | |
113 | + } | |
114 | +} | |
\ No newline at end of file | ... | ... |
1 | +<!-- | |
2 | + | |
3 | + Copyright © 2016-2017 The Thingsboard Authors | |
4 | + | |
5 | + Licensed under the Apache License, Version 2.0 (the "License"); | |
6 | + you may not use this file except in compliance with the License. | |
7 | + You may obtain a copy of the License at | |
8 | + | |
9 | + http://www.apache.org/licenses/LICENSE-2.0 | |
10 | + | |
11 | + Unless required by applicable law or agreed to in writing, software | |
12 | + distributed under the License is distributed on an "AS IS" BASIS, | |
13 | + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
14 | + See the License for the specific language governing permissions and | |
15 | + limitations under the License. | |
16 | + | |
17 | +--> | |
18 | + | |
19 | +<md-fab-toolbar md-open="vm.toolbarOpened" | |
20 | + md-direction="left" | |
21 | + ng-class="{'is-fullscreen': vm.forceFullscreen, 'md-whiteframe-z1': vm.forceFullscreen}"> | |
22 | + <md-fab-trigger class="align-with-text"> | |
23 | + <md-button aria-label="menu" class="md-fab md-primary" ng-click="vm.onTriggerClick()"> | |
24 | + <md-tooltip ng-show="!vm.toolbarOpened" md-direction="bottom"> | |
25 | + {{ 'dashboard.open-toolbar' | translate }} | |
26 | + </md-tooltip> | |
27 | + <md-icon aria-label="dashboard-toolbar" class="material-icons">more_horiz</md-icon> | |
28 | + </md-button> | |
29 | + </md-fab-trigger> | |
30 | + <md-toolbar> | |
31 | + <md-fab-actions class="md-toolbar-tools"> | |
32 | + <div ng-transclude></div> | |
33 | + </md-fab-actions> | |
34 | + </md-toolbar> | |
35 | +</md-fab-toolbar> | ... | ... |
... | ... | @@ -63,7 +63,9 @@ export default function DashboardController(types, dashboardUtils, widgetService |
63 | 63 | } |
64 | 64 | |
65 | 65 | Object.defineProperty(vm, 'toolbarOpened', { |
66 | - get: function() { return !vm.widgetEditMode && ($scope.forceFullscreen || vm.isToolbarOpened || vm.isEdit || vm.showRightLayoutSwitch()); }, | |
66 | + get: function() { | |
67 | + return !vm.widgetEditMode && | |
68 | + (toolbarAlwaysOpen() || $scope.forceFullscreen || vm.isToolbarOpened || vm.isEdit || vm.showRightLayoutSwitch()); }, | |
67 | 69 | set: function() { } |
68 | 70 | }); |
69 | 71 | |
... | ... | @@ -103,9 +105,11 @@ export default function DashboardController(types, dashboardUtils, widgetService |
103 | 105 | } |
104 | 106 | |
105 | 107 | vm.showCloseToolbar = function() { |
106 | - return !$scope.forceFullscreen && !vm.isEdit && !vm.showRightLayoutSwitch(); | |
108 | + return !vm.toolbarAlwaysOpen() && !$scope.forceFullscreen && !vm.isEdit && !vm.showRightLayoutSwitch(); | |
107 | 109 | } |
108 | 110 | |
111 | + vm.toolbarAlwaysOpen = toolbarAlwaysOpen; | |
112 | + | |
109 | 113 | vm.showRightLayoutSwitch = function() { |
110 | 114 | return vm.isMobile && vm.layouts.right.show; |
111 | 115 | } |
... | ... | @@ -738,6 +742,15 @@ export default function DashboardController(types, dashboardUtils, widgetService |
738 | 742 | return link; |
739 | 743 | } |
740 | 744 | |
745 | + function toolbarAlwaysOpen() { | |
746 | + if (vm.dashboard && vm.dashboard.configuration.settings && | |
747 | + angular.isDefined(vm.dashboard.configuration.settings.toolbarAlwaysOpen)) { | |
748 | + return vm.dashboard.configuration.settings.toolbarAlwaysOpen; | |
749 | + } else { | |
750 | + return false; | |
751 | + } | |
752 | + } | |
753 | + | |
741 | 754 | function displayTitle() { |
742 | 755 | if (vm.dashboard && vm.dashboard.configuration.settings && |
743 | 756 | angular.isDefined(vm.dashboard.configuration.settings.showTitle)) { | ... | ... |
... | ... | @@ -68,87 +68,23 @@ section.tb-dashboard-toolbar { |
68 | 68 | pointer-events: none; |
69 | 69 | &.tb-dashboard-toolbar-opened { |
70 | 70 | right: 0px; |
71 | - @include transition(right .3s cubic-bezier(.55,0,.55,.2)); | |
71 | + // @include transition(right .3s cubic-bezier(.55,0,.55,.2)); | |
72 | 72 | } |
73 | 73 | &.tb-dashboard-toolbar-closed { |
74 | 74 | right: 18px; |
75 | 75 | @include transition(right .3s cubic-bezier(.55,0,.55,.2) .2s); |
76 | 76 | } |
77 | - md-fab-toolbar { | |
78 | - &.md-is-open { | |
79 | - md-fab-trigger { | |
80 | - .md-button { | |
81 | - &.md-fab { | |
82 | - opacity: 1; | |
83 | - @include transition(opacity .3s cubic-bezier(.55,0,.55,.2)); | |
84 | - } | |
85 | - } | |
86 | - } | |
87 | - } | |
88 | - md-fab-trigger { | |
89 | - .md-button { | |
90 | - &.md-fab { | |
91 | - line-height: 36px; | |
92 | - width: 36px; | |
93 | - height: 36px; | |
94 | - margin: 4px 0 0 4px; | |
95 | - opacity: 0.5; | |
96 | - @include transition(opacity .3s cubic-bezier(.55,0,.55,.2) .2s); | |
97 | - md-icon { | |
98 | - position: absolute; | |
99 | - top: 25%; | |
100 | - margin: 0; | |
101 | - line-height: 18px; | |
102 | - height: 18px; | |
103 | - width: 18px; | |
104 | - min-height: 18px; | |
105 | - min-width: 18px; | |
106 | - } | |
107 | - } | |
108 | - } | |
109 | - } | |
110 | - .md-fab-toolbar-wrapper { | |
111 | - height: 50px; | |
112 | - md-toolbar { | |
113 | - min-height: 46px; | |
114 | - height: 46px; | |
115 | - md-fab-actions { | |
116 | - font-size: 16px; | |
117 | - margin-top: 0px; | |
118 | - .close-action { | |
119 | - margin-right: -18px; | |
120 | - } | |
121 | - .md-fab-action-item { | |
122 | - width: 100%; | |
123 | - height: 46px; | |
124 | - .tb-dashboard-action-panels { | |
125 | - height: 46px; | |
126 | - flex-direction: row-reverse; | |
127 | - .tb-dashboard-action-panel { | |
128 | - height: 46px; | |
129 | - flex-direction: row-reverse; | |
130 | - div { | |
131 | - height: 46px; | |
132 | - } | |
133 | - md-select { | |
134 | - pointer-events: all; | |
135 | - } | |
136 | - tb-states-component { | |
137 | - pointer-events: all; | |
138 | - } | |
139 | - } | |
140 | - } | |
141 | - } | |
142 | - } | |
143 | - } | |
144 | - } | |
145 | - } | |
146 | 77 | } |
147 | 78 | |
148 | 79 | .tb-dashboard-container { |
149 | 80 | &.tb-dashboard-toolbar-opened { |
150 | - margin-top: 50px; | |
151 | - @include transition(margin-top .3s cubic-bezier(.55,0,.55,.2)); | |
81 | + &.is-fullscreen { | |
82 | + margin-top: 64px; | |
83 | + } | |
84 | + &:not(.is-fullscreen) { | |
85 | + margin-top: 50px; | |
86 | + @include transition(margin-top .3s cubic-bezier(.55,0,.55,.2)); | |
87 | + } | |
152 | 88 | } |
153 | 89 | &.tb-dashboard-toolbar-closed { |
154 | 90 | margin-top: 0px; | ... | ... |
... | ... | @@ -19,110 +19,98 @@ |
19 | 19 | hide-expand-button="vm.widgetEditMode || vm.iframeMode || forceFullscreen" expand-tooltip-direction="bottom"> |
20 | 20 | <section class="tb-dashboard-toolbar" ng-show="vm.showDashboardToolbar()" |
21 | 21 | ng-class="{ 'tb-dashboard-toolbar-opened': vm.toolbarOpened, 'tb-dashboard-toolbar-closed': !vm.toolbarOpened }"> |
22 | - <md-fab-toolbar ng-show="!vm.widgetEditMode" md-open="vm.toolbarOpened" | |
23 | - md-direction="left"> | |
24 | - <md-fab-trigger class="align-with-text"> | |
25 | - <md-button aria-label="menu" class="md-fab md-primary" ng-click="vm.openToolbar()"> | |
26 | - <md-tooltip ng-show="!vm.toolbarOpened" md-direction="bottom"> | |
27 | - {{ 'dashboard.open-toolbar' | translate }} | |
28 | - </md-tooltip> | |
29 | - <md-icon aria-label="dashboard-toolbar" class="material-icons">more_horiz</md-icon> | |
30 | - </md-button> | |
31 | - </md-fab-trigger> | |
32 | - <md-toolbar> | |
33 | - <md-fab-actions class="md-toolbar-tools"> | |
34 | - <div class="tb-dashboard-action-panels" flex layout="row" layout-align="start center"> | |
35 | - <div class="tb-dashboard-action-panel" flex="50" layout="row" layout-align="start center"> | |
36 | - <md-button ng-show="vm.showCloseToolbar()" aria-label="close-toolbar" class="md-icon-button close-action" ng-click="vm.closeToolbar()"> | |
37 | - <md-tooltip md-direction="bottom"> | |
38 | - {{ 'dashboard.close-toolbar' | translate }} | |
39 | - </md-tooltip> | |
40 | - <md-icon aria-label="close-toolbar" class="material-icons">arrow_forward</md-icon> | |
41 | - </md-button> | |
42 | - <md-button ng-show="vm.showRightLayoutSwitch()" aria-label="switch-layouts" class="md-icon-button" ng-click="vm.toggleLayouts()"> | |
43 | - <ng-md-icon icon="{{vm.isRightLayoutOpened ? 'arrow_back' : 'menu'}}" options='{"easing": "circ-in-out", "duration": 375, "rotation": "none"}'></ng-md-icon> | |
44 | - <md-tooltip md-direction="bottom"> | |
45 | - {{ (vm.isRightLayoutOpened ? 'dashboard.hide-details' : 'dashboard.show-details') | translate }} | |
46 | - </md-tooltip> | |
47 | - </md-button> | |
48 | - <md-button id="dashboard-expand-button" | |
49 | - aria-label="{{ 'fullscreen.fullscreen' | translate }}" | |
50 | - class="md-icon-button"> | |
51 | - </md-button> | |
52 | - <tb-user-menu ng-if="!vm.isPublicUser() && forceFullscreen" display-user-info="true"> | |
53 | - </tb-user-menu> | |
54 | - <md-button ng-show="vm.isEdit || vm.displayExport()" | |
55 | - aria-label="{{ 'action.export' | translate }}" class="md-icon-button" | |
56 | - ng-click="vm.exportDashboard($event)"> | |
57 | - <md-tooltip md-direction="bottom"> | |
58 | - {{ 'dashboard.export' | translate }} | |
59 | - </md-tooltip> | |
60 | - <md-icon aria-label="{{ 'action.export' | translate }}" class="material-icons">file_download</md-icon> | |
61 | - </md-button> | |
62 | - <tb-timewindow ng-show="vm.isEdit || vm.displayDashboardTimewindow()" | |
63 | - is-toolbar | |
64 | - direction="left" | |
65 | - tooltip-direction="bottom" aggregation | |
66 | - ng-model="vm.dashboardCtx.dashboardTimewindow"> | |
67 | - </tb-timewindow> | |
68 | - <tb-aliases-entity-select ng-show="!vm.isEdit && vm.displayEntitiesSelect()" | |
69 | - tooltip-direction="bottom" | |
70 | - ng-model="vm.dashboardCtx.aliasesInfo.entityAliases" | |
71 | - entity-aliases-info="vm.dashboardCtx.aliasesInfo.entityAliasesInfo"> | |
72 | - </tb-aliases-entity-select> | |
73 | - <md-button ng-show="vm.isEdit" aria-label="{{ 'entity.aliases' | translate }}" class="md-icon-button" | |
74 | - ng-click="vm.openEntityAliases($event)"> | |
75 | - <md-tooltip md-direction="bottom"> | |
76 | - {{ 'entity.aliases' | translate }} | |
77 | - </md-tooltip> | |
78 | - <md-icon aria-label="{{ 'entity.aliases' | translate }}" class="material-icons">devices_other</md-icon> | |
79 | - </md-button> | |
80 | - <md-button ng-show="vm.isEdit" aria-label="{{ 'dashboard.settings' | translate }}" class="md-icon-button" | |
81 | - ng-click="vm.openDashboardSettings($event)"> | |
82 | - <md-tooltip md-direction="bottom"> | |
83 | - {{ 'dashboard.settings' | translate }} | |
84 | - </md-tooltip> | |
85 | - <md-icon aria-label="{{ 'dashboard.settings' | translate }}" class="material-icons">settings</md-icon> | |
86 | - </md-button> | |
87 | - <tb-dashboard-select ng-show="!vm.isEdit && !vm.widgetEditMode && vm.displayDashboardsSelect()" | |
88 | - ng-model="vm.currentDashboardId" | |
89 | - dashboards-scope="{{vm.currentDashboardScope}}" | |
90 | - customer-id="vm.currentCustomerId"> | |
91 | - </tb-dashboard-select> | |
92 | - </div> | |
93 | - <div class="tb-dashboard-action-panel" flex="50" layout="row" layout-align="end center"> | |
94 | - <div layout="row" layout-align="start center" ng-show="vm.isEdit"> | |
95 | - <md-button aria-label="{{ 'dashboard.manage-states' | translate }}" class="md-icon-button" | |
96 | - ng-click="vm.manageDashboardStates($event)"> | |
97 | - <md-tooltip md-direction="bottom"> | |
98 | - {{ 'dashboard.manage-states' | translate }} | |
99 | - </md-tooltip> | |
100 | - <md-icon aria-label="{{ 'dashboard.manage-states' | translate }}" class="material-icons">layers</md-icon> | |
101 | - </md-button> | |
102 | - <md-button aria-label="{{ 'layout.manage' | translate }}" class="md-icon-button" | |
103 | - ng-click="vm.manageDashboardLayouts($event)"> | |
104 | - <md-tooltip md-direction="bottom"> | |
105 | - {{ 'layout.manage' | translate }} | |
106 | - </md-tooltip> | |
107 | - <md-icon aria-label="{{ 'layout.manage' | translate }}" class="material-icons">view_compact</md-icon> | |
108 | - </md-button> | |
109 | - </div> | |
110 | - <div layout="row" layout-align="start center"> | |
111 | - <tb-states-component ng-if="vm.isEdit" states-controller-id="'default'" | |
112 | - dashboard-ctrl="vm" states="vm.dashboardConfiguration.states"> | |
113 | - </tb-states-component> | |
114 | - <tb-states-component ng-if="!vm.isEdit" states-controller-id="vm.dashboardConfiguration.settings.stateControllerId" | |
115 | - dashboard-ctrl="vm" states="vm.dashboardConfiguration.states"> | |
116 | - </tb-states-component> | |
117 | - </div> | |
118 | - </div> | |
22 | + <tb-dashboard-toolbar ng-show="!vm.widgetEditMode" force-fullscreen="forceFullscreen" | |
23 | + toolbar-opened="vm.toolbarOpened" on-trigger-click="vm.openToolbar()"> | |
24 | + <div class="tb-dashboard-action-panels" flex layout="row" layout-align="start center"> | |
25 | + <div class="tb-dashboard-action-panel" flex="50" layout="row" layout-align="start center"> | |
26 | + <md-button ng-show="vm.showCloseToolbar()" aria-label="close-toolbar" class="md-icon-button close-action" ng-click="vm.closeToolbar()"> | |
27 | + <md-tooltip md-direction="bottom"> | |
28 | + {{ 'dashboard.close-toolbar' | translate }} | |
29 | + </md-tooltip> | |
30 | + <md-icon aria-label="close-toolbar" class="material-icons">arrow_forward</md-icon> | |
31 | + </md-button> | |
32 | + <md-button ng-show="vm.showRightLayoutSwitch()" aria-label="switch-layouts" class="md-icon-button" ng-click="vm.toggleLayouts()"> | |
33 | + <ng-md-icon icon="{{vm.isRightLayoutOpened ? 'arrow_back' : 'menu'}}" options='{"easing": "circ-in-out", "duration": 375, "rotation": "none"}'></ng-md-icon> | |
34 | + <md-tooltip md-direction="bottom"> | |
35 | + {{ (vm.isRightLayoutOpened ? 'dashboard.hide-details' : 'dashboard.show-details') | translate }} | |
36 | + </md-tooltip> | |
37 | + </md-button> | |
38 | + <md-button id="dashboard-expand-button" | |
39 | + aria-label="{{ 'fullscreen.fullscreen' | translate }}" | |
40 | + class="md-icon-button"> | |
41 | + </md-button> | |
42 | + <tb-user-menu ng-if="!vm.isPublicUser() && forceFullscreen" display-user-info="true"> | |
43 | + </tb-user-menu> | |
44 | + <md-button ng-show="vm.isEdit || vm.displayExport()" | |
45 | + aria-label="{{ 'action.export' | translate }}" class="md-icon-button" | |
46 | + ng-click="vm.exportDashboard($event)"> | |
47 | + <md-tooltip md-direction="bottom"> | |
48 | + {{ 'dashboard.export' | translate }} | |
49 | + </md-tooltip> | |
50 | + <md-icon aria-label="{{ 'action.export' | translate }}" class="material-icons">file_download</md-icon> | |
51 | + </md-button> | |
52 | + <tb-timewindow ng-show="vm.isEdit || vm.displayDashboardTimewindow()" | |
53 | + is-toolbar | |
54 | + direction="left" | |
55 | + tooltip-direction="bottom" aggregation | |
56 | + ng-model="vm.dashboardCtx.dashboardTimewindow"> | |
57 | + </tb-timewindow> | |
58 | + <tb-aliases-entity-select ng-show="!vm.isEdit && vm.displayEntitiesSelect()" | |
59 | + tooltip-direction="bottom" | |
60 | + ng-model="vm.dashboardCtx.aliasesInfo.entityAliases" | |
61 | + entity-aliases-info="vm.dashboardCtx.aliasesInfo.entityAliasesInfo"> | |
62 | + </tb-aliases-entity-select> | |
63 | + <md-button ng-show="vm.isEdit" aria-label="{{ 'entity.aliases' | translate }}" class="md-icon-button" | |
64 | + ng-click="vm.openEntityAliases($event)"> | |
65 | + <md-tooltip md-direction="bottom"> | |
66 | + {{ 'entity.aliases' | translate }} | |
67 | + </md-tooltip> | |
68 | + <md-icon aria-label="{{ 'entity.aliases' | translate }}" class="material-icons">devices_other</md-icon> | |
69 | + </md-button> | |
70 | + <md-button ng-show="vm.isEdit" aria-label="{{ 'dashboard.settings' | translate }}" class="md-icon-button" | |
71 | + ng-click="vm.openDashboardSettings($event)"> | |
72 | + <md-tooltip md-direction="bottom"> | |
73 | + {{ 'dashboard.settings' | translate }} | |
74 | + </md-tooltip> | |
75 | + <md-icon aria-label="{{ 'dashboard.settings' | translate }}" class="material-icons">settings</md-icon> | |
76 | + </md-button> | |
77 | + <tb-dashboard-select ng-show="!vm.isEdit && !vm.widgetEditMode && vm.displayDashboardsSelect()" | |
78 | + ng-model="vm.currentDashboardId" | |
79 | + dashboards-scope="{{vm.currentDashboardScope}}" | |
80 | + customer-id="vm.currentCustomerId"> | |
81 | + </tb-dashboard-select> | |
82 | + </div> | |
83 | + <div class="tb-dashboard-action-panel" flex="50" layout="row" layout-align="end center"> | |
84 | + <div layout="row" layout-align="start center" ng-show="vm.isEdit"> | |
85 | + <md-button aria-label="{{ 'dashboard.manage-states' | translate }}" class="md-icon-button" | |
86 | + ng-click="vm.manageDashboardStates($event)"> | |
87 | + <md-tooltip md-direction="bottom"> | |
88 | + {{ 'dashboard.manage-states' | translate }} | |
89 | + </md-tooltip> | |
90 | + <md-icon aria-label="{{ 'dashboard.manage-states' | translate }}" class="material-icons">layers</md-icon> | |
91 | + </md-button> | |
92 | + <md-button aria-label="{{ 'layout.manage' | translate }}" class="md-icon-button" | |
93 | + ng-click="vm.manageDashboardLayouts($event)"> | |
94 | + <md-tooltip md-direction="bottom"> | |
95 | + {{ 'layout.manage' | translate }} | |
96 | + </md-tooltip> | |
97 | + <md-icon aria-label="{{ 'layout.manage' | translate }}" class="material-icons">view_compact</md-icon> | |
98 | + </md-button> | |
119 | 99 | </div> |
120 | - </md-fab-actions> | |
121 | - </md-toolbar> | |
122 | - </md-fab-toolbar> | |
100 | + <div layout="row" layout-align="start center"> | |
101 | + <tb-states-component ng-if="vm.isEdit" states-controller-id="'default'" | |
102 | + dashboard-ctrl="vm" states="vm.dashboardConfiguration.states"> | |
103 | + </tb-states-component> | |
104 | + <tb-states-component ng-if="!vm.isEdit" states-controller-id="vm.dashboardConfiguration.settings.stateControllerId" | |
105 | + dashboard-ctrl="vm" states="vm.dashboardConfiguration.states"> | |
106 | + </tb-states-component> | |
107 | + </div> | |
108 | + </div> | |
109 | + </div> | |
110 | + </tb-dashboard-toolbar> | |
123 | 111 | </section> |
124 | 112 | <section class="tb-dashboard-container tb-absolute-fill" |
125 | - ng-class="{ 'tb-dashboard-toolbar-opened': vm.toolbarOpened, 'tb-dashboard-toolbar-closed': !vm.toolbarOpened }"> | |
113 | + ng-class="{ 'is-fullscreen': forceFullscreen, 'tb-dashboard-toolbar-opened': vm.toolbarOpened, 'tb-dashboard-toolbar-closed': !vm.toolbarOpened }"> | |
126 | 114 | <section ng-show="!loading && vm.dashboardConfigurationError()" layout-align="center center" |
127 | 115 | ng-style="{'color': vm.dashboard.configuration.settings.titleColor}" |
128 | 116 | ng-class="{'tb-padded' : !vm.widgetEditMode}" | ... | ... |
... | ... | @@ -45,6 +45,7 @@ import AddDashboardsToCustomerController from './add-dashboards-to-customer.cont |
45 | 45 | import AddWidgetController from './add-widget.controller'; |
46 | 46 | import DashboardDirective from './dashboard.directive'; |
47 | 47 | import EditWidgetDirective from './edit-widget.directive'; |
48 | +import DashboardToolbar from './dashboard-toolbar.directive'; | |
48 | 49 | |
49 | 50 | export default angular.module('thingsboard.dashboard', [ |
50 | 51 | uiRouter, |
... | ... | @@ -78,4 +79,5 @@ export default angular.module('thingsboard.dashboard', [ |
78 | 79 | .controller('AddWidgetController', AddWidgetController) |
79 | 80 | .directive('tbDashboardDetails', DashboardDirective) |
80 | 81 | .directive('tbEditWidget', EditWidgetDirective) |
82 | + .directive('tbDashboardToolbar', DashboardToolbar) | |
81 | 83 | .name; | ... | ... |
... | ... | @@ -328,6 +328,7 @@ export default angular.module('thingsboard.locale', []) |
328 | 328 | "min-vertical-margin-message": "Only 0 is allowed as minimum vertical margin value.", |
329 | 329 | "max-vertical-margin-message": "Only 50 is allowed as maximum vertical margin value.", |
330 | 330 | "display-title": "Display dashboard title", |
331 | + "toolbar-always-open": "Keep toolbar opened", | |
331 | 332 | "title-color": "Title color", |
332 | 333 | "display-dashboards-selection": "Display dashboards selection", |
333 | 334 | "display-entities-selection": "Display entities selection", | ... | ... |
... | ... | @@ -20,10 +20,12 @@ |
20 | 20 | $gray: #eee; |
21 | 21 | |
22 | 22 | $primary-palette-color: 'indigo'; |
23 | +$default: '500'; | |
23 | 24 | $hue-1: '300'; |
24 | 25 | $hue-2: '800'; |
25 | 26 | $hue-3: 'a100'; |
26 | 27 | |
28 | +$primary-default: #305680; //material-color($primary-palette-color, $default); | |
27 | 29 | $primary-hue-1: material-color($primary-palette-color, $hue-1); |
28 | 30 | $primary-hue-2: material-color($primary-palette-color, $hue-2); |
29 | 31 | $primary-hue-3: rgb(207, 216, 220); | ... | ... |