Merge pull request #11207 from umbraco/v8/bugfix/mntp-performance

Combine GetUrl requests when loading a MNTP with many entries
This commit is contained in:
Mole
2021-10-06 08:56:12 +02:00
committed by GitHub
4 changed files with 84 additions and 24 deletions

View File

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

View File

@@ -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) {

View File

@@ -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) {

View File

@@ -235,6 +235,50 @@ namespace Umbraco.Web.Editors
return GetUrl(intId.Result, entityType, culture);
}
/// <summary>
/// Get entity URLs by UDIs
/// </summary>
/// <param name="udis">
/// A list of UDIs to lookup items by
/// </param>
/// <param name="culture">The culture to fetch the URL for</param>
/// <returns>Dictionary mapping Udi -> Url</returns>
/// <remarks>
/// We allow for POST because there could be quite a lot of Ids.
/// </remarks>
[HttpGet]
[HttpPost]
public IDictionary<Udi, string> GetUrlsByUdis([FromJsonPath] Udi[] udis, string culture = null)
{
if (udis == null || udis.Length == 0)
{
return new Dictionary<Udi, string>();
}
// 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);
}
/// <summary>
/// Gets the URL of an entity
/// </summary>