Refactor Tracked references endpoints (#15933)

* Moved tracked references under their respective sources

Prepped the endpoints to be more inline with how we will optimize in the future

* Fixed some endpoint signature issues and update openapi spec

* Partial Revert "Moved tracked references under their respective sources"

This reverts the submodule update in commit 3819276a74c6ff4d848e27c8a36c0abfc2d28b9d.

* Fix duplicate line

* Rework for polymorphic output

* Improved endpoint naming

* Regenerate OpenApi.json

---------

Co-authored-by: Sven Geusens <sge@umbraco.dk>
Co-authored-by: kjac <kja@umbraco.dk>
This commit is contained in:
Sven Geusens
2024-03-26 14:32:56 +01:00
committed by GitHub
parent 2175d523cc
commit e1ee896556
19 changed files with 863 additions and 370 deletions

View File

@@ -1,21 +1,21 @@
using Asp.Versioning;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Api.Common.ViewModels.Pagination;
using Umbraco.Cms.Api.Management.ViewModels;
using Umbraco.Cms.Core.Mapping;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Api.Common.ViewModels.Pagination;
using Umbraco.Cms.Api.Management.ViewModels.TrackedReferences;
namespace Umbraco.Cms.Api.Management.Controllers.TrackedReference;
namespace Umbraco.Cms.Api.Management.Controllers.Document.References;
[ApiVersion("1.0")]
public class ItemsTrackedReferenceController : TrackedReferenceControllerBase
public class AreReferencedDocumentController : DocumentControllerBase
{
private readonly ITrackedReferencesService _trackedReferencesSkipTakeService;
private readonly IUmbracoMapper _umbracoMapper;
public ItemsTrackedReferenceController(ITrackedReferencesService trackedReferencesSkipTakeService, IUmbracoMapper umbracoMapper)
public AreReferencedDocumentController(ITrackedReferencesService trackedReferencesSkipTakeService, IUmbracoMapper umbracoMapper)
{
_trackedReferencesSkipTakeService = trackedReferencesSkipTakeService;
_umbracoMapper = umbracoMapper;
@@ -28,16 +28,16 @@ public class ItemsTrackedReferenceController : TrackedReferenceControllerBase
/// Used when bulk deleting content/media and bulk unpublishing content (delete and unpublish on List view).
/// This is basically finding children of relations.
/// </remarks>
[HttpGet("item")]
[HttpGet("are-referenced")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(PagedViewModel<RelationItemResponseModel>), StatusCodes.Status200OK)]
public async Task<ActionResult<PagedViewModel<RelationItemResponseModel>>> GetPagedReferencedItems([FromQuery(Name="id")]HashSet<Guid> ids, int skip = 0, int take = 20, bool filterMustBeIsDependency = true)
[ProducesResponseType(typeof(PagedViewModel<ReferenceByIdModel>), StatusCodes.Status200OK)]
public async Task<ActionResult<PagedViewModel<ReferenceByIdModel>>> GetPagedReferencedItems([FromQuery(Name="id")]HashSet<Guid> ids, int skip = 0, int take = 20)
{
PagedModel<RelationItemModel> relationItems = await _trackedReferencesSkipTakeService.GetPagedItemsWithRelationsAsync(ids, skip, take, filterMustBeIsDependency);
var pagedViewModel = new PagedViewModel<RelationItemResponseModel>
PagedModel<RelationItemModel> distinctByKeyItemsWithReferencedRelations = await _trackedReferencesSkipTakeService.GetPagedItemsWithRelationsAsync(ids, skip, take, true);
var pagedViewModel = new PagedViewModel<ReferenceByIdModel>
{
Total = relationItems.Total,
Items = _umbracoMapper.MapEnumerable<RelationItemModel, RelationItemResponseModel>(relationItems.Items),
Total = distinctByKeyItemsWithReferencedRelations.Total,
Items = _umbracoMapper.MapEnumerable<RelationItemModel, ReferenceByIdModel>(distinctByKeyItemsWithReferencedRelations.Items),
};
return await Task.FromResult(pagedViewModel);

View File

@@ -0,0 +1,49 @@
using Asp.Versioning;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Api.Common.ViewModels.Pagination;
using Umbraco.Cms.Api.Management.Factories;
using Umbraco.Cms.Api.Management.ViewModels.TrackedReferences;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Services;
namespace Umbraco.Cms.Api.Management.Controllers.Document.References;
[ApiVersion("1.0")]
public class ReferencedByDocumentController : DocumentControllerBase
{
private readonly ITrackedReferencesService _trackedReferencesService;
private readonly IRelationTypePresentationFactory _relationTypePresentationFactory;
public ReferencedByDocumentController(ITrackedReferencesService trackedReferencesService, IRelationTypePresentationFactory relationTypePresentationFactory)
{
_trackedReferencesService = trackedReferencesService;
_relationTypePresentationFactory = relationTypePresentationFactory;
}
/// <summary>
/// Gets a page list of tracked references for the current item, so you can see where an item is being used.
/// </summary>
/// <remarks>
/// Used by info tabs on content, media etc. and for the delete and unpublish of single items.
/// This is basically finding parents of relations.
/// </remarks>
[HttpGet("{id:guid}/referenced-by")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(PagedViewModel<IReferenceResponseModel>), StatusCodes.Status200OK)]
public async Task<ActionResult<PagedViewModel<IReferenceResponseModel>>> ReferencedBy(
Guid id,
int skip = 0,
int take = 20)
{
PagedModel<RelationItemModel> relationItems = await _trackedReferencesService.GetPagedRelationsForItemAsync(id, skip, take, false);
var pagedViewModel = new PagedViewModel<IReferenceResponseModel>
{
Total = relationItems.Total,
Items = await _relationTypePresentationFactory.CreateReferenceResponseModelsAsync(relationItems.Items),
};
return await Task.FromResult(pagedViewModel);
}
}

View File

@@ -1,21 +1,21 @@
using Asp.Versioning;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Api.Common.ViewModels.Pagination;
using Umbraco.Cms.Api.Management.ViewModels;
using Umbraco.Cms.Core.Mapping;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Api.Common.ViewModels.Pagination;
using Umbraco.Cms.Api.Management.ViewModels.TrackedReferences;
namespace Umbraco.Cms.Api.Management.Controllers.TrackedReference;
namespace Umbraco.Cms.Api.Management.Controllers.Document.References;
[ApiVersion("1.0")]
public class DescendantsTrackedReferenceController : TrackedReferenceControllerBase
public class ReferencedDescendantsDocumentController : DocumentControllerBase
{
private readonly ITrackedReferencesService _trackedReferencesSkipTakeService;
private readonly IUmbracoMapper _umbracoMapper;
public DescendantsTrackedReferenceController(ITrackedReferencesService trackedReferencesSkipTakeService, IUmbracoMapper umbracoMapper)
public ReferencedDescendantsDocumentController(ITrackedReferencesService trackedReferencesSkipTakeService, IUmbracoMapper umbracoMapper)
{
_trackedReferencesSkipTakeService = trackedReferencesSkipTakeService;
_umbracoMapper = umbracoMapper;
@@ -29,16 +29,16 @@ public class DescendantsTrackedReferenceController : TrackedReferenceControllerB
/// kind of relation.
/// This is basically finding the descending items which are children in relations.
/// </remarks>
[HttpGet("descendants/{parentId:guid}")]
[HttpGet("{id:guid}/referenced-descendants")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(PagedViewModel<RelationItemResponseModel>), StatusCodes.Status200OK)]
public async Task<ActionResult<PagedViewModel<RelationItemResponseModel>>> Descendants(Guid parentId, int skip = 0, int take = 20, bool filterMustBeIsDependency = true)
[ProducesResponseType(typeof(PagedViewModel<ReferenceByIdModel>), StatusCodes.Status200OK)]
public async Task<ActionResult<PagedViewModel<ReferenceByIdModel>>> ReferencedDescendants(Guid id, int skip = 0, int take = 20)
{
PagedModel<RelationItemModel> relationItems = await _trackedReferencesSkipTakeService.GetPagedDescendantsInReferencesAsync(parentId, skip, take, filterMustBeIsDependency);
var pagedViewModel = new PagedViewModel<RelationItemResponseModel>
PagedModel<RelationItemModel> relationItems = await _trackedReferencesSkipTakeService.GetPagedDescendantsInReferencesAsync(id, skip, take, true);
var pagedViewModel = new PagedViewModel<ReferenceByIdModel>
{
Total = relationItems.Total,
Items = _umbracoMapper.MapEnumerable<RelationItemModel, RelationItemResponseModel>(relationItems.Items),
Items = _umbracoMapper.MapEnumerable<RelationItemModel, ReferenceByIdModel>(relationItems.Items),
};
return await Task.FromResult(pagedViewModel);

View File

@@ -0,0 +1,46 @@
using Asp.Versioning;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Api.Common.ViewModels.Pagination;
using Umbraco.Cms.Api.Management.ViewModels;
using Umbraco.Cms.Core.Mapping;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Services;
namespace Umbraco.Cms.Api.Management.Controllers.Media.References;
[ApiVersion("1.0")]
public class AreReferencedMediaController : MediaControllerBase
{
private readonly ITrackedReferencesService _trackedReferencesSkipTakeService;
private readonly IUmbracoMapper _umbracoMapper;
public AreReferencedMediaController(ITrackedReferencesService trackedReferencesSkipTakeService, IUmbracoMapper umbracoMapper)
{
_trackedReferencesSkipTakeService = trackedReferencesSkipTakeService;
_umbracoMapper = umbracoMapper;
}
/// <summary>
/// Gets a page list of the items used in any kind of relation from selected keys.
/// </summary>
/// <remarks>
/// Used when bulk deleting content/media and bulk unpublishing content (delete and unpublish on List view).
/// This is basically finding children of relations.
/// </remarks>
// [HttpGet("item")]
[HttpGet("are-referenced")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(PagedViewModel<ReferenceByIdModel>), StatusCodes.Status200OK)]
public async Task<ActionResult<PagedViewModel<ReferenceByIdModel>>> GetPagedReferencedItems([FromQuery(Name="id")]HashSet<Guid> ids, int skip = 0, int take = 20)
{
PagedModel<RelationItemModel> distinctByKeyItemsWithReferencedRelations = await _trackedReferencesSkipTakeService.GetPagedItemsWithRelationsAsync(ids, skip, take, true);
var pagedViewModel = new PagedViewModel<ReferenceByIdModel>
{
Total = distinctByKeyItemsWithReferencedRelations.Total,
Items = _umbracoMapper.MapEnumerable<RelationItemModel, ReferenceByIdModel>(distinctByKeyItemsWithReferencedRelations.Items),
};
return await Task.FromResult(pagedViewModel);
}
}

View File

@@ -1,24 +1,24 @@
using Asp.Versioning;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Core.Mapping;
using Umbraco.Cms.Api.Common.ViewModels.Pagination;
using Umbraco.Cms.Api.Management.Factories;
using Umbraco.Cms.Api.Management.ViewModels.TrackedReferences;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Api.Common.ViewModels.Pagination;
using Umbraco.Cms.Api.Management.ViewModels.TrackedReferences;
namespace Umbraco.Cms.Api.Management.Controllers.TrackedReference;
namespace Umbraco.Cms.Api.Management.Controllers.Media.References;
[ApiVersion("1.0")]
public class ByIdTrackedReferenceController : TrackedReferenceControllerBase
public class ReferencedByMediaController : MediaControllerBase
{
private readonly ITrackedReferencesService _trackedReferencesService;
private readonly IUmbracoMapper _umbracoMapper;
private readonly IRelationTypePresentationFactory _relationTypePresentationFactory;
public ByIdTrackedReferenceController(ITrackedReferencesService trackedReferencesService, IUmbracoMapper umbracoMapper)
public ReferencedByMediaController(ITrackedReferencesService trackedReferencesService, IRelationTypePresentationFactory relationTypePresentationFactory)
{
_trackedReferencesService = trackedReferencesService;
_umbracoMapper = umbracoMapper;
_relationTypePresentationFactory = relationTypePresentationFactory;
}
/// <summary>
@@ -28,21 +28,20 @@ public class ByIdTrackedReferenceController : TrackedReferenceControllerBase
/// Used by info tabs on content, media etc. and for the delete and unpublish of single items.
/// This is basically finding parents of relations.
/// </remarks>
[HttpGet("{id:guid}")]
[HttpGet("{id:guid}/referenced-by")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(PagedViewModel<RelationItemResponseModel>), StatusCodes.Status200OK)]
public async Task<ActionResult<PagedViewModel<RelationItemResponseModel>>> Get(
[ProducesResponseType(typeof(PagedViewModel<IReferenceResponseModel>), StatusCodes.Status200OK)]
public async Task<ActionResult<PagedViewModel<IReferenceResponseModel>>> ReferencedBy(
Guid id,
int skip = 0,
int take = 20,
bool filterMustBeIsDependency = false)
int take = 20)
{
PagedModel<RelationItemModel> relationItems = await _trackedReferencesService.GetPagedRelationsForItemAsync(id, skip, take, filterMustBeIsDependency);
PagedModel<RelationItemModel> relationItems = await _trackedReferencesService.GetPagedRelationsForItemAsync(id, skip, take, false);
var pagedViewModel = new PagedViewModel<RelationItemResponseModel>
var pagedViewModel = new PagedViewModel<IReferenceResponseModel>
{
Total = relationItems.Total,
Items = _umbracoMapper.MapEnumerable<RelationItemModel, RelationItemResponseModel>(relationItems.Items),
Items = await _relationTypePresentationFactory.CreateReferenceResponseModelsAsync(relationItems.Items),
};
return await Task.FromResult(pagedViewModel);

View File

@@ -0,0 +1,46 @@
using Asp.Versioning;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Api.Common.ViewModels.Pagination;
using Umbraco.Cms.Api.Management.ViewModels;
using Umbraco.Cms.Core.Mapping;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Services;
namespace Umbraco.Cms.Api.Management.Controllers.Media.References;
[ApiVersion("1.0")]
public class ReferencedDescendantsMediaController : MediaControllerBase
{
private readonly ITrackedReferencesService _trackedReferencesSkipTakeService;
private readonly IUmbracoMapper _umbracoMapper;
public ReferencedDescendantsMediaController(ITrackedReferencesService trackedReferencesSkipTakeService, IUmbracoMapper umbracoMapper)
{
_trackedReferencesSkipTakeService = trackedReferencesSkipTakeService;
_umbracoMapper = umbracoMapper;
}
/// <summary>
/// Gets a page list of the child nodes of the current item used in any kind of relation.
/// </summary>
/// <remarks>
/// Used when deleting and unpublishing a single item to check if this item has any descending items that are in any
/// kind of relation.
/// This is basically finding the descending items which are children in relations.
/// </remarks>
[HttpGet("{id:guid}/referenced-descendants")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(PagedViewModel<ReferenceByIdModel>), StatusCodes.Status200OK)]
public async Task<ActionResult<PagedViewModel<ReferenceByIdModel>>> ReferencedDescendants(Guid id, int skip = 0, int take = 20)
{
PagedModel<RelationItemModel> relationItems = await _trackedReferencesSkipTakeService.GetPagedDescendantsInReferencesAsync(id, skip, take, true);
var pagedViewModel = new PagedViewModel<ReferenceByIdModel>
{
Total = relationItems.Total,
Items = _umbracoMapper.MapEnumerable<RelationItemModel, ReferenceByIdModel>(relationItems.Items),
};
return await Task.FromResult(pagedViewModel);
}
}

View File

@@ -1,13 +0,0 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Api.Management.Routing;
using Umbraco.Cms.Web.Common.Authorization;
namespace Umbraco.Cms.Api.Management.Controllers.TrackedReference;
[VersionedApiBackOfficeRoute("tracked-reference")]
[ApiExplorerSettings(GroupName = "Tracked Reference")]
[Authorize(Policy = AuthorizationPolicies.SectionAccessContentOrMedia)]
public abstract class TrackedReferenceControllerBase : ManagementApiControllerBase
{
}

View File

@@ -1,4 +1,5 @@
using Umbraco.Cms.Api.Management.ViewModels.RelationType;
using Umbraco.Cms.Api.Management.ViewModels.TrackedReferences;
using Umbraco.Cms.Core.Models;
namespace Umbraco.Cms.Api.Management.Factories;
@@ -8,4 +9,6 @@ public interface IRelationTypePresentationFactory
IRelationType CreateRelationType(CreateRelationTypeRequestModel createRelationTypeRequestModel);
void MapUpdateModelToRelationType(UpdateRelationTypeRequestModel updateRelationTypeRequestModel, IRelationType target);
Task<IEnumerable<IReferenceResponseModel>> CreateReferenceResponseModelsAsync(IEnumerable<RelationItemModel> relationItemModels);
}

View File

@@ -1,4 +1,7 @@
using Umbraco.Cms.Api.Management.ViewModels.RelationType;
using Umbraco.Cms.Api.Management.ViewModels.TrackedReferences;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Mapping;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Strings;
using Umbraco.Extensions;
@@ -8,8 +11,13 @@ namespace Umbraco.Cms.Api.Management.Factories;
public class RelationTypePresentationFactory : IRelationTypePresentationFactory
{
private readonly IShortStringHelper _shortStringHelper;
private readonly IUmbracoMapper _umbracoMapper;
public RelationTypePresentationFactory(IShortStringHelper shortStringHelper) => _shortStringHelper = shortStringHelper;
public RelationTypePresentationFactory(IShortStringHelper shortStringHelper, IUmbracoMapper umbracoMapper)
{
_shortStringHelper = shortStringHelper;
_umbracoMapper = umbracoMapper;
}
public IRelationType CreateRelationType(CreateRelationTypeRequestModel createRelationTypeRequestModel) =>
new RelationType(
@@ -34,4 +42,16 @@ public class RelationTypePresentationFactory : IRelationTypePresentationFactory
target.ParentObjectType = updateRelationTypeRequestModel.ParentObjectType;
}
public async Task<IEnumerable<IReferenceResponseModel>> CreateReferenceResponseModelsAsync(IEnumerable<RelationItemModel> relationItemModels)
{
IReferenceResponseModel[] result = relationItemModels.Select(relationItemModel => relationItemModel.NodeType switch
{
Constants.UdiEntityType.Document => _umbracoMapper.Map<DocumentReferenceResponseModel>(relationItemModel),
Constants.UdiEntityType.Media => _umbracoMapper.Map<MediaReferenceResponseModel>(relationItemModel),
_ => _umbracoMapper.Map<DefaultReferenceResponseModel>(relationItemModel) as IReferenceResponseModel,
}).WhereNotNull().ToArray();
return await Task.FromResult(result);
}
}

View File

@@ -1,4 +1,5 @@
using Umbraco.Cms.Core.Mapping;
using Umbraco.Cms.Api.Management.ViewModels;
using Umbraco.Cms.Core.Mapping;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Api.Management.ViewModels.TrackedReferences;
@@ -8,22 +9,51 @@ public class TrackedReferenceViewModelsMapDefinition : IMapDefinition
{
public void DefineMaps(IUmbracoMapper mapper)
{
mapper.Define<RelationItemModel, RelationItemResponseModel>((source, context) => new RelationItemResponseModel(), Map);
mapper.Define<RelationItemModel, DocumentReferenceResponseModel>((source, context) => new DocumentReferenceResponseModel(), Map);
mapper.Define<RelationItemModel, MediaReferenceResponseModel>((source, context) => new MediaReferenceResponseModel(), Map);
mapper.Define<RelationItemModel, DefaultReferenceResponseModel>((source, context) => new DefaultReferenceResponseModel(), Map);
mapper.Define<RelationItemModel, ReferenceByIdModel>((source, context) => new ReferenceByIdModel(), Map);
}
// Umbraco.Code.MapAll
private void Map(RelationItemModel source, RelationItemResponseModel target, MapperContext context)
private void Map(RelationItemModel source, DocumentReferenceResponseModel target, MapperContext context)
{
target.ContentTypeAlias = source.ContentTypeAlias;
target.ContentTypeIcon = source.ContentTypeIcon;
target.ContentTypeName = source.ContentTypeName;
target.NodeId = source.NodeKey;
target.NodeName = source.NodeName;
target.NodeType = source.NodeType;
target.RelationTypeIsBidirectional = source.RelationTypeIsBidirectional;
target.RelationTypeIsDependency = source.RelationTypeIsDependency;
target.RelationTypeName = source.RelationTypeName;
target.NodePublished = source.NodePublished;
target.Id = source.NodeKey;
target.Name = source.NodeName;
target.Published = source.NodePublished;
target.DocumentType = new TrackedReferenceDocumentType
{
Alias = source.ContentTypeAlias,
Icon = source.ContentTypeIcon,
Name = source.ContentTypeName,
};
}
// Umbraco.Code.MapAll
private void Map(RelationItemModel source, MediaReferenceResponseModel target, MapperContext context)
{
target.Id = source.NodeKey;
target.Name = source.NodeName;
target.MediaType = new TrackedReferenceMediaType
{
Alias = source.ContentTypeAlias,
Icon = source.ContentTypeIcon,
Name = source.ContentTypeName,
};
}
// Umbraco.Code.MapAll
private void Map(RelationItemModel source, DefaultReferenceResponseModel target, MapperContext context)
{
target.Id = source.NodeKey;
target.Name = source.NodeName;
target.Type = source.NodeType;
target.Icon = source.ContentTypeIcon;
}
// Umbraco.Code.MapAll
private void Map(RelationItemModel source, ReferenceByIdModel target, MapperContext context)
{
target.Id = source.NodeKey;
}
}

View File

@@ -7494,6 +7494,140 @@
]
}
},
"/umbraco/management/api/v1/document/{id}/referenced-by": {
"get": {
"tags": [
"Document"
],
"operationId": "GetDocumentByIdReferencedBy",
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"name": "skip",
"in": "query",
"schema": {
"type": "integer",
"format": "int32",
"default": 0
}
},
{
"name": "take",
"in": "query",
"schema": {
"type": "integer",
"format": "int32",
"default": 20
}
}
],
"responses": {
"200": {
"description": "Success",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PagedIReferenceResponseModel"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/PagedIReferenceResponseModel"
}
},
"text/plain": {
"schema": {
"$ref": "#/components/schemas/PagedIReferenceResponseModel"
}
}
}
},
"401": {
"description": "The resource is protected and requires an authentication token"
}
},
"security": [
{
"Backoffice User": [ ]
}
]
}
},
"/umbraco/management/api/v1/document/{id}/referenced-descendants": {
"get": {
"tags": [
"Document"
],
"operationId": "GetDocumentByIdReferencedDescendants",
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"name": "skip",
"in": "query",
"schema": {
"type": "integer",
"format": "int32",
"default": 0
}
},
{
"name": "take",
"in": "query",
"schema": {
"type": "integer",
"format": "int32",
"default": 20
}
}
],
"responses": {
"200": {
"description": "Success",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PagedReferenceByIdModel"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/PagedReferenceByIdModel"
}
},
"text/plain": {
"schema": {
"$ref": "#/components/schemas/PagedReferenceByIdModel"
}
}
}
},
"401": {
"description": "The resource is protected and requires an authentication token"
}
},
"security": [
{
"Backoffice User": [ ]
}
]
}
},
"/umbraco/management/api/v1/document/{id}/unpublish": {
"put": {
"tags": [
@@ -7802,6 +7936,76 @@
]
}
},
"/umbraco/management/api/v1/document/are-referenced": {
"get": {
"tags": [
"Document"
],
"operationId": "GetDocumentAreReferenced",
"parameters": [
{
"name": "id",
"in": "query",
"schema": {
"uniqueItems": true,
"type": "array",
"items": {
"type": "string",
"format": "uuid"
}
}
},
{
"name": "skip",
"in": "query",
"schema": {
"type": "integer",
"format": "int32",
"default": 0
}
},
{
"name": "take",
"in": "query",
"schema": {
"type": "integer",
"format": "int32",
"default": 20
}
}
],
"responses": {
"200": {
"description": "Success",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PagedReferenceByIdModel"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/PagedReferenceByIdModel"
}
},
"text/plain": {
"schema": {
"$ref": "#/components/schemas/PagedReferenceByIdModel"
}
}
}
},
"401": {
"description": "The resource is protected and requires an authentication token"
}
},
"security": [
{
"Backoffice User": [ ]
}
]
}
},
"/umbraco/management/api/v1/document/configuration": {
"get": {
"tags": [
@@ -14256,6 +14460,140 @@
]
}
},
"/umbraco/management/api/v1/media/{id}/referenced-by": {
"get": {
"tags": [
"Media"
],
"operationId": "GetMediaByIdReferencedBy",
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"name": "skip",
"in": "query",
"schema": {
"type": "integer",
"format": "int32",
"default": 0
}
},
{
"name": "take",
"in": "query",
"schema": {
"type": "integer",
"format": "int32",
"default": 20
}
}
],
"responses": {
"200": {
"description": "Success",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PagedIReferenceResponseModel"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/PagedIReferenceResponseModel"
}
},
"text/plain": {
"schema": {
"$ref": "#/components/schemas/PagedIReferenceResponseModel"
}
}
}
},
"401": {
"description": "The resource is protected and requires an authentication token"
}
},
"security": [
{
"Backoffice User": [ ]
}
]
}
},
"/umbraco/management/api/v1/media/{id}/referenced-descendants": {
"get": {
"tags": [
"Media"
],
"operationId": "GetMediaByIdReferencedDescendants",
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"name": "skip",
"in": "query",
"schema": {
"type": "integer",
"format": "int32",
"default": 0
}
},
{
"name": "take",
"in": "query",
"schema": {
"type": "integer",
"format": "int32",
"default": 20
}
}
],
"responses": {
"200": {
"description": "Success",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PagedReferenceByIdModel"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/PagedReferenceByIdModel"
}
},
"text/plain": {
"schema": {
"$ref": "#/components/schemas/PagedReferenceByIdModel"
}
}
}
},
"401": {
"description": "The resource is protected and requires an authentication token"
}
},
"security": [
{
"Backoffice User": [ ]
}
]
}
},
"/umbraco/management/api/v1/media/{id}/validate": {
"put": {
"tags": [
@@ -14410,6 +14748,76 @@
]
}
},
"/umbraco/management/api/v1/media/are-referenced": {
"get": {
"tags": [
"Media"
],
"operationId": "GetMediaAreReferenced",
"parameters": [
{
"name": "id",
"in": "query",
"schema": {
"uniqueItems": true,
"type": "array",
"items": {
"type": "string",
"format": "uuid"
}
}
},
{
"name": "skip",
"in": "query",
"schema": {
"type": "integer",
"format": "int32",
"default": 0
}
},
{
"name": "take",
"in": "query",
"schema": {
"type": "integer",
"format": "int32",
"default": 20
}
}
],
"responses": {
"200": {
"description": "Success",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PagedReferenceByIdModel"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/PagedReferenceByIdModel"
}
},
"text/plain": {
"schema": {
"$ref": "#/components/schemas/PagedReferenceByIdModel"
}
}
}
},
"401": {
"description": "The resource is protected and requires an authentication token"
}
},
"security": [
{
"Backoffice User": [ ]
}
]
}
},
"/umbraco/management/api/v1/media/configuration": {
"get": {
"tags": [
@@ -27127,234 +27535,6 @@
]
}
},
"/umbraco/management/api/v1/tracked-reference/{id}": {
"get": {
"tags": [
"Tracked Reference"
],
"operationId": "GetTrackedReferenceById",
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"name": "skip",
"in": "query",
"schema": {
"type": "integer",
"format": "int32",
"default": 0
}
},
{
"name": "take",
"in": "query",
"schema": {
"type": "integer",
"format": "int32",
"default": 20
}
},
{
"name": "filterMustBeIsDependency",
"in": "query",
"schema": {
"type": "boolean",
"default": false
}
}
],
"responses": {
"200": {
"description": "Success",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PagedRelationItemResponseModel"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/PagedRelationItemResponseModel"
}
},
"text/plain": {
"schema": {
"$ref": "#/components/schemas/PagedRelationItemResponseModel"
}
}
}
},
"401": {
"description": "The resource is protected and requires an authentication token"
}
},
"security": [
{
"Backoffice User": [ ]
}
]
}
},
"/umbraco/management/api/v1/tracked-reference/descendants/{parentId}": {
"get": {
"tags": [
"Tracked Reference"
],
"operationId": "GetTrackedReferenceDescendantsByParentId",
"parameters": [
{
"name": "parentId",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"name": "skip",
"in": "query",
"schema": {
"type": "integer",
"format": "int32",
"default": 0
}
},
{
"name": "take",
"in": "query",
"schema": {
"type": "integer",
"format": "int32",
"default": 20
}
},
{
"name": "filterMustBeIsDependency",
"in": "query",
"schema": {
"type": "boolean",
"default": true
}
}
],
"responses": {
"200": {
"description": "Success",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PagedRelationItemResponseModel"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/PagedRelationItemResponseModel"
}
},
"text/plain": {
"schema": {
"$ref": "#/components/schemas/PagedRelationItemResponseModel"
}
}
}
},
"401": {
"description": "The resource is protected and requires an authentication token"
}
},
"security": [
{
"Backoffice User": [ ]
}
]
}
},
"/umbraco/management/api/v1/tracked-reference/item": {
"get": {
"tags": [
"Tracked Reference"
],
"operationId": "GetTrackedReferenceItem",
"parameters": [
{
"name": "id",
"in": "query",
"schema": {
"uniqueItems": true,
"type": "array",
"items": {
"type": "string",
"format": "uuid"
}
}
},
{
"name": "skip",
"in": "query",
"schema": {
"type": "integer",
"format": "int32",
"default": 0
}
},
{
"name": "take",
"in": "query",
"schema": {
"type": "integer",
"format": "int32",
"default": 20
}
},
{
"name": "filterMustBeIsDependency",
"in": "query",
"schema": {
"type": "boolean",
"default": true
}
}
],
"responses": {
"200": {
"description": "Success",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PagedRelationItemResponseModel"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/PagedRelationItemResponseModel"
}
},
"text/plain": {
"schema": {
"$ref": "#/components/schemas/PagedRelationItemResponseModel"
}
}
}
},
"401": {
"description": "The resource is protected and requires an authentication token"
}
},
"security": [
{
"Backoffice User": [ ]
}
]
}
},
"/umbraco/management/api/v1/upgrade/authorize": {
"post": {
"tags": [
@@ -35139,6 +35319,31 @@
},
"additionalProperties": false
},
"DefaultReferenceResponseModel": {
"required": [
"id"
],
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"name": {
"type": "string",
"nullable": true
},
"type": {
"type": "string",
"nullable": true
},
"icon": {
"type": "string",
"nullable": true
}
},
"additionalProperties": false
},
"DeleteUserGroupsRequestModel": {
"required": [
"userGroupIds"
@@ -35511,6 +35716,35 @@
},
"additionalProperties": false
},
"DocumentReferenceResponseModel": {
"required": [
"documentType",
"id"
],
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"name": {
"type": "string",
"nullable": true
},
"published": {
"type": "boolean",
"nullable": true
},
"documentType": {
"oneOf": [
{
"$ref": "#/components/schemas/TrackedReferenceDocumentTypeModel"
}
]
}
},
"additionalProperties": false
},
"DocumentResponseModel": {
"required": [
"documentType",
@@ -37173,6 +37407,31 @@
},
"additionalProperties": false
},
"MediaReferenceResponseModel": {
"required": [
"id",
"mediaType"
],
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"name": {
"type": "string",
"nullable": true
},
"mediaType": {
"oneOf": [
{
"$ref": "#/components/schemas/TrackedReferenceMediaTypeModel"
}
]
}
},
"additionalProperties": false
},
"MediaResponseModel": {
"required": [
"isTrashed",
@@ -38626,6 +38885,36 @@
},
"additionalProperties": false
},
"PagedIReferenceResponseModel": {
"required": [
"items",
"total"
],
"type": "object",
"properties": {
"total": {
"type": "integer",
"format": "int64"
},
"items": {
"type": "array",
"items": {
"oneOf": [
{
"$ref": "#/components/schemas/DefaultReferenceResponseModel"
},
{
"$ref": "#/components/schemas/DocumentReferenceResponseModel"
},
{
"$ref": "#/components/schemas/MediaReferenceResponseModel"
}
]
}
}
},
"additionalProperties": false
},
"PagedIndexResponseModel": {
"required": [
"items",
@@ -39075,7 +39364,7 @@
},
"additionalProperties": false
},
"PagedRelationItemResponseModel": {
"PagedReferenceByIdModel": {
"required": [
"items",
"total"
@@ -39091,7 +39380,7 @@
"items": {
"oneOf": [
{
"$ref": "#/components/schemas/RelationItemResponseModel"
"$ref": "#/components/schemas/ReferenceByIdModel"
}
]
}
@@ -39849,55 +40138,6 @@
},
"additionalProperties": false
},
"RelationItemResponseModel": {
"required": [
"nodeId",
"relationTypeIsBidirectional",
"relationTypeIsDependency"
],
"type": "object",
"properties": {
"nodeId": {
"type": "string",
"format": "uuid"
},
"nodeName": {
"type": "string",
"nullable": true
},
"nodeType": {
"type": "string",
"nullable": true
},
"nodePublished": {
"type": "boolean",
"nullable": true
},
"contentTypeIcon": {
"type": "string",
"nullable": true
},
"contentTypeAlias": {
"type": "string",
"nullable": true
},
"contentTypeName": {
"type": "string",
"nullable": true
},
"relationTypeName": {
"type": "string",
"nullable": true
},
"relationTypeIsBidirectional": {
"type": "boolean"
},
"relationTypeIsDependency": {
"type": "boolean"
}
},
"additionalProperties": false
},
"RelationResponseModel": {
"required": [
"childId",
@@ -40903,6 +41143,42 @@
},
"additionalProperties": false
},
"TrackedReferenceContentTypeModel": {
"type": "object",
"properties": {
"icon": {
"type": "string",
"nullable": true
},
"alias": {
"type": "string",
"nullable": true
},
"name": {
"type": "string",
"nullable": true
}
},
"additionalProperties": false
},
"TrackedReferenceDocumentTypeModel": {
"type": "object",
"allOf": [
{
"$ref": "#/components/schemas/TrackedReferenceContentTypeModel"
}
],
"additionalProperties": false
},
"TrackedReferenceMediaTypeModel": {
"type": "object",
"allOf": [
{
"$ref": "#/components/schemas/TrackedReferenceContentTypeModel"
}
],
"additionalProperties": false
},
"TreeItemPresentationModel": {
"required": [
"hasChildren"

View File

@@ -0,0 +1,12 @@
namespace Umbraco.Cms.Api.Management.ViewModels.TrackedReferences;
public class DefaultReferenceResponseModel : IReferenceResponseModel
{
public Guid Id { get; set; }
public string? Name { get; set; }
public string? Type { get; set; }
public string? Icon { get; set; }
}

View File

@@ -0,0 +1,12 @@
namespace Umbraco.Cms.Api.Management.ViewModels.TrackedReferences;
public class DocumentReferenceResponseModel : IReferenceResponseModel
{
public Guid Id { get; set; }
public string? Name { get; set; }
public bool? Published { get; set; }
public TrackedReferenceDocumentType DocumentType { get; set; } = new();
}

View File

@@ -0,0 +1,8 @@
namespace Umbraco.Cms.Api.Management.ViewModels.TrackedReferences;
public interface IReferenceResponseModel
{
public Guid Id { get; }
public string? Name { get; }
}

View File

@@ -0,0 +1,10 @@
namespace Umbraco.Cms.Api.Management.ViewModels.TrackedReferences;
public class MediaReferenceResponseModel : IReferenceResponseModel
{
public Guid Id { get; set; }
public string? Name { get; set; }
public TrackedReferenceMediaType MediaType { get; set; } = new();
}

View File

@@ -1,25 +0,0 @@
namespace Umbraco.Cms.Api.Management.ViewModels.TrackedReferences;
public class RelationItemResponseModel
{
public Guid NodeId { get; set; }
public string? NodeName { get; set; }
public string? NodeType { get; set; }
public bool? NodePublished { get; set; }
public string? ContentTypeIcon { get; set; }
public string? ContentTypeAlias { get; set; }
public string? ContentTypeName { get; set; }
public string? RelationTypeName { get; set; }
public bool RelationTypeIsBidirectional { get; set; }
public bool RelationTypeIsDependency { get; set; }
}

View File

@@ -0,0 +1,10 @@
namespace Umbraco.Cms.Api.Management.ViewModels.TrackedReferences;
public abstract class TrackedReferenceContentType
{
public string? Icon { get; set; }
public string? Alias { get; set; }
public string? Name { get; set; }
}

View File

@@ -0,0 +1,5 @@
namespace Umbraco.Cms.Api.Management.ViewModels.TrackedReferences;
public class TrackedReferenceDocumentType : TrackedReferenceContentType
{
}

View File

@@ -0,0 +1,5 @@
namespace Umbraco.Cms.Api.Management.ViewModels.TrackedReferences;
public class TrackedReferenceMediaType : TrackedReferenceContentType
{
}