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 23f3fb6d58..ecc92263bc 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 @@ -30,12 +30,6 @@ function navigationService($routeParams, $location, $q, $timeout, $injector, eve var nonRoutingQueryStrings = ["mculture", "cculture"]; var retainedQueryStrings = ['mculture']; - //used to track the current dialog object - var currentDialog = null; - - //tracks the user profile dialog - var userDialog = null; - function setMode(mode) { switch (mode) { case 'tree': @@ -287,7 +281,7 @@ function navigationService($routeParams, $location, $q, $timeout, $injector, eve appState.setGlobalState("showTray", false); }, - /** + /** * @ngdoc method * @name umbraco.services.navigationService#syncTree * @methodOf umbraco.services.navigationService 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 d4be18cf05..92e02d0d14 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 @@ -34,22 +34,25 @@ function ContentDeleteController($scope, $timeout, contentResource, treeService, toggleDeleting(false); if (rootNode) { - $timeout(function () { - //ensure the recycle bin has child nodes now - var recycleBin = treeService.getDescendantNode(rootNode, -20); - if (recycleBin) { - //TODO: This seems to return a rejection and we end up with "Possibly unhanded rejection" - treeService.syncTree({ node: recycleBin, path: treeService.getPath(recycleBin), forceReload: true }); + //ensure the recycle bin has child nodes now + var recycleBin = treeService.getDescendantNode(rootNode, -20); + if (recycleBin) { + recycleBin.hasChildren = true; + //reload the recycle bin if it's already expanded so the deleted item is shown + if (recycleBin.expanded) { + treeService.loadNodeChildren({ node: recycleBin, section: "content" }); } - }, 500); + } } - + //if the current edited item is the same one as we're deleting, we need to navigate elsewhere if (editorState.current && editorState.current.id == $scope.currentNode.id) { //If the deleted item lived at the root then just redirect back to the root, otherwise redirect to the item's parent var location = "/content"; - if ($scope.currentNode.parentId.toString() !== "-1") + if ($scope.currentNode.parentId.toString() === "-20") + location = "/content/content/recyclebin"; + else if ($scope.currentNode.parentId.toString() !== "-1") location = "/content/content/edit/" + $scope.currentNode.parentId; $location.path(location); diff --git a/src/Umbraco.Web.UI.Client/src/views/media/media.delete.controller.js b/src/Umbraco.Web.UI.Client/src/views/media/media.delete.controller.js index 974f2ad21b..e5e95e94df 100644 --- a/src/Umbraco.Web.UI.Client/src/views/media/media.delete.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/media/media.delete.controller.js @@ -30,6 +30,10 @@ function MediaDeleteController($scope, mediaResource, treeService, navigationSer var recycleBin = treeService.getDescendantNode(rootNode, -21); if (recycleBin) { recycleBin.hasChildren = true; + //reload the recycle bin if it's already expanded so the deleted item is shown + if (recycleBin.expanded) { + treeService.loadNodeChildren({ node: recycleBin, section: "media" }); + } } } @@ -37,8 +41,10 @@ function MediaDeleteController($scope, mediaResource, treeService, navigationSer if (editorState.current && editorState.current.id == $scope.currentNode.id) { //If the deleted item lived at the root then just redirect back to the root, otherwise redirect to the item's parent - var location = "/media"; - if ($scope.currentNode.parentId.toString() !== "-1") + var location = "/media"; + if ($scope.currentNode.parentId.toString() === "-21") + location = "/media/media/recyclebin"; + else if ($scope.currentNode.parentId.toString() !== "-1") location = "/media/media/edit/" + $scope.currentNode.parentId; $location.path(location); diff --git a/src/Umbraco.Web.UI.Client/src/views/media/media.move.controller.js b/src/Umbraco.Web.UI.Client/src/views/media/media.move.controller.js index 8bb1dc3ac8..163cee9088 100644 --- a/src/Umbraco.Web.UI.Client/src/views/media/media.move.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/media/media.move.controller.js @@ -5,6 +5,14 @@ angular.module("umbraco").controller("Umbraco.Editors.Media.MoveController", $scope.dialogTreeApi = {}; $scope.source = _.clone($scope.currentNode); + $scope.busy = false; + $scope.searchInfo = { + searchFromId: null, + searchFromName: null, + showSearch: false, + results: [], + selectedSearchResults: [] + } $scope.treeModel = { hideHeader: false } @@ -52,6 +60,24 @@ angular.module("umbraco").controller("Umbraco.Editors.Media.MoveController", $scope.close = function() { navigationService.hideDialog(); }; + $scope.hideSearch = function () { + $scope.searchInfo.showSearch = false; + $scope.searchInfo.searchFromId = null; + $scope.searchInfo.searchFromName = null; + $scope.searchInfo.results = []; + } + + // method to select a search result + $scope.selectResult = function (evt, result) { + result.selected = result.selected === true ? false : true; + nodeSelectHandler({ event: evt, node: result }); + }; + + //callback when there are search results + $scope.onSearchResults = function (results) { + $scope.searchInfo.results = results; + $scope.searchInfo.showSearch = true; + }; $scope.move = function () { $scope.busy = true; @@ -83,11 +109,11 @@ angular.module("umbraco").controller("Umbraco.Editors.Media.MoveController", $scope.error = err; }); }; - + // Mini list view $scope.selectListViewNode = function (node) { node.selected = node.selected === true ? false : true; - nodeSelectHandler({}, { node: node }); + nodeSelectHandler({ node: node }); }; $scope.closeMiniListView = function () { diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml index a1ab9c6e6c..08d286d41d 100644 --- a/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml +++ b/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml @@ -1706,7 +1706,7 @@ To manage your website, simply open the Umbraco back office and start adding con An invitation has been sent to the new user with details about how to log in to Umbraco. Hello there and welcome to Umbraco! In just 1 minute you’ll be good to go, we just need you to setup a password and add a picture for your avatar. Welcome to Umbraco! Unfortunately your invite has expired. Please contact your administrator and ask them to resend it. - Upload a picture to make it easy for other users to recognize you. + Uploading a photo of yourself will make it easy for other users to recognize you. Click the circle above to upload your photo. Writer Change Your profile diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml index 4bc117e574..a3b5185613 100644 --- a/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml +++ b/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml @@ -289,7 +289,7 @@ Click to upload or click here to choose files - You can drag files here to upload + You can drag files here to upload. Cannot upload this file, it does not have an approved file type Max file size is Media root @@ -1754,7 +1754,7 @@ To manage your website, simply open the Umbraco back office and start adding con An invitation has been sent to the new user with details about how to log in to Umbraco. Hello there and welcome to Umbraco! In just 1 minute you’ll be good to go, we just need you to setup a password and add a picture for your avatar. Welcome to Umbraco! Unfortunately your invite has expired. Please contact your administrator and ask them to resend it. - Upload a picture to make it easy for other users to recognize you. + Uploading a photo of yourself will make it easy for other users to recognize you. Click the circle above to upload your photo. Writer Change Your profile diff --git a/src/Umbraco.Web/Editors/ContentTypeControllerBase.cs b/src/Umbraco.Web/Editors/ContentTypeControllerBase.cs index cc2c1ab622..2572bed816 100644 --- a/src/Umbraco.Web/Editors/ContentTypeControllerBase.cs +++ b/src/Umbraco.Web/Editors/ContentTypeControllerBase.cs @@ -89,24 +89,7 @@ namespace Umbraco.Web.Editors var availableCompositions = Services.ContentTypeService.GetAvailableCompositeContentTypes(source, allContentTypes, filterContentTypes, filterPropertyTypes); - Func> getEntityContainers = contentType => - { - if (contentType == null) - { - return null; - } - switch (type) - { - case UmbracoObjectTypes.DocumentType: - return Services.ContentTypeService.GetContentTypeContainers(contentType as IContentType); - case UmbracoObjectTypes.MediaType: - return Services.ContentTypeService.GetMediaTypeContainers(contentType as IMediaType); - case UmbracoObjectTypes.MemberType: - return new EntityContainer[0]; - default: - throw new ArgumentOutOfRangeException("The entity type was not a content type"); - } - }; + var currCompositions = source == null ? new IContentTypeComposition[] { } : source.ContentTypeComposition.ToArray(); var compAliases = currCompositions.Select(x => x.Alias).ToArray(); @@ -128,7 +111,7 @@ namespace Umbraco.Web.Editors x.Item1.Name = TranslateItem(x.Item1.Name); var contentType = allContentTypes.FirstOrDefault(c => c.Key == x.Item1.Key); - var containers = getEntityContainers(contentType)?.ToArray(); + var containers = GetEntityContainers(contentType, type)?.ToArray(); var containerPath = $"/{(containers != null && containers.Any() ? $"{string.Join("/", containers.Select(c => c.Name))}/" : null)}"; x.Item1.AdditionalData["containerPath"] = containerPath; @@ -137,6 +120,26 @@ namespace Umbraco.Web.Editors .ToList(); } + private IEnumerable GetEntityContainers(IContentTypeComposition contentType, UmbracoObjectTypes type) + { + if (contentType == null) + { + return null; + } + + switch (type) + { + case UmbracoObjectTypes.DocumentType: + return Services.ContentTypeService.GetContainers(contentType as IContentType); + case UmbracoObjectTypes.MediaType: + return Services.MediaTypeService.GetContainers(contentType as IMediaType); + case UmbracoObjectTypes.MemberType: + return new EntityContainer[0]; + default: + throw new ArgumentOutOfRangeException("The entity type was not a content type"); + } + } + /// /// Returns a list of content types where a particular composition content type is used ///