diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/content/umbcontentnodeinfo.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/content/umbcontentnodeinfo.directive.js index 7f9d05aebc..8f613469a3 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/content/umbcontentnodeinfo.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/content/umbcontentnodeinfo.directive.js @@ -1,7 +1,7 @@ (function () { 'use strict'; - function ContentNodeInfoDirective($timeout, $location, logResource, eventsService, userService, localizationService, dateHelper) { + function ContentNodeInfoDirective($timeout, $location, logResource, eventsService, userService, localizationService, dateHelper, redirectUrlsResource) { function link(scope, element, attrs, ctrl) { @@ -46,6 +46,9 @@ // Make sure to set the node status setNodePublishStatus(scope.node); + //default setting for redirect url management + scope.urlTrackerDisabled = false; + // Declare a fallback URL for the directive if (scope.documentType !== null) { scope.previewOpenUrl = '#/settings/documenttypes/edit/' + scope.documentType.id; @@ -99,7 +102,7 @@ // get current backoffice user and format dates userService.getCurrentUser().then(function (currentUser) { - angular.forEach(data.items, function(item) { + angular.forEach(data.items, function (item) { item.timestampFormatted = dateHelper.getLocalDate(item.timestamp, currentUser.locale, 'LLL'); }); }); @@ -116,6 +119,25 @@ }); } + function loadRedirectUrls() { + scope.loadingRedirectUrls = true; + //check if Redirect Url Management is enabled + redirectUrlsResource.getEnableState().then(function (response) { + scope.urlTrackerDisabled = response.enabled !== true; + if (scope.urlTrackerDisabled === false) { + + redirectUrlsResource.getRedirectsForContentItem(scope.node.udi) + .then(function (data) { + scope.redirectUrls = data.searchResults; + scope.hasRedirects = (typeof data.searchResults !== 'undefined' && data.searchResults.length > 0); + scope.loadingRedirectUrls = false; + }); + } + else { + scope.loadingRedirectUrls = false; + } + }); + } function setAuditTrailLogTypeColor(auditTrail) { angular.forEach(auditTrail, function (item) { @@ -136,27 +158,27 @@ function setNodePublishStatus(node) { // deleted node - if(node.trashed === true) { + if (node.trashed === true) { scope.publishStatus.label = localizationService.localize("general_deleted"); scope.publishStatus.color = "danger"; } // unpublished node - if(node.published === false && node.trashed === false) { + if (node.published === false && node.trashed === false) { scope.publishStatus.label = localizationService.localize("content_unpublished"); scope.publishStatus.color = "gray"; } // published node - if(node.hasPublishedVersion === true && node.publishDate && node.published === true) { + if (node.hasPublishedVersion === true && node.publishDate && node.published === true) { scope.publishStatus.label = localizationService.localize("content_published"); scope.publishStatus.color = "success"; } // published node with pending changes - if(node.hasPublishedVersion === true && node.publishDate && node.published === false) { + if (node.hasPublishedVersion === true && node.publishDate && node.published === false) { scope.publishStatus.label = localizationService.localize("content_publishedPendingChanges"); - scope.publishStatus.color = "success" + scope.publishStatus.color = "success"; } } @@ -252,12 +274,13 @@ }); } - // load audit trail when on the info tab + // load audit trail and redirects when on the info tab evts.push(eventsService.on("app.tabChange", function (event, args) { - $timeout(function(){ + $timeout(function () { if (args.id === -1) { isInfoTab = true; loadAuditTrail(); + loadRedirectUrls(); } else { isInfoTab = false; } @@ -265,13 +288,14 @@ })); // watch for content updates - reload content when node is saved, published etc. - scope.$watch('node.updateDate', function(newValue, oldValue){ + scope.$watch('node.updateDate', function (newValue, oldValue) { - if(!newValue) { return; } - if(newValue === oldValue) { return; } + if (!newValue) { return; } + if (newValue === oldValue) { return; } if(isInfoTab) { loadAuditTrail(); + loadRedirectUrls(); formatDatesToLocal(); setNodePublishStatus(scope.node); } diff --git a/src/Umbraco.Web.UI.Client/src/common/resources/redirecturls.resource.js b/src/Umbraco.Web.UI.Client/src/common/resources/redirecturls.resource.js index ea40c066f0..fb145418ed 100644 --- a/src/Umbraco.Web.UI.Client/src/common/resources/redirecturls.resource.js +++ b/src/Umbraco.Web.UI.Client/src/common/resources/redirecturls.resource.js @@ -40,6 +40,32 @@ { searchTerm: searchTerm, page: pageIndex, pageSize: pageSize })), 'Failed to retrieve data for searching redirect urls'); } + /** + * @ngdoc function + * @name umbraco.resources.redirectUrlResource#getRedirectsForContentItem + * @methodOf umbraco.resources.redirectUrlResource + * @function + * + * @description + * Used to retrieve RedirectUrls for a specific item of content for Information tab + * ##usage + *
+   * redirectUrlsResource.getRedirectsForContentItem("udi:123456")
+   *    .then(function(response) {
+   *
+   *    });
+   * 
+ * @param {String} contentUdi identifier for the content item to retrieve redirects for + */ + function getRedirectsForContentItem(contentUdi) { + return umbRequestHelper.resourcePromise( + $http.get( + umbRequestHelper.getApiUrl( + "redirectUrlManagementApiBaseUrl", + "RedirectUrlsForContentItem", + { contentUdi: contentUdi })), + 'Failed to retrieve redirects for content: ' + contentUdi); + } function getEnableState() { @@ -50,7 +76,7 @@ "GetEnableState")), 'Failed to retrieve data to check if the 301 redirect is enabled'); } - + /** * @ngdoc function * @name umbraco.resources.redirectUrlResource#deleteRedirectUrl @@ -107,7 +133,8 @@ searchRedirectUrls: searchRedirectUrls, deleteRedirectUrl: deleteRedirectUrl, toggleUrlTracker: toggleUrlTracker, - getEnableState: getEnableState + getEnableState: getEnableState, + getRedirectsForContentItem: getRedirectsForContentItem }; return resource; diff --git a/src/Umbraco.Web.UI.Client/src/views/components/content/umb-content-node-info.html b/src/Umbraco.Web.UI.Client/src/views/components/content/umb-content-node-info.html index 7e80aa2fca..0706e9596c 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/content/umb-content-node-info.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/content/umb-content-node-info.html @@ -19,6 +19,23 @@ + + + +
+
+ +
+

The following URLs redirect to this content item:

+ +
+
+
+
@@ -61,6 +78,7 @@
+ {{ item.logType }} diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/en.xml b/src/Umbraco.Web.UI/umbraco/config/lang/en.xml index f7a5ac5ef4..7ec238408b 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/en.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/en.xml @@ -1688,8 +1688,8 @@ To manage your website, simply open the Umbraco back office and start adding con tab has no sort order - Where is this composition used? - This composition is currently used in the composition of the following content types: + Where is this composition used? + This composition is currently used in the composition of the following content types: @@ -2186,6 +2186,8 @@ To manage your website, simply open the Umbraco back office and start adding con Enable URL tracker Original URL Redirected To + Redirect Url Management + The following URLs redirect to this content item: No redirects have been made When a published page gets renamed or moved a redirect will automatically be made to the new page. Remove 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 655c619095..a7fad7132b 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml @@ -1681,8 +1681,8 @@ To manage your website, simply open the Umbraco back office and start adding con tab has no sort order - Where is this composition used? - This composition is currently used in the composition of the following content types: + Where is this composition used? + This composition is currently used in the composition of the following content types: @@ -2178,6 +2178,8 @@ To manage your website, simply open the Umbraco back office and start adding con Enable URL tracker Original URL Redirected To + Redirect Url Management + The following URLs redirect to this content item: No redirects have been made When a published page gets renamed or moved a redirect will automatically be made to the new page. Remove diff --git a/src/Umbraco.Web/Editors/RedirectUrlManagementController.cs b/src/Umbraco.Web/Editors/RedirectUrlManagementController.cs index 9fb7a63c9f..f9a2807003 100644 --- a/src/Umbraco.Web/Editors/RedirectUrlManagementController.cs +++ b/src/Umbraco.Web/Editors/RedirectUrlManagementController.cs @@ -12,6 +12,7 @@ using Umbraco.Web.Models.ContentEditing; using Umbraco.Web.Mvc; using Umbraco.Web.WebApi; using File = System.IO.File; +using Umbraco.Core; namespace Umbraco.Web.Editors { @@ -39,7 +40,7 @@ namespace Umbraco.Web.Editors var redirectUrlService = Services.RedirectUrlService; long resultCount; - var redirects = string.IsNullOrWhiteSpace(searchTerm) + var redirects = string.IsNullOrWhiteSpace(searchTerm) ? redirectUrlService.GetAllRedirectUrls(page, pageSize, out resultCount) : redirectUrlService.SearchRedirectUrls(searchTerm, page, pageSize, out resultCount); @@ -53,11 +54,32 @@ namespace Umbraco.Web.Editors searchResult.TotalCount = resultCount; searchResult.CurrentPage = page; searchResult.PageCount = ((int)resultCount + pageSize - 1) / pageSize; - + return searchResult; } - + /// + /// This lists the RedirectUrls for a particular content item + /// Do we need to consider paging here? + /// + /// Udi of content item to retrieve RedirectUrls for + /// + [HttpGet] + public RedirectUrlSearchResult RedirectUrlsForContentItem(string contentUdi) + { + var redirectsResult = new RedirectUrlSearchResult(); + if (GuidUdi.TryParse(contentUdi, out var guidIdi)) + { + var redirectUrlService = Services.RedirectUrlService; + var redirects = redirectUrlService.GetContentRedirectUrls(guidIdi.Guid); + redirectsResult.SearchResults = Mapper.Map>(redirects).ToArray(); + //not doing paging 'yet' + redirectsResult.TotalCount = redirects.Count(); + redirectsResult.CurrentPage = 1; + redirectsResult.PageCount = 1; + } + return redirectsResult; + } [HttpPost] public IHttpActionResult DeleteRedirectUrl(Guid id) { @@ -100,4 +122,4 @@ namespace Umbraco.Web.Editors return Ok(string.Format("URL tracker is now {0}d", action)); } } -} \ No newline at end of file +}