Skip to content

Commit

Permalink
Merge pull request #11207 from umbraco/v8/bugfix/mntp-performance
Browse files Browse the repository at this point in the history
Combine GetUrl requests when loading a MNTP with many entries
  • Loading branch information
nikolajlauridsen authored Oct 6, 2021
2 parents 20b9db8 + 106f6dc commit e36dd86
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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()) {
Expand Down Expand Up @@ -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);
Expand Down
15 changes: 15 additions & 0 deletions src/Umbraco.Web.UI.Client/src/common/resources/entity.resource.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -413,16 +413,26 @@ 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) {
return $scope.model.config.idType === "udi" ? (d.udi == id) : (d.id == id);
});

if (entity) {
addSelectedItem(entity);

entity.url = entity.trashed
? vm.labels.general_recycleBin
: urlMap[id];

addSelectedItem(entity);
}

});
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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) {
Expand Down
44 changes: 44 additions & 0 deletions src/Umbraco.Web/Editors/EntityController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,50 @@ public HttpResponseMessage GetUrl(Udi udi, string culture = "*")
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>
Expand Down

0 comments on commit e36dd86

Please sign in to comment.