From f877e0d1bbeecc5c456fdf737871ea7203bc660a Mon Sep 17 00:00:00 2001 From: Shannon Date: Tue, 19 Jun 2018 12:20:18 +1000 Subject: [PATCH] Fixes delete animations --- .../components/tree/umbtree.directive.js | 104 ++++++------------ .../components/tree/umbtreeitem.directive.js | 104 +++++++++--------- .../src/common/services/navigation.service.js | 11 +- .../views/components/tree/umb-tree-item.html | 4 +- .../content/content.delete.controller.js | 42 ++++--- 5 files changed, 117 insertions(+), 148 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/tree/umbtree.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/tree/umbtree.directive.js index 07b3158a2a..2ddd3f00e6 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/tree/umbtree.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/tree/umbtree.directive.js @@ -3,7 +3,7 @@ * @name umbraco.directives.directive:umbTree * @restrict E **/ -function umbTreeDirective($compile, $log, $q, $rootScope, treeService, notificationsService, $timeout, userService) { +function umbTreeDirective($q, $rootScope, treeService, notificationsService, userService) { return { restrict: 'E', @@ -63,7 +63,8 @@ function umbTreeDirective($compile, $log, $q, $rootScope, treeService, notificat vm.emitEvent = emitEvent; vm.load = load; vm.reloadNode = reloadNode; - vm.syncTree = syncTree; + vm.syncTree = syncTree; + vm.loadChildren = loadChildren; //wire up the exposed api object for hosting controllers if ($scope.api) { @@ -81,9 +82,6 @@ function umbTreeDirective($compile, $log, $q, $rootScope, treeService, notificat // since it saves on data retreival and DOM processing. var lastSection = ""; - //flag to enable/disable delete animations - var deleteAnimations = false; - /** Helper function to emit tree events */ function emitEvent(eventName, args) { if (registeredCallbacks[eventName] && angular.isArray(registeredCallbacks[eventName])) { @@ -93,15 +91,6 @@ function umbTreeDirective($compile, $log, $q, $rootScope, treeService, notificat } } - /** This will deleteAnimations to true after the current digest */ - function enableDeleteAnimations() { - //do timeout so that it re-enables them after this digest - $timeout(function () { - //enable delete animations - deleteAnimations = true; - }, 0, false); - } - function clearCache(section) { treeService.clearCache({ section: section }); } @@ -189,9 +178,7 @@ function umbTreeDirective($compile, $log, $q, $rootScope, treeService, notificat args.path = args.path.splice(_.indexOf(args.path, found)); } }); - - deleteAnimations = false; - + var treeNode = loadActiveTree(args.tree); return treeService.syncTree({ @@ -205,9 +192,7 @@ function umbTreeDirective($compile, $log, $q, $rootScope, treeService, notificat } emitEvent("treeSynced", { node: data, activate: args.activate }); - - enableDeleteAnimations(); - + return $q.when({ node: data, activate: args.activate }); }); }); @@ -251,10 +236,7 @@ function umbTreeDirective($compile, $log, $q, $rootScope, treeService, notificat function loadTree() { if (!$scope.loading && $scope.section) { $scope.loading = true; - - //anytime we want to load the tree we need to disable the delete animations - deleteAnimations = false; - + //default args var args = { section: $scope.section, tree: $scope.treealias, cacheKey: $scope.cachekey, isDialog: $scope.isdialog ? $scope.isdialog : false, onlyinitialized: $scope.onlyInitialized }; @@ -269,8 +251,6 @@ function umbTreeDirective($compile, $log, $q, $rootScope, treeService, notificat //set the data once we have it $scope.tree = data; - enableDeleteAnimations(); - $scope.loading = false; //set the root as the current active tree @@ -289,6 +269,33 @@ function umbTreeDirective($compile, $log, $q, $rootScope, treeService, notificat return $q.reject(); } } + + function loadChildren(node, forceReload) { + //emit treeNodeExpanding event, if a callback object is set on the tree + emitEvent("treeNodeExpanding", { tree: $scope.tree, node: node }); + + //standardising + if (!node.children) { + node.children = []; + } + + if (forceReload || (node.hasChildren && node.children.length === 0)) { + //get the children from the tree service + return treeService.loadNodeChildren({ node: node, section: $scope.section }) + .then(function(data) { + //emit expanded event + emitEvent("treeNodeExpanded", { tree: $scope.tree, node: node, children: data }); + + return $q.when(data); + }); + } + else { + emitEvent("treeNodeExpanded", { tree: $scope.tree, node: node, children: node.children }); + node.expanded = true; + + return $q.when(node.children); + } + } /** Returns the css classses assigned to the node (div element) */ $scope.getNodeCssClass = function (node) { @@ -317,50 +324,9 @@ function umbTreeDirective($compile, $log, $q, $rootScope, treeService, notificat ''; }; - /** method to set the current animation for the node. - * This changes dynamically based on if we are changing sections or just loading normal tree data. - * When changing sections we don't want all of the tree-ndoes to do their 'leave' animations. - */ - $scope.animation = function () { - if (deleteAnimations && $scope.tree && $scope.tree.root && $scope.tree.root.expanded) { - return { leave: 'tree-node-delete-leave' }; - } - else { - return {}; - } - }; - /* helper to force reloading children of a tree node */ - $scope.loadChildren = function (node, forceReload) { - - //emit treeNodeExpanding event, if a callback object is set on the tree - emitEvent("treeNodeExpanding", { tree: $scope.tree, node: node }); - - //standardising - if (!node.children) { - node.children = []; - } - - if (forceReload || (node.hasChildren && node.children.length === 0)) { - //get the children from the tree service - return treeService.loadNodeChildren({ node: node, section: $scope.section }) - .then(function (data) { - //emit expanded event - emitEvent("treeNodeExpanded", { tree: $scope.tree, node: node, children: data }); - - enableDeleteAnimations(); - - return $q.when(data); - }); - } - else { - emitEvent("treeNodeExpanded", { tree: $scope.tree, node: node, children: node.children }); - node.expanded = true; - - enableDeleteAnimations(); - - return $q.when(node.children); - } + $scope.loadChildren = function(node, forceReload) { + return loadChildren(node, forceReload); }; /** diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/tree/umbtreeitem.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/tree/umbtreeitem.directive.js index d336d0d59e..dcb8a4df90 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/tree/umbtreeitem.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/tree/umbtreeitem.directive.js @@ -18,7 +18,7 @@ */ angular.module("umbraco.directives") -.directive('umbTreeItem', function ($compile, $http, $templateCache, $interpolate, $log, $location, $rootScope, $window, treeService, $timeout, localizationService) { + .directive('umbTreeItem', function(treeService, $timeout, localizationService, eventsService, appState) { return { restrict: 'E', replace: true, @@ -37,10 +37,7 @@ angular.module("umbraco.directives") localizationService.localize("general_search").then(function (value) { scope.searchAltText = value; }); - - //flag to enable/disable delete animations, default for an item is true - scope.deleteAnimations = true; - + // updates the node's DOM/styles function setupNodeDom(node, tree) { @@ -58,15 +55,6 @@ angular.module("umbraco.directives") } - //This will deleteAnimations to true after the current digest - function enableDeleteAnimations() { - //do timeout so that it re-enables them after this digest - $timeout(function () { - //enable delete animations - scope.deleteAnimations = true; - }, 0, false); - } - /** Returns the css classses assigned to the node (div element) */ scope.getNodeCssClass = function (node) { if (!node) { @@ -138,26 +126,10 @@ angular.module("umbraco.directives") and emits it as a treeNodeSelect element if there is a callback object defined on the tree */ - scope.altSelect = function (n, ev) { + scope.altSelect = function(n, ev) { umbTreeCtrl.emitEvent("treeNodeAltSelect", { element: element, tree: scope.tree, node: n, event: ev }); }; - - /** method to set the current animation for the node. - * This changes dynamically based on if we are changing sections or just loading normal tree data. - * When changing sections we don't want all of the tree-ndoes to do their 'leave' animations. - */ - scope.animation = function () { - if (scope.node.showHideAnimation) { - return scope.node.showHideAnimation; - } - if (scope.deleteAnimations && scope.node.expanded) { - return { leave: 'tree-node-delete-leave' }; - } - else { - return {}; - } - }; - + /** Method called when a node in the tree is expanded, when clicking the arrow takes the arrow DOM element and node data as parameters @@ -165,7 +137,6 @@ angular.module("umbraco.directives") */ scope.load = function (node) { if (node.expanded && !node.metaData.isContainer) { - scope.deleteAnimations = false; umbTreeCtrl.emitEvent("treeNodeCollapsing", { tree: scope.tree, node: node, element: element }); node.expanded = false; } @@ -175,28 +146,11 @@ angular.module("umbraco.directives") }; /* helper to force reloading children of a tree node */ - scope.loadChildren = function (node, forceReload) { - //emit treeNodeExpanding event, if a callback object is set on the tree - umbTreeCtrl.emitEvent("treeNodeExpanding", { tree: scope.tree, node: node }); - - if (node.hasChildren && (forceReload || !node.children || (angular.isArray(node.children) && node.children.length === 0))) { - //get the children from the tree service - treeService.loadNodeChildren({ node: node, section: scope.section }) - .then(function (data) { - //emit expanded event - umbTreeCtrl.emitEvent("treeNodeExpanded", { tree: scope.tree, node: node, children: data }); - enableDeleteAnimations(); - }); - } - else { - umbTreeCtrl.emitEvent("treeNodeExpanded", { tree: scope.tree, node: node, children: node.children }); - node.expanded = true; - enableDeleteAnimations(); - } - }; + scope.loadChildren = function(node, forceReload) { + return umbTreeCtrl.loadChildren(node, forceReload); + }; //if the current path contains the node id, we will auto-expand the tree item children - setupNodeDom(scope.node, scope.tree); // load the children if the current user don't have access to the node @@ -204,7 +158,49 @@ angular.module("umbraco.directives") if(scope.node.hasChildren && scope.node.metaData.noAccess) { scope.loadChildren(scope.node); } - + + var evts = []; + + //listen for section changes + evts.push(eventsService.on("appState.sectionState.changed", function(e, args) { + if (args.key === "currentSection") { + //when the section changes disable all delete animations + scope.node.deleteAnimations = false; + } + })); + + /** Depending on if any menu is shown and if the menu is shown for the current node, toggle delete animations */ + function toggleDeleteAnimations() { + //if both are false then remove animations + var hide = !appState.getMenuState("showMenuDialog") && !appState.getMenuState("showMenu"); + if (hide) { + scope.node.deleteAnimations = false; + } + else { + //enable animations for this node if it is the node currently showing a context menu + var currentNode = appState.getMenuState("currentNode"); + if (currentNode && currentNode.id == scope.node.id) { + scope.node.deleteAnimations = true; + } + else { + scope.node.deleteAnimations = false; + } + } + } + + //listen for context menu and current node changes + evts.push(eventsService.on("appState.menuState.changed", function(e, args) { + if (args.key === "showMenuDialog" || args.key == "showMenu" || args.key == "currentNode") { + toggleDeleteAnimations(); + } + })); + + //cleanup events + scope.$on('$destroy', function() { + for (var e in evts) { + eventsService.unsubscribe(evts[e]); + } + }); } }; }); diff --git a/src/Umbraco.Web.UI.Client/src/common/services/navigation.service.js b/src/Umbraco.Web.UI.Client/src/common/services/navigation.service.js index 726f23c45d..5cc0b9bb1e 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/navigation.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/navigation.service.js @@ -281,10 +281,9 @@ function navigationService($rootScope, $route, $routeParams, $log, $location, $q */ showMenu: function(args) { - var deferred = $q.defer(); var self = this; - treeService.getMenu({ treeNode: args.node }) + return treeService.getMenu({ treeNode: args.node }) .then(function(data) { //check for a default @@ -313,8 +312,7 @@ function navigationService($rootScope, $route, $routeParams, $log, $location, $q }); //return the dialog this is opening. - deferred.resolve(dialog); - return; + return $q.resolve(dialog); } } @@ -327,10 +325,9 @@ function navigationService($rootScope, $route, $routeParams, $log, $location, $q appState.setMenuState("dialogTitle", args.node.name); //we're not opening a dialog, return null. - deferred.resolve(null); + return $q.resolve(null); }); - - return deferred.promise; + }, /** diff --git a/src/Umbraco.Web.UI.Client/src/views/components/tree/umb-tree-item.html b/src/Umbraco.Web.UI.Client/src/views/components/tree/umb-tree-item.html index c52e6e88b9..d375f16835 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/tree/umb-tree-item.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/tree/umb-tree-item.html @@ -1,4 +1,4 @@ -
  • +
  •   - {{::node.name}} {{deleteAnimations}} + {{::node.name}} {{node.deleteAnimations}} diff --git a/src/Umbraco.Web.UI.Client/src/views/content/content.delete.controller.js b/src/Umbraco.Web.UI.Client/src/views/content/content.delete.controller.js index 863d06444c..3c112c292b 100644 --- a/src/Umbraco.Web.UI.Client/src/views/content/content.delete.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/content/content.delete.controller.js @@ -6,31 +6,41 @@ * @description * The controller for deleting content */ -function ContentDeleteController($scope, contentResource, treeService, navigationService, editorState, $location, dialogService, notificationsService) { - +function ContentDeleteController($scope, $timeout, contentResource, treeService, navigationService, editorState, $location, dialogService, notificationsService) { + + /** + * Used to toggle UI elements during delete operations + * @param {any} isDeleting + */ + function toggleDeleting(isDeleting) { + $scope.currentNode.loading = isDeleting; + $scope.busy = isDeleting; + } + $scope.performDelete = function() { // stop from firing again on double-click if ($scope.busy) { return false; } - //mark it for deletion (used in the UI) - $scope.currentNode.loading = true; - $scope.busy = true; + toggleDeleting(true); contentResource.deleteById($scope.currentNode.id).then(function () { - $scope.currentNode.loading = false; - + //get the root node before we remove it var rootNode = treeService.getTreeRoot($scope.currentNode); treeService.removeNode($scope.currentNode); + + toggleDeleting(false); - if (rootNode) { - //ensure the recycle bin has child nodes now - var recycleBin = treeService.getDescendantNode(rootNode, -20); - if (recycleBin) { - recycleBin.hasChildren = true; - } + if (rootNode) { + $timeout(function () { + //ensure the recycle bin has child nodes now + var recycleBin = treeService.getDescendantNode(rootNode, -20); + if (recycleBin) { + treeService.syncTree({ node: recycleBin, path: treeService.getPath(recycleBin), forceReload: true }); + } + }, 500); } //if the current edited item is the same one as we're deleting, we need to navigate elsewhere @@ -47,8 +57,7 @@ function ContentDeleteController($scope, contentResource, treeService, navigatio navigationService.hideMenu(); }, function(err) { - $scope.currentNode.loading = false; - $scope.busy = false; + toggleDeleting(false); //check if response is ysod if (err.status && err.status >= 500) { @@ -59,7 +68,8 @@ function ContentDeleteController($scope, contentResource, treeService, navigatio }; $scope.cancel = function() { - navigationService.hideDialog(); + toggleDeleting(false); + navigationService.hideDialog(); }; }