diff --git a/src/Umbraco.Web.UI.Client/src/common/mocks/resources/entity.mocks.js b/src/Umbraco.Web.UI.Client/src/common/mocks/resources/entity.mocks.js
index 2c2007dd91b0..05594115e1d2 100644
--- a/src/Umbraco.Web.UI.Client/src/common/mocks/resources/entity.mocks.js
+++ b/src/Umbraco.Web.UI.Client/src/common/mocks/resources/entity.mocks.js
@@ -34,6 +34,15 @@ angular.module('umbraco.mocks').
return [200, nodes, null];
}
+ function returnUrlsbyUdis(status, data, headers) {
+
+ if (!mocksUtils.checkAuth()) {
+ return [401, null, null];
+ }
+
+ return [200, {}, null];
+ }
+
function returnEntitybyIdsPost(method, url, data, headers) {
if (!mocksUtils.checkAuth()) {
@@ -73,6 +82,10 @@ angular.module('umbraco.mocks').
.whenPOST(mocksUtils.urlRegex('/umbraco/UmbracoApi/Entity/GetByIds'))
.respond(returnEntitybyIdsPost);
+ $httpBackend
+ .whenPOST(mocksUtils.urlRegex('/umbraco/UmbracoApi/Entity/GetUrlsByUdis'))
+ .respond(returnUrlsbyUdis);
+
$httpBackend
.whenGET(mocksUtils.urlRegex('/umbraco/UmbracoApi/Entity/GetAncestors'))
.respond(returnEntitybyIds);
diff --git a/src/Umbraco.Web.UI.Client/src/common/resources/entity.resource.js b/src/Umbraco.Web.UI.Client/src/common/resources/entity.resource.js
index 0b060da34bed..44be85b8fdd9 100644
--- a/src/Umbraco.Web.UI.Client/src/common/resources/entity.resource.js
+++ b/src/Umbraco.Web.UI.Client/src/common/resources/entity.resource.js
@@ -127,6 +127,21 @@ function entityResource($q, $http, umbRequestHelper) {
'Failed to retrieve url for id:' + id);
},
+ getUrlsByUdis: function(udis, culture) {
+ var query = "culture=" + (culture || "");
+
+ return umbRequestHelper.resourcePromise(
+ $http.post(
+ umbRequestHelper.getApiUrl(
+ "entityApiBaseUrl",
+ "GetUrlsByUdis",
+ query),
+ {
+ udis: udis
+ }),
+ 'Failed to retrieve url map for udis ' + udis);
+ },
+
getUrlByUdi: function (udi, culture) {
if (!udi) {
diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/contentpicker/contentpicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/contentpicker/contentpicker.controller.js
index d8c7b3e76a62..7c8c1e64fbd7 100644
--- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/contentpicker/contentpicker.controller.js
+++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/contentpicker/contentpicker.controller.js
@@ -413,8 +413,13 @@ function contentPickerController($scope, $q, $routeParams, $location, entityReso
var missingIds = _.difference(valueIds, renderModelIds);
if (missingIds.length > 0) {
- return entityResource.getByIds(missingIds, entityType).then(function (data) {
+ var requests = [
+ entityResource.getByIds(missingIds, entityType),
+ entityResource.getUrlsByUdis(missingIds)
+ ];
+
+ return $q.all(requests).then(function ([data, urlMap]) {
_.each(valueIds,
function (id, i) {
var entity = _.find(data, function (d) {
@@ -422,7 +427,12 @@ function contentPickerController($scope, $q, $routeParams, $location, entityReso
});
if (entity) {
- addSelectedItem(entity);
+
+ entity.url = entity.trashed
+ ? vm.labels.general_recycleBin
+ : urlMap[id];
+
+ addSelectedItem(entity);
}
});
@@ -469,26 +479,6 @@ function contentPickerController($scope, $q, $routeParams, $location, entityReso
}
- function setEntityUrl(entity) {
-
- // get url for content and media items
- if (entityType !== "Member") {
- entityResource.getUrl(entity.id, entityType).then(function (data) {
- // update url
- $scope.renderModel.forEach(function (item) {
- if (item.id === entity.id) {
- if (entity.trashed) {
- item.url = vm.labels.general_recycleBin;
- } else {
- item.url = data;
- }
- }
- });
- });
- }
-
- }
-
function addSelectedItem(item) {
// set icon
@@ -523,8 +513,6 @@ function contentPickerController($scope, $q, $routeParams, $location, entityReso
"published": (item.metaData && item.metaData.IsPublished === false && entityType === "Document") ? false : true
// only content supports published/unpublished content so we set everything else to published so the UI looks correct
});
-
- setEntityUrl(item);
}
function setSortingState(items) {
diff --git a/src/Umbraco.Web/Editors/EntityController.cs b/src/Umbraco.Web/Editors/EntityController.cs
index b6bef3fd9651..0b6273e79da8 100644
--- a/src/Umbraco.Web/Editors/EntityController.cs
+++ b/src/Umbraco.Web/Editors/EntityController.cs
@@ -235,6 +235,50 @@ public HttpResponseMessage GetUrl(Udi udi, string culture = "*")
return GetUrl(intId.Result, entityType, culture);
}
+ ///
+ /// Get entity URLs by UDIs
+ ///
+ ///
+ /// A list of UDIs to lookup items by
+ ///
+ /// The culture to fetch the URL for
+ /// Dictionary mapping Udi -> Url
+ ///
+ /// We allow for POST because there could be quite a lot of Ids.
+ ///
+ [HttpGet]
+ [HttpPost]
+ public IDictionary GetUrlsByUdis([FromJsonPath] Udi[] udis, string culture = null)
+ {
+ if (udis == null || udis.Length == 0)
+ {
+ return new Dictionary();
+ }
+
+ // TODO: PMJ 2021-09-27 - Should GetUrl(Udi) exist as an extension method on UrlProvider/IUrlProvider (in v9)
+ string MediaOrDocumentUrl(Udi udi)
+ {
+ if (udi is not GuidUdi guidUdi)
+ {
+ return null;
+ }
+
+ return guidUdi.EntityType switch
+ {
+ Constants.UdiEntityType.Document => UmbracoContext.UrlProvider.GetUrl(guidUdi.Guid, culture: culture ?? ClientCulture()),
+ // NOTE: If culture is passed here we get an empty string rather than a media item URL WAT
+ Constants.UdiEntityType.Media => UmbracoContext.UrlProvider.GetMediaUrl(guidUdi.Guid, culture: null),
+ _ => null
+ };
+ }
+
+ return udis
+ .Select(udi => new {
+ Udi = udi,
+ Url = MediaOrDocumentUrl(udi)
+ }).ToDictionary(x => x.Udi, x => x.Url);
+ }
+
///
/// Gets the URL of an entity
///