diff --git a/ui/src/app/components/details-sidenav.directive.js b/ui/src/app/components/details-sidenav.directive.js
index a25374b..2516134 100644
--- a/ui/src/app/components/details-sidenav.directive.js
+++ b/ui/src/app/components/details-sidenav.directive.js
@@ -26,7 +26,7 @@ export default angular.module('thingsboard.directives.detailsSidenav', [])
.name;
/*@ngInject*/
-function DetailsSidenav($timeout, $window) {
+function DetailsSidenav($timeout, $mdUtil, $q, $animate) {
var linker = function (scope, element, attrs) {
@@ -42,22 +42,62 @@ function DetailsSidenav($timeout, $window) {
scope.isEdit = true;
}
- if (angular.isDefined(attrs.closeOnClickOutside && attrs.closeOnClickOutside)) {
- scope.closeOnClickOutside = true;
- var clickOutsideHandler = function() {
- scope.closeDetails();
- };
- angular.element($window).click(clickOutsideHandler);
- scope.$on("$destroy", function () {
- angular.element($window).unbind('click', clickOutsideHandler);
+ var backdrop;
+ var previousContainerStyles;
+
+ if (attrs.hasOwnProperty('tbEnableBackdrop')) {
+ backdrop = $mdUtil.createBackdrop(scope, "md-sidenav-backdrop md-opaque ng-enter");
+ element.on('$destroy', function() {
+ backdrop && backdrop.remove();
+ });
+ scope.$on('$destroy', function(){
+ backdrop && backdrop.remove();
+ });
+ scope.$watch('isOpen', updateIsOpen);
+ }
+
+ function updateIsOpen(isOpen) {
+ backdrop[isOpen ? 'on' : 'off']('click', (ev)=>{
+ ev.preventDefault();
+ scope.isOpen = false;
+ scope.$apply();
+ });
+ var parent = element.parent();
+ var restorePositioning = updateContainerPositions(parent, isOpen);
+
+ return $q.all([
+ isOpen && backdrop ? $animate.enter(backdrop, parent) : backdrop ?
+ $animate.leave(backdrop) : $q.when(true)
+ ]).then(function() {
+ restorePositioning && restorePositioning();
});
}
- scope.onClick = function($event) {
- if (scope.closeOnClickOutside) {
- $event.stopPropagation();
+ function updateContainerPositions(parent, willOpen) {
+ var drawerEl = element[0];
+ var scrollTop = parent[0].scrollTop;
+ if (willOpen && scrollTop) {
+ previousContainerStyles = {
+ top: drawerEl.style.top,
+ bottom: drawerEl.style.bottom,
+ height: drawerEl.style.height
+ };
+ var positionStyle = {
+ top: scrollTop + 'px',
+ bottom: 'auto',
+ height: parent[0].clientHeight + 'px'
+ };
+ backdrop.css(positionStyle);
}
- };
+ if (!willOpen && previousContainerStyles) {
+ return function() {
+ backdrop[0].style.top = null;
+ backdrop[0].style.bottom = null;
+ backdrop[0].style.height = null;
+ previousContainerStyles = null;
+ };
+ }
+ }
scope.toggleDetailsEditMode = function () {
if (!scope.isAlwaysEdit) {
diff --git a/ui/src/app/components/details-sidenav.tpl.html b/ui/src/app/components/details-sidenav.tpl.html
index a0032ff..763bc22 100644
--- a/ui/src/app/components/details-sidenav.tpl.html
+++ b/ui/src/app/components/details-sidenav.tpl.html
@@ -16,10 +16,9 @@
-->
<md-sidenav class="md-sidenav-right md-whiteframe-4dp tb-sidenav-details"
- md-disable-backdrop="true"
+ md-disable-backdrop
md-is-open="isOpen"
md-component-id="right"
- ng-click="onClick($event)"
layout="column">
<header>
<md-toolbar class="md-theme-light" ng-style="{'height':headerHeightPx+'px'}">
diff --git a/ui/src/app/rulechain/rulechain.tpl.html b/ui/src/app/rulechain/rulechain.tpl.html
index 0d55771..b25447e 100644
--- a/ui/src/app/rulechain/rulechain.tpl.html
+++ b/ui/src/app/rulechain/rulechain.tpl.html
@@ -69,7 +69,7 @@
+ ' - ' + vm.editingRuleNode.component.name}}"
is-read-only="vm.selectedRuleNodeTabIndex > 0"
is-open="vm.isEditingRuleNode"
- close-on-click-outside="true"
+ tb-enable-backdrop
is-always-edit="true"
on-close-details="vm.onEditRuleNodeClosed()"
on-toggle-details-edit-mode="vm.onRevertRuleNodeEdit(vm.ruleNodeForm)"
@@ -108,7 +108,7 @@
header-subtitle="{{'rulenode.link-details' | translate}}"
is-read-only="false"
is-open="vm.isEditingRuleNodeLink"
- close-on-click-outside="true"
+ tb-enable-backdrop
is-always-edit="true"
on-close-details="vm.onEditRuleNodeLinkClosed()"
on-toggle-details-edit-mode="vm.onRevertRuleNodeLinkEdit(vm.ruleNodeLinkForm)"