Fixes delete animations

This commit is contained in:
Shannon
2018-06-19 12:20:18 +10:00
parent ba408e8c79
commit f877e0d1bb
5 changed files with 117 additions and 148 deletions

View File

@@ -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);
};
/**

View File

@@ -18,7 +18,7 @@
</example>
*/
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]);
}
});
}
};
});

View File

@@ -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;
},
/**

View File

@@ -1,4 +1,4 @@
<li class="umb-tree-item" data-element="tree-item-{{::node.dataElement}}" ng-class="{'current': (node == currentNode), 'has-children': node.hasChildren, 'umb-tree-item--deleted': deleteAnimations}" on-right-click="altSelect(node, $event)">
<li class="umb-tree-item" data-element="tree-item-{{::node.dataElement}}" ng-class="{'current': (node == currentNode), 'has-children': node.hasChildren, 'umb-tree-item--deleted': node.deleteAnimations}" on-right-click="altSelect(node, $event)">
<div ng-class="getNodeCssClass(node)" ng-swipe-right="options(node, $event)" ng-dblclick="load(node)" >
<ins data-element="tree-item-expand"
ng-class="{'icon-navigation-right': !node.expanded || node.metaData.isContainer, 'icon-navigation-down': node.expanded && !node.metaData.isContainer}"
@@ -6,7 +6,7 @@
ng-click="load(node)">&nbsp;</ins>
<i class="icon umb-tree-icon sprTree" ng-class="::node.cssClass" title="{{::node.routePath}}" ng-click="select(node, $event)" ng-style="::node.style"></i>
<a class="umb-tree-item__label" ng-href="#/{{::node.routePath}}" ng-click="select(node, $event)">{{::node.name}} {{deleteAnimations}}</a>
<a class="umb-tree-item__label" ng-href="#/{{::node.routePath}}" ng-click="select(node, $event)">{{::node.name}} <small>{{node.deleteAnimations}}</small></a>
<!-- NOTE: These are the 'option' elipses -->
<a data-element="tree-item-options" class="umb-options" ng-click="options(node, $event)" ng-if="::node.menuUrl"><i></i><i></i><i></i></a>

View File

@@ -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();
};
}