Member types: Implement containers (#20706)
* Add MemberType/MemberTypeContainer to supported EntityContainer object types * Implement MemberTypeContainerRepository * Update and add member type container API endpoints * Complete server and client-side implementation for member type container support. * Fix FE linting errors. * Export folder constants. * Applied suggestions from code review. * Updated management API authorization tests for member types. * Resolved breaking change on copy member type controller. * Allow content types to be moved to own folder without error. * Use flag providers for member type siblings endpoint. --------- Co-authored-by: Andy Butland <abutland73@gmail.com>
This commit is contained in:
@@ -31,7 +31,7 @@ public abstract class MediaTypeControllerBase : ManagementApiControllerBase
|
||||
.WithDetail("The import failed due to not being able to convert the file into proper xml.")
|
||||
.Build()),
|
||||
MediaTypeImportOperationStatus.MediaTypeExists => BadRequest(problemDetailsBuilder
|
||||
.WithTitle("Failed to import because media type exits")
|
||||
.WithTitle("Failed to import because media type exists")
|
||||
.WithDetail("The import failed because the media type that was being imported already exits.")
|
||||
.Build()),
|
||||
MediaTypeImportOperationStatus.TypeMismatch => BadRequest(problemDetailsBuilder
|
||||
@@ -42,6 +42,6 @@ public abstract class MediaTypeControllerBase : ManagementApiControllerBase
|
||||
.WithTitle("Invalid Id")
|
||||
.WithDetail("The import failed because the id of the media type you are trying to update did not match the id in the file.")
|
||||
.Build()),
|
||||
_ => StatusCode(StatusCodes.Status500InternalServerError, "Unknown media type import operation status.")
|
||||
_ => StatusCode(StatusCodes.Status500InternalServerError, "Unknown media type import operation status."),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
using Asp.Versioning;
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.MemberType;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
@@ -24,9 +25,12 @@ public class CopyMemberTypeController : MemberTypeControllerBase
|
||||
[ProducesResponseType(StatusCodes.Status201Created)]
|
||||
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
|
||||
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
|
||||
public async Task<IActionResult> Copy(CancellationToken cancellationToken, Guid id)
|
||||
public async Task<IActionResult> Copy(
|
||||
CancellationToken cancellationToken,
|
||||
Guid id,
|
||||
CopyMemberTypeRequestModel? copyMemberTypeRequestModel)
|
||||
{
|
||||
Attempt<IMemberType?, ContentTypeStructureOperationStatus> result = await _memberTypeService.CopyAsync(id, containerKey: null);
|
||||
Attempt<IMemberType?, ContentTypeStructureOperationStatus> result = await _memberTypeService.CopyAsync(id, copyMemberTypeRequestModel?.Target?.Id);
|
||||
|
||||
return result.Success
|
||||
? CreatedAtId<ByKeyMemberTypeController>(controller => nameof(controller.ByKey), result.Result!.Key)
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Api.Management.Factories;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Core.Services.OperationStatus;
|
||||
using Umbraco.Cms.Web.Common.Authorization;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.MemberType;
|
||||
|
||||
[ApiVersion("1.0")]
|
||||
[Authorize(Policy = AuthorizationPolicies.TreeAccessMemberTypes)]
|
||||
public class ExportMemberTypeController : MemberTypeControllerBase
|
||||
{
|
||||
private readonly IMemberTypeService _memberTypeService;
|
||||
private readonly IUdtFileContentFactory _fileContentFactory;
|
||||
|
||||
public ExportMemberTypeController(
|
||||
IMemberTypeService memberTypeService,
|
||||
IUdtFileContentFactory fileContentFactory)
|
||||
{
|
||||
_memberTypeService = memberTypeService;
|
||||
_fileContentFactory = fileContentFactory;
|
||||
}
|
||||
|
||||
[HttpGet("{id:guid}/export")]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(typeof(FileContentResult), StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
|
||||
public IActionResult Export(
|
||||
CancellationToken cancellationToken,
|
||||
Guid id)
|
||||
{
|
||||
IMemberType? memberType = _memberTypeService.Get(id);
|
||||
if (memberType is null)
|
||||
{
|
||||
return OperationStatusResult(ContentTypeOperationStatus.NotFound);
|
||||
}
|
||||
|
||||
return _fileContentFactory.Create(memberType);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.MemberType;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Security;
|
||||
using Umbraco.Cms.Core.Services.ImportExport;
|
||||
using Umbraco.Cms.Core.Services.OperationStatus;
|
||||
using Umbraco.Cms.Web.Common.Authorization;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.MemberType;
|
||||
|
||||
[ApiVersion("1.0")]
|
||||
[Authorize(Policy = AuthorizationPolicies.TreeAccessMemberTypes)]
|
||||
public class ImportExistingMemberTypeController : MemberTypeControllerBase
|
||||
{
|
||||
private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor;
|
||||
private readonly IMemberTypeImportService _memberTypeImportService;
|
||||
|
||||
public ImportExistingMemberTypeController(
|
||||
IBackOfficeSecurityAccessor backOfficeSecurityAccessor,
|
||||
IMemberTypeImportService memberTypeImportService)
|
||||
{
|
||||
_backOfficeSecurityAccessor = backOfficeSecurityAccessor;
|
||||
_memberTypeImportService = memberTypeImportService;
|
||||
}
|
||||
|
||||
[HttpPut("{id:guid}/import")]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
|
||||
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
|
||||
public async Task<IActionResult> Import(
|
||||
CancellationToken cancellationToken,
|
||||
Guid id,
|
||||
ImportMemberTypeRequestModel model)
|
||||
{
|
||||
Attempt<IMemberType?, MemberTypeImportOperationStatus> importAttempt = await _memberTypeImportService.Import(model.File.Id, CurrentUserKey(_backOfficeSecurityAccessor));
|
||||
|
||||
return importAttempt.Success is false
|
||||
? MemberTypeImportOperationStatusResult(importAttempt.Status)
|
||||
: Ok();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.MemberType;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Security;
|
||||
using Umbraco.Cms.Core.Services.ImportExport;
|
||||
using Umbraco.Cms.Core.Services.OperationStatus;
|
||||
using Umbraco.Cms.Web.Common.Authorization;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.MemberType;
|
||||
|
||||
[ApiVersion("1.0")]
|
||||
[Authorize(Policy = AuthorizationPolicies.TreeAccessMemberTypes)]
|
||||
public class ImportNewMemberTypeController : MemberTypeControllerBase
|
||||
{
|
||||
private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor;
|
||||
private readonly IMemberTypeImportService _memberTypeImportService;
|
||||
|
||||
public ImportNewMemberTypeController(
|
||||
IBackOfficeSecurityAccessor backOfficeSecurityAccessor,
|
||||
IMemberTypeImportService memberTypeImportService)
|
||||
{
|
||||
_backOfficeSecurityAccessor = backOfficeSecurityAccessor;
|
||||
_memberTypeImportService = memberTypeImportService;
|
||||
}
|
||||
|
||||
[HttpPost("import")]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(StatusCodes.Status201Created)]
|
||||
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
|
||||
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
|
||||
public async Task<IActionResult> Import(
|
||||
CancellationToken cancellationToken,
|
||||
ImportMemberTypeRequestModel model)
|
||||
{
|
||||
Attempt<IMemberType?, MemberTypeImportOperationStatus> importAttempt = await _memberTypeImportService.Import(model.File.Id, CurrentUserKey(_backOfficeSecurityAccessor));
|
||||
|
||||
return importAttempt.Success is false
|
||||
? MemberTypeImportOperationStatusResult(importAttempt.Status)
|
||||
: CreatedAtId<ByKeyMemberTypeController>(controller => nameof(controller.ByKey), importAttempt.Result!.Key);
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Api.Management.Controllers.DocumentType;
|
||||
using Umbraco.Cms.Api.Management.Routing;
|
||||
@@ -18,4 +19,29 @@ public abstract class MemberTypeControllerBase : ManagementApiControllerBase
|
||||
|
||||
protected IActionResult StructureOperationStatusResult(ContentTypeStructureOperationStatus status)
|
||||
=> DocumentTypeControllerBase.ContentTypeStructureOperationStatusResult(status, "member");
|
||||
|
||||
protected IActionResult MemberTypeImportOperationStatusResult(MemberTypeImportOperationStatus operationStatus) =>
|
||||
OperationStatusResult(operationStatus, problemDetailsBuilder => operationStatus switch
|
||||
{
|
||||
MemberTypeImportOperationStatus.TemporaryFileNotFound => NotFound(problemDetailsBuilder
|
||||
.WithTitle("Temporary file not found")
|
||||
.Build()),
|
||||
MemberTypeImportOperationStatus.TemporaryFileConversionFailure => BadRequest(problemDetailsBuilder
|
||||
.WithTitle("Failed to convert the specified file")
|
||||
.WithDetail("The import failed due to not being able to convert the file into proper xml.")
|
||||
.Build()),
|
||||
MemberTypeImportOperationStatus.MemberTypeExists => BadRequest(problemDetailsBuilder
|
||||
.WithTitle("Failed to import because member type exists")
|
||||
.WithDetail("The import failed because the member type that was being imported already exits.")
|
||||
.Build()),
|
||||
MemberTypeImportOperationStatus.TypeMismatch => BadRequest(problemDetailsBuilder
|
||||
.WithTitle("Type Mismatch")
|
||||
.WithDetail("The import failed because the file contained an entity that is not a member type.")
|
||||
.Build()),
|
||||
MemberTypeImportOperationStatus.IdMismatch => BadRequest(problemDetailsBuilder
|
||||
.WithTitle("Invalid Id")
|
||||
.WithDetail("The import failed because the id of the member type you are trying to update did not match the id in the file.")
|
||||
.Build()),
|
||||
_ => StatusCode(StatusCodes.Status500InternalServerError, "Unknown member type import operation status."),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.MemberType;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Core.Services.OperationStatus;
|
||||
using Umbraco.Cms.Web.Common.Authorization;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.MemberType;
|
||||
|
||||
[ApiVersion("1.0")]
|
||||
[Authorize(Policy = AuthorizationPolicies.TreeAccessMemberTypes)]
|
||||
public class MoveMemberTypeController : MemberTypeControllerBase
|
||||
{
|
||||
private readonly IMemberTypeService _memberTypeService;
|
||||
|
||||
public MoveMemberTypeController(IMemberTypeService memberTypeService)
|
||||
=> _memberTypeService = memberTypeService;
|
||||
|
||||
[HttpPut("{id:guid}/move")]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
|
||||
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
|
||||
public async Task<IActionResult> Move(
|
||||
CancellationToken cancellationToken,
|
||||
Guid id,
|
||||
MoveMemberTypeRequestModel moveMemberTypeRequestModel)
|
||||
{
|
||||
Attempt<IMemberType?, ContentTypeStructureOperationStatus> result = await _memberTypeService.MoveAsync(id, moveMemberTypeRequestModel.Target?.Id);
|
||||
|
||||
return result.Success
|
||||
? Ok()
|
||||
: StructureOperationStatusResult(result.Status);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Api.Management.Services.Flags;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.Tree;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.MemberType.Tree;
|
||||
|
||||
[ApiVersion("1.0")]
|
||||
public class AncestorsMemberTypeTreeController : MemberTypeTreeControllerBase
|
||||
{
|
||||
public AncestorsMemberTypeTreeController(IEntityService entityService, FlagProviderCollection flagProviders, IMemberTypeService memberTypeService)
|
||||
: base(entityService, flagProviders, memberTypeService)
|
||||
{
|
||||
}
|
||||
|
||||
[HttpGet("ancestors")]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(typeof(IEnumerable<MemberTypeTreeItemResponseModel>), StatusCodes.Status200OK)]
|
||||
public async Task<ActionResult<IEnumerable<MemberTypeTreeItemResponseModel>>> Ancestors(CancellationToken cancellationToken, Guid descendantId)
|
||||
=> await GetAncestors(descendantId);
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Api.Common.ViewModels.Pagination;
|
||||
using Umbraco.Cms.Api.Management.Services.Flags;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.Tree;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Controllers.MemberType.Tree;
|
||||
|
||||
[ApiVersion("1.0")]
|
||||
public class ChildrenMemberTypeTreeController : MemberTypeTreeControllerBase
|
||||
{
|
||||
public ChildrenMemberTypeTreeController(IEntityService entityService, FlagProviderCollection flagProviders, IMemberTypeService memberTypeService)
|
||||
: base(entityService, flagProviders, memberTypeService)
|
||||
{ }
|
||||
|
||||
[HttpGet("children")]
|
||||
[MapToApiVersion("1.0")]
|
||||
[ProducesResponseType(typeof(PagedViewModel<MemberTypeTreeItemResponseModel>), StatusCodes.Status200OK)]
|
||||
public async Task<ActionResult<PagedViewModel<MemberTypeTreeItemResponseModel>>> Children(
|
||||
CancellationToken cancellationToken,
|
||||
Guid parentId,
|
||||
int skip = 0,
|
||||
int take = 100,
|
||||
bool foldersOnly = false)
|
||||
{
|
||||
RenderFoldersOnly(foldersOnly);
|
||||
return await GetChildren(parentId, skip, take);
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,7 @@ namespace Umbraco.Cms.Api.Management.Controllers.MemberType.Tree;
|
||||
[VersionedApiBackOfficeRoute($"{Constants.Web.RoutePath.Tree}/{Constants.UdiEntityType.MemberType}")]
|
||||
[ApiExplorerSettings(GroupName = "Member Type")]
|
||||
[Authorize(Policy = AuthorizationPolicies.TreeAccessMembersOrMemberTypes)]
|
||||
public class MemberTypeTreeControllerBase : NamedEntityTreeControllerBase<MemberTypeTreeItemResponseModel>
|
||||
public class MemberTypeTreeControllerBase : FolderTreeControllerBase<MemberTypeTreeItemResponseModel>
|
||||
{
|
||||
private readonly IMemberTypeService _memberTypeService;
|
||||
|
||||
@@ -37,6 +37,8 @@ public class MemberTypeTreeControllerBase : NamedEntityTreeControllerBase<Member
|
||||
|
||||
protected override UmbracoObjectTypes ItemObjectType => UmbracoObjectTypes.MemberType;
|
||||
|
||||
protected override UmbracoObjectTypes FolderObjectType => UmbracoObjectTypes.MemberTypeContainer;
|
||||
|
||||
protected override MemberTypeTreeItemResponseModel[] MapTreeItemViewModels(Guid? parentKey, IEntitySlim[] entities)
|
||||
{
|
||||
var memberTypes = _memberTypeService
|
||||
|
||||
@@ -32,5 +32,8 @@ public class RootMemberTypeTreeController : MemberTypeTreeControllerBase
|
||||
int skip = 0,
|
||||
int take = 100,
|
||||
bool foldersOnly = false)
|
||||
=> await GetRoot(skip, take);
|
||||
{
|
||||
RenderFoldersOnly(foldersOnly);
|
||||
return await GetRoot(skip, take);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Umbraco.Cms.Api.Common.ViewModels.Pagination;
|
||||
using Umbraco.Cms.Api.Management.Services.Flags;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.Tree;
|
||||
@@ -9,10 +10,14 @@ namespace Umbraco.Cms.Api.Management.Controllers.MemberType.Tree;
|
||||
|
||||
public class SiblingMemberTypeTreeController : MemberTypeTreeControllerBase
|
||||
{
|
||||
public SiblingMemberTypeTreeController(
|
||||
IEntityService entityService,
|
||||
FlagProviderCollection flagProviders,
|
||||
IMemberTypeService memberTypeService)
|
||||
[Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 18.")]
|
||||
public SiblingMemberTypeTreeController(IEntityService entityService, IMemberTypeService memberTypeService)
|
||||
: base(entityService, memberTypeService)
|
||||
{
|
||||
}
|
||||
|
||||
[ActivatorUtilitiesConstructor]
|
||||
public SiblingMemberTypeTreeController(IEntityService entityService, FlagProviderCollection flagProviders, IMemberTypeService memberTypeService)
|
||||
: base(entityService, flagProviders, memberTypeService)
|
||||
{
|
||||
}
|
||||
@@ -25,5 +30,8 @@ public class SiblingMemberTypeTreeController : MemberTypeTreeControllerBase
|
||||
int before,
|
||||
int after,
|
||||
bool foldersOnly = false)
|
||||
=> await GetSiblings(target, before, after);
|
||||
{
|
||||
RenderFoldersOnly(foldersOnly);
|
||||
return await GetSiblings(target, before, after);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,4 +8,6 @@ public interface IUdtFileContentFactory
|
||||
FileContentResult Create(IContentType contentType);
|
||||
|
||||
FileContentResult Create(IMediaType mediaType);
|
||||
|
||||
FileContentResult Create(IMemberType mediaType) => throw new NotImplementedException();
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using Umbraco.Cms.Api.Management.ViewModels.MemberType;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.MemberType;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Models.ContentTypeEditing;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
@@ -24,6 +24,7 @@ internal sealed class MemberTypeEditingPresentationFactory : ContentTypeEditingP
|
||||
|
||||
createModel.Key = requestModel.Id;
|
||||
createModel.Compositions = MapCompositions(requestModel.Compositions);
|
||||
createModel.ContainerKey = requestModel.Parent?.Id;
|
||||
|
||||
MapPropertyTypeSensitivityAndVisibility(createModel.Properties, requestModel.Properties);
|
||||
|
||||
|
||||
@@ -27,6 +27,12 @@ public class UdtFileContentFactory : IUdtFileContentFactory
|
||||
return XmlTofile(mediaType, xml);
|
||||
}
|
||||
|
||||
public FileContentResult Create(IMemberType memberType)
|
||||
{
|
||||
XElement xml = _entityXmlSerializer.Serialize(memberType);
|
||||
return XmlTofile(memberType, xml);
|
||||
}
|
||||
|
||||
private static FileContentResult XmlTofile(IContentTypeBase contentTypeBase, XElement xml) =>
|
||||
new(Encoding.UTF8.GetBytes(xml.ToDataString()), MediaTypeNames.Application.Octet)
|
||||
{
|
||||
|
||||
@@ -11898,6 +11898,95 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
"/umbraco/management/api/v1/help": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"Help"
|
||||
],
|
||||
"operationId": "GetHelp",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "section",
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "tree",
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "skip",
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "integer",
|
||||
"format": "int32",
|
||||
"default": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "take",
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "integer",
|
||||
"format": "int32",
|
||||
"default": 100
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "baseUrl",
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"default": "https://our.umbraco.com"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"400": {
|
||||
"description": "Bad Request",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/ProblemDetails"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/PagedHelpPageResponseModel"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "The resource is protected and requires an authentication token"
|
||||
}
|
||||
},
|
||||
"deprecated": true,
|
||||
"security": [
|
||||
{
|
||||
"Backoffice-User": [ ]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"/umbraco/management/api/v1/imaging/resize/urls": {
|
||||
"get": {
|
||||
"tags": [
|
||||
@@ -19996,6 +20085,37 @@
|
||||
}
|
||||
}
|
||||
],
|
||||
"requestBody": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/CopyMemberTypeRequestModel"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"text/json": {
|
||||
"schema": {
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/CopyMemberTypeRequestModel"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"application/*+json": {
|
||||
"schema": {
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/CopyMemberTypeRequestModel"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"responses": {
|
||||
"201": {
|
||||
"description": "Created",
|
||||
@@ -20105,6 +20225,351 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
"/umbraco/management/api/v1/member-type/{id}/export": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"Member Type"
|
||||
],
|
||||
"operationId": "GetMemberTypeByIdExport",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"format": "uuid"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "string",
|
||||
"format": "binary"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
"description": "Not Found",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/ProblemDetails"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "The resource is protected and requires an authentication token"
|
||||
},
|
||||
"403": {
|
||||
"description": "The authenticated user does not have access to this resource"
|
||||
}
|
||||
},
|
||||
"security": [
|
||||
{
|
||||
"Backoffice-User": [ ]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"/umbraco/management/api/v1/member-type/{id}/import": {
|
||||
"put": {
|
||||
"tags": [
|
||||
"Member Type"
|
||||
],
|
||||
"operationId": "PutMemberTypeByIdImport",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"format": "uuid"
|
||||
}
|
||||
}
|
||||
],
|
||||
"requestBody": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/ImportMemberTypeRequestModel"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"text/json": {
|
||||
"schema": {
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/ImportMemberTypeRequestModel"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"application/*+json": {
|
||||
"schema": {
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/ImportMemberTypeRequestModel"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"headers": {
|
||||
"Umb-Notifications": {
|
||||
"description": "The list of notifications produced during the request.",
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/NotificationHeaderModel"
|
||||
},
|
||||
"nullable": true
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
"description": "Not Found",
|
||||
"headers": {
|
||||
"Umb-Notifications": {
|
||||
"description": "The list of notifications produced during the request.",
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/NotificationHeaderModel"
|
||||
},
|
||||
"nullable": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/ProblemDetails"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Bad Request",
|
||||
"headers": {
|
||||
"Umb-Notifications": {
|
||||
"description": "The list of notifications produced during the request.",
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/NotificationHeaderModel"
|
||||
},
|
||||
"nullable": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/ProblemDetails"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "The resource is protected and requires an authentication token"
|
||||
},
|
||||
"403": {
|
||||
"description": "The authenticated user does not have access to this resource",
|
||||
"headers": {
|
||||
"Umb-Notifications": {
|
||||
"description": "The list of notifications produced during the request.",
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/NotificationHeaderModel"
|
||||
},
|
||||
"nullable": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"security": [
|
||||
{
|
||||
"Backoffice-User": [ ]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"/umbraco/management/api/v1/member-type/{id}/move": {
|
||||
"put": {
|
||||
"tags": [
|
||||
"Member Type"
|
||||
],
|
||||
"operationId": "PutMemberTypeByIdMove",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"format": "uuid"
|
||||
}
|
||||
}
|
||||
],
|
||||
"requestBody": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/MoveMemberTypeRequestModel"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"text/json": {
|
||||
"schema": {
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/MoveMemberTypeRequestModel"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"application/*+json": {
|
||||
"schema": {
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/MoveMemberTypeRequestModel"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"headers": {
|
||||
"Umb-Notifications": {
|
||||
"description": "The list of notifications produced during the request.",
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/NotificationHeaderModel"
|
||||
},
|
||||
"nullable": true
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Bad Request",
|
||||
"headers": {
|
||||
"Umb-Notifications": {
|
||||
"description": "The list of notifications produced during the request.",
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/NotificationHeaderModel"
|
||||
},
|
||||
"nullable": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/ProblemDetails"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
"description": "Not Found",
|
||||
"headers": {
|
||||
"Umb-Notifications": {
|
||||
"description": "The list of notifications produced during the request.",
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/NotificationHeaderModel"
|
||||
},
|
||||
"nullable": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/ProblemDetails"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "The resource is protected and requires an authentication token"
|
||||
},
|
||||
"403": {
|
||||
"description": "The authenticated user does not have access to this resource",
|
||||
"headers": {
|
||||
"Umb-Notifications": {
|
||||
"description": "The list of notifications produced during the request.",
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/NotificationHeaderModel"
|
||||
},
|
||||
"nullable": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"security": [
|
||||
{
|
||||
"Backoffice-User": [ ]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"/umbraco/management/api/v1/member-type/available-compositions": {
|
||||
"post": {
|
||||
"tags": [
|
||||
@@ -20688,6 +21153,271 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
"/umbraco/management/api/v1/member-type/import": {
|
||||
"post": {
|
||||
"tags": [
|
||||
"Member Type"
|
||||
],
|
||||
"operationId": "PostMemberTypeImport",
|
||||
"requestBody": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/ImportMemberTypeRequestModel"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"text/json": {
|
||||
"schema": {
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/ImportMemberTypeRequestModel"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"application/*+json": {
|
||||
"schema": {
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/ImportMemberTypeRequestModel"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"responses": {
|
||||
"201": {
|
||||
"description": "Created",
|
||||
"headers": {
|
||||
"Umb-Generated-Resource": {
|
||||
"description": "Identifier of the newly created resource",
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"description": "Identifier of the newly created resource"
|
||||
}
|
||||
},
|
||||
"Location": {
|
||||
"description": "Location of the newly created resource",
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"description": "Location of the newly created resource",
|
||||
"format": "uri"
|
||||
}
|
||||
},
|
||||
"Umb-Notifications": {
|
||||
"description": "The list of notifications produced during the request.",
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/NotificationHeaderModel"
|
||||
},
|
||||
"nullable": true
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
"description": "Not Found",
|
||||
"headers": {
|
||||
"Umb-Notifications": {
|
||||
"description": "The list of notifications produced during the request.",
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/NotificationHeaderModel"
|
||||
},
|
||||
"nullable": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/ProblemDetails"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Bad Request",
|
||||
"headers": {
|
||||
"Umb-Notifications": {
|
||||
"description": "The list of notifications produced during the request.",
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/NotificationHeaderModel"
|
||||
},
|
||||
"nullable": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/ProblemDetails"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "The resource is protected and requires an authentication token"
|
||||
},
|
||||
"403": {
|
||||
"description": "The authenticated user does not have access to this resource",
|
||||
"headers": {
|
||||
"Umb-Notifications": {
|
||||
"description": "The list of notifications produced during the request.",
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/NotificationHeaderModel"
|
||||
},
|
||||
"nullable": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"security": [
|
||||
{
|
||||
"Backoffice-User": [ ]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"/umbraco/management/api/v1/tree/member-type/ancestors": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"Member Type"
|
||||
],
|
||||
"operationId": "GetTreeMemberTypeAncestors",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "descendantId",
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"format": "uuid"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/MemberTypeTreeItemResponseModel"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "The resource is protected and requires an authentication token"
|
||||
},
|
||||
"403": {
|
||||
"description": "The authenticated user does not have access to this resource"
|
||||
}
|
||||
},
|
||||
"security": [
|
||||
{
|
||||
"Backoffice-User": [ ]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"/umbraco/management/api/v1/tree/member-type/children": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"Member Type"
|
||||
],
|
||||
"operationId": "GetTreeMemberTypeChildren",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "parentId",
|
||||
"in": "query",
|
||||
"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": 100
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "foldersOnly",
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/PagedMemberTypeTreeItemResponseModel"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "The resource is protected and requires an authentication token"
|
||||
},
|
||||
"403": {
|
||||
"description": "The authenticated user does not have access to this resource"
|
||||
}
|
||||
},
|
||||
"security": [
|
||||
{
|
||||
"Backoffice-User": [ ]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"/umbraco/management/api/v1/tree/member-type/root": {
|
||||
"get": {
|
||||
"tags": [
|
||||
@@ -20712,6 +21442,14 @@
|
||||
"format": "int32",
|
||||
"default": 100
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "foldersOnly",
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
@@ -20773,6 +21511,14 @@
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "foldersOnly",
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
@@ -36266,6 +37012,20 @@
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"CopyMemberTypeRequestModel": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"target": {
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/ReferenceByIdModel"
|
||||
}
|
||||
],
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"CreateDataTypeRequestModel": {
|
||||
"required": [
|
||||
"editorAlias",
|
||||
@@ -37361,6 +38121,14 @@
|
||||
"format": "uuid",
|
||||
"nullable": true
|
||||
},
|
||||
"parent": {
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/ReferenceByIdModel"
|
||||
}
|
||||
],
|
||||
"nullable": true
|
||||
},
|
||||
"compositions": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
@@ -40574,7 +41342,7 @@
|
||||
},
|
||||
"actionParameters": {
|
||||
"type": "object",
|
||||
"additionalProperties": {},
|
||||
"additionalProperties": { },
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
@@ -40824,6 +41592,22 @@
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"ImportMemberTypeRequestModel": {
|
||||
"required": [
|
||||
"file"
|
||||
],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"file": {
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/ReferenceByIdModel"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"IndexResponseModel": {
|
||||
"required": [
|
||||
"canRebuild",
|
||||
@@ -41199,7 +41983,7 @@
|
||||
},
|
||||
"extensions": {
|
||||
"type": "array",
|
||||
"items": {}
|
||||
"items": { }
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
@@ -42852,6 +43636,7 @@
|
||||
"hasChildren",
|
||||
"icon",
|
||||
"id",
|
||||
"isFolder",
|
||||
"name"
|
||||
],
|
||||
"type": "object",
|
||||
@@ -42884,6 +43669,9 @@
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"isFolder": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"icon": {
|
||||
"type": "string"
|
||||
}
|
||||
@@ -43129,6 +43917,20 @@
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"MoveMemberTypeRequestModel": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"target": {
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/ReferenceByIdModel"
|
||||
}
|
||||
],
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"NamedEntityTreeItemResponseModel": {
|
||||
"required": [
|
||||
"flags",
|
||||
@@ -45071,7 +45873,7 @@
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
"additionalProperties": {}
|
||||
"additionalProperties": { }
|
||||
},
|
||||
"ProblemDetailsBuilderModel": {
|
||||
"type": "object",
|
||||
@@ -48718,8 +49520,7 @@
|
||||
"type": "string"
|
||||
},
|
||||
"subscribeToNewsletter": {
|
||||
"type": "boolean",
|
||||
"readOnly": true
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
namespace Umbraco.Cms.Api.Management.ViewModels.MemberType;
|
||||
|
||||
public class CopyMemberTypeRequestModel
|
||||
{
|
||||
public ReferenceByIdModel? Target { get; set; }
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
using Umbraco.Cms.Api.Management.ViewModels.ContentType;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.ContentType;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.ViewModels.MemberType;
|
||||
|
||||
public class CreateMemberTypeRequestModel
|
||||
: CreateContentTypeRequestModelBase<CreateMemberTypePropertyTypeRequestModel, CreateMemberTypePropertyTypeContainerRequestModel>
|
||||
: CreateContentTypeWithParentRequestModelBase<CreateMemberTypePropertyTypeRequestModel, CreateMemberTypePropertyTypeContainerRequestModel>
|
||||
{
|
||||
public IEnumerable<MemberTypeComposition> Compositions { get; set; } = Enumerable.Empty<MemberTypeComposition>();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
namespace Umbraco.Cms.Api.Management.ViewModels.MemberType;
|
||||
|
||||
public class ImportMemberTypeRequestModel
|
||||
{
|
||||
public required ReferenceByIdModel File { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
namespace Umbraco.Cms.Api.Management.ViewModels.MemberType;
|
||||
|
||||
public class MoveMemberTypeRequestModel
|
||||
{
|
||||
public ReferenceByIdModel? Target { get; set; }
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
namespace Umbraco.Cms.Api.Management.ViewModels.Tree;
|
||||
namespace Umbraco.Cms.Api.Management.ViewModels.Tree;
|
||||
|
||||
public class MemberTypeTreeItemResponseModel : NamedEntityTreeItemResponseModel
|
||||
public class MemberTypeTreeItemResponseModel : FolderTreeItemResponseModel
|
||||
{
|
||||
public string Icon { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
@@ -430,6 +430,7 @@ namespace Umbraco.Cms.Core.DependencyInjection
|
||||
Services.AddUnique<ITemporaryFileToXmlImportService, TemporaryFileToXmlImportService>();
|
||||
Services.AddUnique<IContentTypeImportService, ContentTypeImportService>();
|
||||
Services.AddUnique<IMediaTypeImportService, MediaTypeImportService>();
|
||||
Services.AddUnique<IMemberTypeImportService, MemberTypeImportService>();
|
||||
|
||||
// add validation services
|
||||
Services.AddUnique<IElementSwitchValidator, ElementSwitchValidator>();
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
namespace Umbraco.Cms.Core.Models.ContentTypeEditing;
|
||||
namespace Umbraco.Cms.Core.Models.ContentTypeEditing;
|
||||
|
||||
public class MemberTypeCreateModel : MemberTypeModelBase
|
||||
{
|
||||
public Guid? Key { get; set; }
|
||||
|
||||
public Guid? ContainerKey { get; set; }
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Models.ContentTypeEditing;
|
||||
using Umbraco.Cms.Core.Services.OperationStatus;
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ internal sealed class MemberTypeEditingService : ContentTypeEditingServiceBase<I
|
||||
|
||||
public async Task<Attempt<IMemberType?, ContentTypeOperationStatus>> CreateAsync(MemberTypeCreateModel model, Guid userKey)
|
||||
{
|
||||
Attempt<IMemberType?, ContentTypeOperationStatus> result = await ValidateAndMapForCreationAsync(model, model.Key, containerKey: null);
|
||||
Attempt<IMemberType?, ContentTypeOperationStatus> result = await ValidateAndMapForCreationAsync(model, model.Key, model.ContainerKey);
|
||||
if (result.Success is false)
|
||||
{
|
||||
return result;
|
||||
@@ -80,7 +80,7 @@ internal sealed class MemberTypeEditingService : ContentTypeEditingServiceBase<I
|
||||
|
||||
protected override UmbracoObjectTypes ContentTypeObjectType => UmbracoObjectTypes.MemberType;
|
||||
|
||||
protected override UmbracoObjectTypes ContainerObjectType => throw new NotSupportedException("Member type tree does not support containers");
|
||||
protected override UmbracoObjectTypes ContainerObjectType => UmbracoObjectTypes.MemberTypeContainer;
|
||||
|
||||
protected override ISet<string> GetReservedFieldNames() => _reservedFieldNamesService.GetMemberReservedFieldNames();
|
||||
|
||||
|
||||
@@ -1053,9 +1053,9 @@ public abstract class ContentTypeServiceBase<TRepository, TItem> : ContentTypeSe
|
||||
public Attempt<OperationResult<MoveOperationStatusType>?> Move(TItem moving, int containerId)
|
||||
{
|
||||
EventMessages eventMessages = EventMessagesFactory.Get();
|
||||
if(moving.ParentId == containerId)
|
||||
if (moving.ParentId == containerId)
|
||||
{
|
||||
return OperationResult.Attempt.Fail(MoveOperationStatusType.FailedNotAllowedByPath, eventMessages);
|
||||
return OperationResult.Attempt.Succeed(MoveOperationStatusType.Success, eventMessages);
|
||||
}
|
||||
|
||||
var moveInfo = new List<MoveEventInfo<TItem>>();
|
||||
|
||||
@@ -374,7 +374,11 @@ internal sealed class EntityXmlSerializer : IEntityXmlSerializer
|
||||
return xml;
|
||||
}
|
||||
|
||||
public XElement Serialize(IMediaType mediaType)
|
||||
public XElement Serialize(IMediaType mediaType) => SerializeMediaOrMemberType(mediaType, IEntityXmlSerializer.MediaTypeElementName);
|
||||
|
||||
public XElement Serialize(IMemberType memberType) => SerializeMediaOrMemberType(memberType, IEntityXmlSerializer.MemberTypeElementName);
|
||||
|
||||
private XElement SerializeMediaOrMemberType(IContentTypeComposition mediaType, string elementName)
|
||||
{
|
||||
var info = new XElement(
|
||||
"Info",
|
||||
@@ -410,7 +414,7 @@ internal sealed class EntityXmlSerializer : IEntityXmlSerializer
|
||||
SerializePropertyGroups(mediaType.PropertyGroups)); // TODO Rename to PropertyGroups
|
||||
|
||||
var xml = new XElement(
|
||||
IEntityXmlSerializer.MediaTypeElementName,
|
||||
elementName,
|
||||
info,
|
||||
structure,
|
||||
genericProperties,
|
||||
|
||||
@@ -10,6 +10,7 @@ public interface IEntityXmlSerializer
|
||||
{
|
||||
internal const string DocumentTypeElementName = "DocumentType";
|
||||
internal const string MediaTypeElementName = "MediaType";
|
||||
internal const string MemberTypeElementName = "MemberType";
|
||||
|
||||
/// <summary>
|
||||
/// Exports an IContent item as an XElement.
|
||||
@@ -80,5 +81,7 @@ public interface IEntityXmlSerializer
|
||||
|
||||
XElement Serialize(IMediaType mediaType);
|
||||
|
||||
XElement Serialize(IMemberType memberType) => throw new NotImplementedException();
|
||||
|
||||
XElement Serialize(IContentType contentType);
|
||||
}
|
||||
|
||||
@@ -10,13 +10,21 @@ public interface IPackageDataInstallation
|
||||
InstallationSummary InstallPackageData(CompiledPackage compiledPackage, int userId);
|
||||
|
||||
/// <summary>
|
||||
/// Imports and saves package xml as <see cref="IContentType"/>
|
||||
/// Imports and saves package xml as <see cref="IMediaType"/>.
|
||||
/// </summary>
|
||||
/// <param name="docTypeElements">Xml to import</param>
|
||||
/// <param name="userId">Optional id of the User performing the operation. Default is zero (admin).</param>
|
||||
/// <returns>An enumerable list of generated ContentTypes</returns>
|
||||
/// <returns>An enumerable list of generated <see cref="IMediaType"/>s.</returns>
|
||||
IReadOnlyList<IMediaType> ImportMediaTypes(IEnumerable<XElement> docTypeElements, int userId);
|
||||
|
||||
/// <summary>
|
||||
/// Imports and saves package xml as <see cref="IMemberType"/>.
|
||||
/// </summary>
|
||||
/// <param name="docTypeElements">Xml to import</param>
|
||||
/// <param name="userId">Optional id of the User performing the operation. Default is zero (admin).</param>
|
||||
/// <returns>An enumerable list of generated <see cref="IMemberType"/>s.</returns>
|
||||
IReadOnlyList<IMemberType> ImportMemberTypes(IEnumerable<XElement> docTypeElements, int userId) => throw new NotImplementedException();
|
||||
|
||||
IReadOnlyList<TContentBase> ImportContentBase<TContentBase, TContentTypeComposition>(
|
||||
IEnumerable<CompiledPackageContentBase> docs,
|
||||
IDictionary<string, TContentTypeComposition> importedDocumentTypes,
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Services.OperationStatus;
|
||||
|
||||
namespace Umbraco.Cms.Core.Services.ImportExport;
|
||||
|
||||
public interface IMemberTypeImportService
|
||||
{
|
||||
Task<Attempt<IMemberType?, MemberTypeImportOperationStatus>> Import(
|
||||
Guid temporaryFileId,
|
||||
Guid userKey,
|
||||
Guid? mediaTypeId = null);
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
using System.Xml.Linq;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Models.ContentEditing;
|
||||
using Umbraco.Cms.Core.Scoping;
|
||||
using Umbraco.Cms.Core.Services.OperationStatus;
|
||||
|
||||
namespace Umbraco.Cms.Core.Services.ImportExport;
|
||||
|
||||
public class MemberTypeImportService : IMemberTypeImportService
|
||||
{
|
||||
private readonly IPackageDataInstallation _packageDataInstallation;
|
||||
private readonly IEntityService _entityService;
|
||||
private readonly ITemporaryFileToXmlImportService _temporaryFileToXmlImportService;
|
||||
private readonly ICoreScopeProvider _coreScopeProvider;
|
||||
private readonly IUserIdKeyResolver _userIdKeyResolver;
|
||||
|
||||
public MemberTypeImportService(
|
||||
IPackageDataInstallation packageDataInstallation,
|
||||
IEntityService entityService,
|
||||
ITemporaryFileToXmlImportService temporaryFileToXmlImportService,
|
||||
ICoreScopeProvider coreScopeProvider,
|
||||
IUserIdKeyResolver userIdKeyResolver)
|
||||
{
|
||||
_packageDataInstallation = packageDataInstallation;
|
||||
_entityService = entityService;
|
||||
_temporaryFileToXmlImportService = temporaryFileToXmlImportService;
|
||||
_coreScopeProvider = coreScopeProvider;
|
||||
_userIdKeyResolver = userIdKeyResolver;
|
||||
}
|
||||
|
||||
public async Task<Attempt<IMemberType?, MemberTypeImportOperationStatus>> Import(
|
||||
Guid temporaryFileId,
|
||||
Guid userKey,
|
||||
Guid? memberTypeId = null)
|
||||
{
|
||||
using ICoreScope scope = _coreScopeProvider.CreateCoreScope();
|
||||
|
||||
_temporaryFileToXmlImportService.CleanupFileIfScopeCompletes(temporaryFileId);
|
||||
Attempt<XElement?, TemporaryFileXmlImportOperationStatus> loadXmlAttempt =
|
||||
await _temporaryFileToXmlImportService.LoadXElementFromTemporaryFileAsync(temporaryFileId);
|
||||
if (loadXmlAttempt.Success is false)
|
||||
{
|
||||
return Attempt.FailWithStatus<IMemberType?, MemberTypeImportOperationStatus>(
|
||||
loadXmlAttempt.Status is TemporaryFileXmlImportOperationStatus.TemporaryFileNotFound
|
||||
? MemberTypeImportOperationStatus.TemporaryFileNotFound
|
||||
: MemberTypeImportOperationStatus.TemporaryFileConversionFailure,
|
||||
null);
|
||||
}
|
||||
|
||||
Attempt<UmbracoEntityTypes> packageEntityTypeAttempt = _temporaryFileToXmlImportService.GetEntityType(loadXmlAttempt.Result!);
|
||||
if (packageEntityTypeAttempt.Success is false ||
|
||||
packageEntityTypeAttempt.Result is not UmbracoEntityTypes.MemberType)
|
||||
{
|
||||
return Attempt.FailWithStatus<IMemberType?, MemberTypeImportOperationStatus>(
|
||||
MemberTypeImportOperationStatus.TypeMismatch,
|
||||
null);
|
||||
}
|
||||
|
||||
Guid packageEntityKey = _packageDataInstallation.GetContentTypeKey(loadXmlAttempt.Result!);
|
||||
if (memberTypeId is not null && memberTypeId.Equals(packageEntityKey) is false)
|
||||
{
|
||||
return Attempt.FailWithStatus<IMemberType?, MemberTypeImportOperationStatus>(
|
||||
MemberTypeImportOperationStatus.IdMismatch,
|
||||
null);
|
||||
}
|
||||
|
||||
var entityExits = _entityService.Exists(
|
||||
_packageDataInstallation.GetContentTypeKey(loadXmlAttempt.Result!),
|
||||
UmbracoObjectTypes.MemberType);
|
||||
if (entityExits && memberTypeId is null)
|
||||
{
|
||||
return Attempt.FailWithStatus<IMemberType?, MemberTypeImportOperationStatus>(
|
||||
MemberTypeImportOperationStatus.MemberTypeExists,
|
||||
null);
|
||||
}
|
||||
|
||||
IReadOnlyList<IMemberType> importResult =
|
||||
_packageDataInstallation.ImportMemberTypes(new[] { loadXmlAttempt.Result! }, await _userIdKeyResolver.GetAsync(userKey));
|
||||
|
||||
scope.Complete();
|
||||
|
||||
return Attempt.SucceedWithStatus<IMemberType?, MemberTypeImportOperationStatus>(
|
||||
entityExits
|
||||
? MemberTypeImportOperationStatus.SuccessUpdated
|
||||
: MemberTypeImportOperationStatus.SuccessCreated,
|
||||
importResult[0]);
|
||||
}
|
||||
}
|
||||
@@ -61,6 +61,8 @@ public class TemporaryFileToXmlImportService : ITemporaryFileToXmlImportService
|
||||
=> Attempt<UmbracoEntityTypes>.Succeed(UmbracoEntityTypes.DocumentType),
|
||||
IEntityXmlSerializer.MediaTypeElementName
|
||||
=> Attempt<UmbracoEntityTypes>.Succeed(UmbracoEntityTypes.MediaType),
|
||||
IEntityXmlSerializer.MemberTypeElementName
|
||||
=> Attempt<UmbracoEntityTypes>.Succeed(UmbracoEntityTypes.MemberType),
|
||||
_ => Attempt<UmbracoEntityTypes>.Fail()
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
namespace Umbraco.Cms.Core.Services.OperationStatus;
|
||||
|
||||
public enum MemberTypeImportOperationStatus
|
||||
{
|
||||
SuccessCreated,
|
||||
SuccessUpdated,
|
||||
TemporaryFileNotFound,
|
||||
TemporaryFileConversionFailure,
|
||||
MemberTypeExists,
|
||||
TypeMismatch,
|
||||
IdMismatch
|
||||
}
|
||||
@@ -41,6 +41,7 @@ namespace Umbraco.Cms.Infrastructure.Packaging
|
||||
private readonly IEntityService _entityService;
|
||||
private readonly IContentTypeService _contentTypeService;
|
||||
private readonly IContentService _contentService;
|
||||
private readonly IMemberTypeService _memberTypeService;
|
||||
|
||||
public PackageDataInstallation(
|
||||
IDataValueEditorFactory dataValueEditorFactory,
|
||||
@@ -58,7 +59,8 @@ namespace Umbraco.Cms.Infrastructure.Packaging
|
||||
IMediaService mediaService,
|
||||
IMediaTypeService mediaTypeService,
|
||||
ITemplateContentParserService templateContentParserService,
|
||||
ITemplateService templateService)
|
||||
ITemplateService templateService,
|
||||
IMemberTypeService memberTypeService)
|
||||
{
|
||||
_dataValueEditorFactory = dataValueEditorFactory;
|
||||
_logger = logger;
|
||||
@@ -76,10 +78,48 @@ namespace Umbraco.Cms.Infrastructure.Packaging
|
||||
_mediaTypeService = mediaTypeService;
|
||||
_templateContentParserService = templateContentParserService;
|
||||
_templateService = templateService;
|
||||
_memberTypeService = memberTypeService;
|
||||
}
|
||||
|
||||
// Also remove factory service registration when this constructor is removed
|
||||
[Obsolete("Use the constructor with Infrastructure.IScopeProvider and without global settings and hosting environment instead.")]
|
||||
[Obsolete("Please use the constructor with all parameters. Scheduled for removal in Umbraco 19.")]
|
||||
public PackageDataInstallation(
|
||||
IDataValueEditorFactory dataValueEditorFactory,
|
||||
ILogger<PackageDataInstallation> logger,
|
||||
IFileService fileService,
|
||||
ILocalizationService localizationService,
|
||||
IDataTypeService dataTypeService,
|
||||
IEntityService entityService,
|
||||
IContentTypeService contentTypeService,
|
||||
IContentService contentService,
|
||||
PropertyEditorCollection propertyEditors,
|
||||
IScopeProvider scopeProvider,
|
||||
IShortStringHelper shortStringHelper,
|
||||
IConfigurationEditorJsonSerializer serializer,
|
||||
IMediaService mediaService,
|
||||
IMediaTypeService mediaTypeService,
|
||||
ITemplateContentParserService templateContentParserService,
|
||||
ITemplateService templateService)
|
||||
: this(
|
||||
dataValueEditorFactory,
|
||||
logger,
|
||||
fileService,
|
||||
localizationService,
|
||||
dataTypeService,
|
||||
entityService,
|
||||
contentTypeService,
|
||||
contentService,
|
||||
propertyEditors,
|
||||
scopeProvider,
|
||||
shortStringHelper,
|
||||
serializer,
|
||||
mediaService,
|
||||
mediaTypeService,
|
||||
templateContentParserService,
|
||||
templateService,
|
||||
StaticServiceProvider.Instance.GetRequiredService<IMemberTypeService>())
|
||||
{ }
|
||||
|
||||
[Obsolete("Please use the constructor with all parameters. Scheduled for removal in Umbraco 19.")]
|
||||
public PackageDataInstallation(
|
||||
IDataValueEditorFactory dataValueEditorFactory,
|
||||
ILogger<PackageDataInstallation> logger,
|
||||
@@ -107,7 +147,7 @@ namespace Umbraco.Cms.Infrastructure.Packaging
|
||||
contentTypeService,
|
||||
contentService,
|
||||
propertyEditors,
|
||||
(Umbraco.Cms.Infrastructure.Scoping.IScopeProvider)scopeProvider,
|
||||
(IScopeProvider)scopeProvider,
|
||||
shortStringHelper,
|
||||
serializer,
|
||||
mediaService,
|
||||
@@ -163,27 +203,27 @@ namespace Umbraco.Cms.Infrastructure.Packaging
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Imports and saves package xml as <see cref="IContentType"/>
|
||||
/// </summary>
|
||||
/// <param name="docTypeElements">Xml to import</param>
|
||||
/// <param name="userId">Optional id of the User performing the operation. Default is zero (admin).</param>
|
||||
/// <returns>An enumerable list of generated ContentTypes</returns>
|
||||
/// <inheritdoc/>
|
||||
public IReadOnlyList<IMediaType> ImportMediaTypes(IEnumerable<XElement> docTypeElements, int userId)
|
||||
#pragma warning disable CS0618 // Type or member is obsolete
|
||||
=> ImportMediaTypes(docTypeElements, userId, out _);
|
||||
#pragma warning restore CS0618 // Type or member is obsolete
|
||||
|
||||
/// <summary>
|
||||
/// Imports and saves package xml as <see cref="IContentType"/>
|
||||
/// </summary>
|
||||
/// <param name="docTypeElements">Xml to import</param>
|
||||
/// <param name="userId">Optional id of the User performing the operation. Default is zero (admin).</param>
|
||||
/// <param name="entityContainersInstalled">Collection of entity containers installed by the package to be populated with those created in installing data types.</param>
|
||||
/// <returns>An enumerable list of generated ContentTypes</returns>
|
||||
[Obsolete("This method is not used in Umbraco outside of this class so will be made private in Umbraco 19.")]
|
||||
public IReadOnlyList<IMediaType> ImportMediaTypes(IEnumerable<XElement> docTypeElements, int userId,
|
||||
out IEnumerable<EntityContainer> entityContainersInstalled)
|
||||
=> ImportDocumentTypes(docTypeElements.ToList(), true, userId, _mediaTypeService,
|
||||
out entityContainersInstalled);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IReadOnlyList<IMemberType> ImportMemberTypes(IEnumerable<XElement> docTypeElements, int userId)
|
||||
=> ImportMemberTypes(docTypeElements, userId, out _);
|
||||
|
||||
private IReadOnlyList<IMemberType> ImportMemberTypes(IEnumerable<XElement> docTypeElements, int userId,
|
||||
out IEnumerable<EntityContainer> entityContainersInstalled)
|
||||
=> ImportDocumentTypes(docTypeElements.ToList(), true, userId, _memberTypeService,
|
||||
out entityContainersInstalled);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Content
|
||||
@@ -805,26 +845,23 @@ namespace Umbraco.Cms.Infrastructure.Packaging
|
||||
{
|
||||
if (typeof(T) == typeof(IContentType))
|
||||
{
|
||||
if (parent is null)
|
||||
{
|
||||
return new ContentType(_shortStringHelper, parentId) { Alias = alias, Key = key } as T;
|
||||
}
|
||||
else
|
||||
{
|
||||
return new ContentType(_shortStringHelper, (IContentType)parent, alias) { Key = key } as T;
|
||||
}
|
||||
return parent is null
|
||||
? new ContentType(_shortStringHelper, parentId) { Alias = alias, Key = key } as T
|
||||
: new ContentType(_shortStringHelper, (IContentType)parent, alias) { Key = key } as T;
|
||||
}
|
||||
|
||||
if (typeof(T) == typeof(IMediaType))
|
||||
{
|
||||
if (parent is null)
|
||||
{
|
||||
return new MediaType(_shortStringHelper, parentId) { Alias = alias, Key = key } as T;
|
||||
}
|
||||
else
|
||||
{
|
||||
return new MediaType(_shortStringHelper, (IMediaType)parent, alias) { Key = key } as T;
|
||||
}
|
||||
return parent is null
|
||||
? new MediaType(_shortStringHelper, parentId) { Alias = alias, Key = key } as T
|
||||
: new MediaType(_shortStringHelper, (IMediaType)parent, alias) { Key = key } as T;
|
||||
}
|
||||
|
||||
if (typeof(T) == typeof(IMemberType))
|
||||
{
|
||||
return parent is null
|
||||
? new MemberType(_shortStringHelper, parentId) { Alias = alias, Key = key } as T
|
||||
: new MemberType(_shortStringHelper, (IMemberType)parent, alias) { Key = key } as T;
|
||||
}
|
||||
|
||||
throw new NotSupportedException($"Type {typeof(T)} is not supported");
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -122,6 +122,10 @@ export type CopyMediaTypeRequestModel = {
|
||||
target?: ReferenceByIdModel | null;
|
||||
};
|
||||
|
||||
export type CopyMemberTypeRequestModel = {
|
||||
target?: ReferenceByIdModel | null;
|
||||
};
|
||||
|
||||
export type CreateDataTypeRequestModel = {
|
||||
name: string;
|
||||
editorAlias: string;
|
||||
@@ -327,6 +331,7 @@ export type CreateMemberTypeRequestModel = {
|
||||
properties: Array<CreateMemberTypePropertyTypeRequestModel>;
|
||||
containers: Array<CreateMemberTypePropertyTypeContainerRequestModel>;
|
||||
id?: string | null;
|
||||
parent?: ReferenceByIdModel | null;
|
||||
compositions: Array<MemberTypeCompositionModel>;
|
||||
};
|
||||
|
||||
@@ -1110,6 +1115,10 @@ export type ImportMediaTypeRequestModel = {
|
||||
file: ReferenceByIdModel;
|
||||
};
|
||||
|
||||
export type ImportMemberTypeRequestModel = {
|
||||
file: ReferenceByIdModel;
|
||||
};
|
||||
|
||||
export type IndexResponseModel = {
|
||||
name: string;
|
||||
healthStatus: HealthStatusResponseModel;
|
||||
@@ -1566,6 +1575,7 @@ export type MemberTypeTreeItemResponseModel = {
|
||||
parent?: ReferenceByIdModel | null;
|
||||
flags: Array<FlagModel>;
|
||||
name: string;
|
||||
isFolder: boolean;
|
||||
icon: string;
|
||||
};
|
||||
|
||||
@@ -1636,6 +1646,10 @@ export type MoveMediaTypeRequestModel = {
|
||||
target?: ReferenceByIdModel | null;
|
||||
};
|
||||
|
||||
export type MoveMemberTypeRequestModel = {
|
||||
target?: ReferenceByIdModel | null;
|
||||
};
|
||||
|
||||
export type NamedEntityTreeItemResponseModel = {
|
||||
hasChildren: boolean;
|
||||
id: string;
|
||||
@@ -2923,7 +2937,7 @@ export type UserInstallRequestModel = {
|
||||
name: string;
|
||||
email: string;
|
||||
password: string;
|
||||
readonly subscribeToNewsletter: boolean;
|
||||
subscribeToNewsletter: boolean;
|
||||
};
|
||||
|
||||
export type UserItemResponseModel = {
|
||||
@@ -3158,12 +3172,6 @@ export type UpgradeSettingsResponseModelWritable = {
|
||||
oldVersion: string;
|
||||
};
|
||||
|
||||
export type UserInstallRequestModelWritable = {
|
||||
name: string;
|
||||
email: string;
|
||||
password: string;
|
||||
};
|
||||
|
||||
export type GetCultureData = {
|
||||
body?: never;
|
||||
path?: never;
|
||||
@@ -10718,7 +10726,7 @@ export type GetMemberTypeByIdCompositionReferencesResponses = {
|
||||
export type GetMemberTypeByIdCompositionReferencesResponse = GetMemberTypeByIdCompositionReferencesResponses[keyof GetMemberTypeByIdCompositionReferencesResponses];
|
||||
|
||||
export type PostMemberTypeByIdCopyData = {
|
||||
body?: never;
|
||||
body?: CopyMemberTypeRequestModel;
|
||||
path: {
|
||||
id: string;
|
||||
};
|
||||
@@ -10754,6 +10762,115 @@ export type PostMemberTypeByIdCopyResponses = {
|
||||
201: unknown;
|
||||
};
|
||||
|
||||
export type GetMemberTypeByIdExportData = {
|
||||
body?: never;
|
||||
path: {
|
||||
id: string;
|
||||
};
|
||||
query?: never;
|
||||
url: '/umbraco/management/api/v1/member-type/{id}/export';
|
||||
};
|
||||
|
||||
export type GetMemberTypeByIdExportErrors = {
|
||||
/**
|
||||
* The resource is protected and requires an authentication token
|
||||
*/
|
||||
401: unknown;
|
||||
/**
|
||||
* The authenticated user does not have access to this resource
|
||||
*/
|
||||
403: unknown;
|
||||
/**
|
||||
* Not Found
|
||||
*/
|
||||
404: ProblemDetails;
|
||||
};
|
||||
|
||||
export type GetMemberTypeByIdExportError = GetMemberTypeByIdExportErrors[keyof GetMemberTypeByIdExportErrors];
|
||||
|
||||
export type GetMemberTypeByIdExportResponses = {
|
||||
/**
|
||||
* OK
|
||||
*/
|
||||
200: Blob | File;
|
||||
};
|
||||
|
||||
export type GetMemberTypeByIdExportResponse = GetMemberTypeByIdExportResponses[keyof GetMemberTypeByIdExportResponses];
|
||||
|
||||
export type PutMemberTypeByIdImportData = {
|
||||
body?: ImportMemberTypeRequestModel;
|
||||
path: {
|
||||
id: string;
|
||||
};
|
||||
query?: never;
|
||||
url: '/umbraco/management/api/v1/member-type/{id}/import';
|
||||
};
|
||||
|
||||
export type PutMemberTypeByIdImportErrors = {
|
||||
/**
|
||||
* Bad Request
|
||||
*/
|
||||
400: ProblemDetails;
|
||||
/**
|
||||
* The resource is protected and requires an authentication token
|
||||
*/
|
||||
401: unknown;
|
||||
/**
|
||||
* The authenticated user does not have access to this resource
|
||||
*/
|
||||
403: unknown;
|
||||
/**
|
||||
* Not Found
|
||||
*/
|
||||
404: ProblemDetails;
|
||||
};
|
||||
|
||||
export type PutMemberTypeByIdImportError = PutMemberTypeByIdImportErrors[keyof PutMemberTypeByIdImportErrors];
|
||||
|
||||
export type PutMemberTypeByIdImportResponses = {
|
||||
/**
|
||||
* OK
|
||||
*/
|
||||
200: unknown;
|
||||
};
|
||||
|
||||
export type PutMemberTypeByIdMoveData = {
|
||||
body?: MoveMemberTypeRequestModel;
|
||||
path: {
|
||||
id: string;
|
||||
};
|
||||
query?: never;
|
||||
url: '/umbraco/management/api/v1/member-type/{id}/move';
|
||||
};
|
||||
|
||||
export type PutMemberTypeByIdMoveErrors = {
|
||||
/**
|
||||
* Bad Request
|
||||
*/
|
||||
400: ProblemDetails;
|
||||
/**
|
||||
* The resource is protected and requires an authentication token
|
||||
*/
|
||||
401: unknown;
|
||||
/**
|
||||
* The authenticated user does not have access to this resource
|
||||
*/
|
||||
403: unknown;
|
||||
/**
|
||||
* Not Found
|
||||
*/
|
||||
404: ProblemDetails;
|
||||
};
|
||||
|
||||
export type PutMemberTypeByIdMoveError = PutMemberTypeByIdMoveErrors[keyof PutMemberTypeByIdMoveErrors];
|
||||
|
||||
export type PutMemberTypeByIdMoveResponses = {
|
||||
/**
|
||||
* OK
|
||||
*/
|
||||
200: unknown;
|
||||
};
|
||||
|
||||
export type PostMemberTypeAvailableCompositionsData = {
|
||||
body?: MemberTypeCompositionRequestModel;
|
||||
path?: never;
|
||||
@@ -10952,12 +11069,109 @@ export type PutMemberTypeFolderByIdResponses = {
|
||||
200: unknown;
|
||||
};
|
||||
|
||||
export type PostMemberTypeImportData = {
|
||||
body?: ImportMemberTypeRequestModel;
|
||||
path?: never;
|
||||
query?: never;
|
||||
url: '/umbraco/management/api/v1/member-type/import';
|
||||
};
|
||||
|
||||
export type PostMemberTypeImportErrors = {
|
||||
/**
|
||||
* Bad Request
|
||||
*/
|
||||
400: ProblemDetails;
|
||||
/**
|
||||
* The resource is protected and requires an authentication token
|
||||
*/
|
||||
401: unknown;
|
||||
/**
|
||||
* The authenticated user does not have access to this resource
|
||||
*/
|
||||
403: unknown;
|
||||
/**
|
||||
* Not Found
|
||||
*/
|
||||
404: ProblemDetails;
|
||||
};
|
||||
|
||||
export type PostMemberTypeImportError = PostMemberTypeImportErrors[keyof PostMemberTypeImportErrors];
|
||||
|
||||
export type PostMemberTypeImportResponses = {
|
||||
/**
|
||||
* Created
|
||||
*/
|
||||
201: unknown;
|
||||
};
|
||||
|
||||
export type GetTreeMemberTypeAncestorsData = {
|
||||
body?: never;
|
||||
path?: never;
|
||||
query?: {
|
||||
descendantId?: string;
|
||||
};
|
||||
url: '/umbraco/management/api/v1/tree/member-type/ancestors';
|
||||
};
|
||||
|
||||
export type GetTreeMemberTypeAncestorsErrors = {
|
||||
/**
|
||||
* The resource is protected and requires an authentication token
|
||||
*/
|
||||
401: unknown;
|
||||
/**
|
||||
* The authenticated user does not have access to this resource
|
||||
*/
|
||||
403: unknown;
|
||||
};
|
||||
|
||||
export type GetTreeMemberTypeAncestorsResponses = {
|
||||
/**
|
||||
* OK
|
||||
*/
|
||||
200: Array<MemberTypeTreeItemResponseModel>;
|
||||
};
|
||||
|
||||
export type GetTreeMemberTypeAncestorsResponse = GetTreeMemberTypeAncestorsResponses[keyof GetTreeMemberTypeAncestorsResponses];
|
||||
|
||||
export type GetTreeMemberTypeChildrenData = {
|
||||
body?: never;
|
||||
path?: never;
|
||||
query?: {
|
||||
parentId?: string;
|
||||
skip?: number;
|
||||
take?: number;
|
||||
foldersOnly?: boolean;
|
||||
};
|
||||
url: '/umbraco/management/api/v1/tree/member-type/children';
|
||||
};
|
||||
|
||||
export type GetTreeMemberTypeChildrenErrors = {
|
||||
/**
|
||||
* The resource is protected and requires an authentication token
|
||||
*/
|
||||
401: unknown;
|
||||
/**
|
||||
* The authenticated user does not have access to this resource
|
||||
*/
|
||||
403: unknown;
|
||||
};
|
||||
|
||||
export type GetTreeMemberTypeChildrenResponses = {
|
||||
/**
|
||||
* OK
|
||||
*/
|
||||
200: PagedMemberTypeTreeItemResponseModel;
|
||||
};
|
||||
|
||||
export type GetTreeMemberTypeChildrenResponse = GetTreeMemberTypeChildrenResponses[keyof GetTreeMemberTypeChildrenResponses];
|
||||
|
||||
export type GetTreeMemberTypeRootData = {
|
||||
body?: never;
|
||||
path?: never;
|
||||
query?: {
|
||||
skip?: number;
|
||||
take?: number;
|
||||
foldersOnly?: boolean;
|
||||
};
|
||||
url: '/umbraco/management/api/v1/tree/member-type/root';
|
||||
};
|
||||
@@ -10989,6 +11203,7 @@ export type GetTreeMemberTypeSiblingsData = {
|
||||
target?: string;
|
||||
before?: number;
|
||||
after?: number;
|
||||
foldersOnly?: boolean;
|
||||
};
|
||||
url: '/umbraco/management/api/v1/tree/member-type/siblings';
|
||||
};
|
||||
|
||||
@@ -6,7 +6,7 @@ import type { MetaEntityCreateOptionAction } from '@umbraco-cms/backoffice/entit
|
||||
export class UmbDefaultMediaTypeCreateOptionAction extends UmbEntityCreateOptionActionBase<MetaEntityCreateOptionAction> {
|
||||
override async getHref() {
|
||||
const parentEntityType = this.args.entityType as UmbMediaTypeRootEntityType | UmbMediaTypeFolderEntityType;
|
||||
if (!parentEntityType) throw new Error('Entity type is required to create a document type');
|
||||
if (!parentEntityType) throw new Error('Entity type is required to create a media type');
|
||||
|
||||
const parentUnique = this.args.unique ?? null;
|
||||
|
||||
|
||||
@@ -8,4 +8,8 @@ export * from './search/constants.js';
|
||||
export * from './tree/constants.js';
|
||||
export * from './workspace/constants.js';
|
||||
|
||||
export { UMB_MEMBER_TYPE_ROOT_ENTITY_TYPE, UMB_MEMBER_TYPE_ENTITY_TYPE } from './entity.js';
|
||||
export {
|
||||
UMB_MEMBER_TYPE_ROOT_ENTITY_TYPE,
|
||||
UMB_MEMBER_TYPE_ENTITY_TYPE,
|
||||
UMB_MEMBER_TYPE_FOLDER_ENTITY_TYPE,
|
||||
} from './entity.js';
|
||||
@@ -1 +1,4 @@
|
||||
export * from './duplicate/constants.js';
|
||||
export * from './export/constants.js';
|
||||
export * from './import/constants.js';
|
||||
export * from './move-to/constants.js';
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import type { UmbMemberTypeRootEntityType } from '../../../entity.js';
|
||||
import type { UmbMemberTypeFolderEntityType, UmbMemberTypeRootEntityType } from '../../../entity.js';
|
||||
import { UMB_CREATE_MEMBER_TYPE_WORKSPACE_PATH_PATTERN } from '../../../paths.js';
|
||||
import { UmbEntityCreateOptionActionBase } from '@umbraco-cms/backoffice/entity-create-option-action';
|
||||
import type { MetaEntityCreateOptionAction } from '@umbraco-cms/backoffice/entity-create-option-action';
|
||||
|
||||
export class UmbDefaultMemberTypeCreateOptionAction extends UmbEntityCreateOptionActionBase<MetaEntityCreateOptionAction> {
|
||||
override async getHref() {
|
||||
const parentEntityType = this.args.entityType as UmbMemberTypeRootEntityType;
|
||||
const parentEntityType = this.args.entityType as UmbMemberTypeRootEntityType | UmbMemberTypeFolderEntityType;
|
||||
if (!parentEntityType) throw new Error('Entity type is required to create a member type');
|
||||
|
||||
const parentUnique = this.args.unique ?? null;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { UMB_MEMBER_TYPE_ROOT_ENTITY_TYPE } from '../../../entity.js';
|
||||
import { UMB_MEMBER_TYPE_FOLDER_ENTITY_TYPE, UMB_MEMBER_TYPE_ROOT_ENTITY_TYPE } from '../../../entity.js';
|
||||
import type { UmbExtensionManifestKind } from '@umbraco-cms/backoffice/extension-registry';
|
||||
|
||||
export const manifests: Array<UmbExtensionManifest | UmbExtensionManifestKind> = [
|
||||
@@ -8,10 +8,12 @@ export const manifests: Array<UmbExtensionManifest | UmbExtensionManifestKind> =
|
||||
name: 'Default Member Type Entity Create Option Action',
|
||||
weight: 1000,
|
||||
api: () => import('./default-member-type-create-option-action.js'),
|
||||
forEntityTypes: [UMB_MEMBER_TYPE_ROOT_ENTITY_TYPE],
|
||||
forEntityTypes: [UMB_MEMBER_TYPE_ROOT_ENTITY_TYPE, UMB_MEMBER_TYPE_FOLDER_ENTITY_TYPE],
|
||||
meta: {
|
||||
icon: 'icon-user',
|
||||
label: '#content_membertype',
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
import { UMB_MEMBER_TYPE_FOLDER_ENTITY_TYPE, UMB_MEMBER_TYPE_ROOT_ENTITY_TYPE } from '../../../entity.js';
|
||||
import type { UmbExtensionManifestKind } from '@umbraco-cms/backoffice/extension-registry';
|
||||
import { UMB_MEMBER_TYPE_FOLDER_REPOSITORY_ALIAS } from '../../../tree/folder/constants.js';
|
||||
|
||||
export const manifests: Array<UmbExtensionManifest | UmbExtensionManifestKind> = [
|
||||
{
|
||||
type: 'entityCreateOptionAction',
|
||||
kind: 'folder',
|
||||
alias: 'Umb.EntityCreateOptionAction.MemberType.Folder',
|
||||
name: 'Member Type Folder Entity Create Option Action',
|
||||
forEntityTypes: [UMB_MEMBER_TYPE_ROOT_ENTITY_TYPE, UMB_MEMBER_TYPE_FOLDER_ENTITY_TYPE],
|
||||
meta: {
|
||||
icon: 'icon-folder',
|
||||
label: '#create_folder',
|
||||
additionalOptions: true,
|
||||
folderRepositoryAlias: UMB_MEMBER_TYPE_FOLDER_REPOSITORY_ALIAS,
|
||||
},
|
||||
},
|
||||
];
|
||||
@@ -1,5 +1,10 @@
|
||||
import { UMB_MEMBER_TYPE_ROOT_ENTITY_TYPE } from '../../entity.js';
|
||||
import {
|
||||
UMB_MEMBER_TYPE_ENTITY_TYPE,
|
||||
UMB_MEMBER_TYPE_FOLDER_ENTITY_TYPE,
|
||||
UMB_MEMBER_TYPE_ROOT_ENTITY_TYPE,
|
||||
} from '../../entity.js';
|
||||
import { manifests as defaultManifests } from './default/manifests.js';
|
||||
import { manifests as folderManifests } from './folder/manifests.js';
|
||||
import type { UmbExtensionManifestKind } from '@umbraco-cms/backoffice/extension-registry';
|
||||
|
||||
export const manifests: Array<UmbExtensionManifest | UmbExtensionManifestKind> = [
|
||||
@@ -8,7 +13,9 @@ export const manifests: Array<UmbExtensionManifest | UmbExtensionManifestKind> =
|
||||
kind: 'create',
|
||||
alias: 'Umb.EntityAction.MemberType.Create',
|
||||
name: 'Create Member Type Entity Action',
|
||||
forEntityTypes: [UMB_MEMBER_TYPE_ROOT_ENTITY_TYPE],
|
||||
weight: 1200,
|
||||
forEntityTypes: [UMB_MEMBER_TYPE_ENTITY_TYPE, UMB_MEMBER_TYPE_ROOT_ENTITY_TYPE, UMB_MEMBER_TYPE_FOLDER_ENTITY_TYPE],
|
||||
},
|
||||
...defaultManifests,
|
||||
...folderManifests,
|
||||
];
|
||||
|
||||
@@ -1,18 +1,23 @@
|
||||
import { UMB_MEMBER_TYPE_ENTITY_TYPE } from '../../entity.js';
|
||||
import { UMB_MEMBER_TYPE_TREE_REPOSITORY_ALIAS } from '../../constants.js';
|
||||
import { UMB_DUPLICATE_MEMBER_TYPE_REPOSITORY_ALIAS } from './repository/index.js';
|
||||
import {
|
||||
UMB_MEMBER_TYPE_ENTITY_TYPE,
|
||||
UMB_MEMBER_TYPE_TREE_ALIAS,
|
||||
UMB_MEMBER_TYPE_TREE_REPOSITORY_ALIAS,
|
||||
} from '../../constants.js';
|
||||
import { UMB_DUPLICATE_MEMBER_TYPE_REPOSITORY_ALIAS } from './constants.js';
|
||||
import { manifests as repositoryManifests } from './repository/manifests.js';
|
||||
|
||||
export const manifests: Array<UmbExtensionManifest> = [
|
||||
{
|
||||
type: 'entityAction',
|
||||
kind: 'duplicate',
|
||||
alias: 'Umb.EntityAction.MemberType.Duplicate',
|
||||
name: 'Duplicate Member Type Entity Action',
|
||||
kind: 'duplicateTo',
|
||||
alias: 'Umb.EntityAction.MemberType.DuplicateTo',
|
||||
name: 'Duplicate Document To Entity Action',
|
||||
forEntityTypes: [UMB_MEMBER_TYPE_ENTITY_TYPE],
|
||||
meta: {
|
||||
duplicateRepositoryAlias: UMB_DUPLICATE_MEMBER_TYPE_REPOSITORY_ALIAS,
|
||||
treeAlias: UMB_MEMBER_TYPE_TREE_ALIAS,
|
||||
treeRepositoryAlias: UMB_MEMBER_TYPE_TREE_REPOSITORY_ALIAS,
|
||||
foldersOnly: true,
|
||||
},
|
||||
},
|
||||
...repositoryManifests,
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import { UmbDuplicateMemberTypeServerDataSource } from './member-type-duplicate.server.data-source.js';
|
||||
import { UMB_NOTIFICATION_CONTEXT } from '@umbraco-cms/backoffice/notification';
|
||||
import type { UmbDuplicateRepository, UmbDuplicateRequestArgs } from '@umbraco-cms/backoffice/entity-action';
|
||||
import type { UmbDuplicateToRepository, UmbDuplicateToRequestArgs } from '@umbraco-cms/backoffice/tree';
|
||||
import { UmbRepositoryBase } from '@umbraco-cms/backoffice/repository';
|
||||
|
||||
export class UmbDuplicateMemberTypeRepository extends UmbRepositoryBase implements UmbDuplicateRepository {
|
||||
export class UmbDuplicateMemberTypeRepository extends UmbRepositoryBase implements UmbDuplicateToRepository {
|
||||
#duplicateSource = new UmbDuplicateMemberTypeServerDataSource(this);
|
||||
|
||||
async requestDuplicate(args: UmbDuplicateRequestArgs) {
|
||||
const { error } = await this.#duplicateSource.duplicate(args);
|
||||
async requestDuplicateTo(args: UmbDuplicateToRequestArgs) {
|
||||
const { error } = await this.#duplicateSource.duplicateTo(args);
|
||||
|
||||
if (!error) {
|
||||
const notificationContext = await this.getContext(UMB_NOTIFICATION_CONTEXT);
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import { MemberTypeService } from '@umbraco-cms/backoffice/external/backend-api';
|
||||
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
|
||||
import { tryExecute } from '@umbraco-cms/backoffice/resources';
|
||||
import type { UmbDuplicateDataSource, UmbDuplicateRequestArgs } from '@umbraco-cms/backoffice/entity-action';
|
||||
import type { UmbDuplicateToDataSource, UmbDuplicateToRequestArgs } from '@umbraco-cms/backoffice/tree';
|
||||
|
||||
/**
|
||||
* Duplicate Document Server Data Source
|
||||
* Duplicate Member Type Server Data Source
|
||||
* @class UmbDuplicateMemberTypeServerDataSource
|
||||
*/
|
||||
export class UmbDuplicateMemberTypeServerDataSource implements UmbDuplicateDataSource {
|
||||
export class UmbDuplicateMemberTypeServerDataSource implements UmbDuplicateToDataSource {
|
||||
#host: UmbControllerHost;
|
||||
|
||||
/**
|
||||
@@ -20,18 +20,22 @@ export class UmbDuplicateMemberTypeServerDataSource implements UmbDuplicateDataS
|
||||
}
|
||||
|
||||
/**
|
||||
* Duplicate an item for the given unique
|
||||
* @param {UmbDuplicateRequestArgs} args
|
||||
* Duplicate an item for the given unique to the destination unique
|
||||
* @param {UmbDuplicateToRequestArgs} args
|
||||
* @returns {*}
|
||||
* @memberof UmbDuplicateDataTypeServerDataSource
|
||||
* @memberof UmbDuplicateMemberTypeServerDataSource
|
||||
*/
|
||||
async duplicate(args: UmbDuplicateRequestArgs) {
|
||||
async duplicateTo(args: UmbDuplicateToRequestArgs) {
|
||||
if (!args.unique) throw new Error('Unique is missing');
|
||||
if (args.destination.unique === undefined) throw new Error('Destination unique is missing');
|
||||
|
||||
return tryExecute(
|
||||
this.#host,
|
||||
MemberTypeService.postMemberTypeByIdCopy({
|
||||
path: { id: args.unique },
|
||||
body: {
|
||||
target: args.destination.unique ? { id: args.destination.unique } : null,
|
||||
},
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
export * from './repository/constants.js';
|
||||
@@ -0,0 +1,19 @@
|
||||
import { UMB_MEMBER_TYPE_ENTITY_TYPE } from '../../entity.js';
|
||||
import { manifests as repositoryManifests } from './repository/manifests.js';
|
||||
|
||||
export const manifests: Array<UmbExtensionManifest> = [
|
||||
{
|
||||
type: 'entityAction',
|
||||
kind: 'default',
|
||||
alias: 'Umb.EntityAction.MemberType.Export',
|
||||
name: 'Export Member Type Entity Action',
|
||||
forEntityTypes: [UMB_MEMBER_TYPE_ENTITY_TYPE],
|
||||
api: () => import('./member-type-export.action.js'),
|
||||
meta: {
|
||||
icon: 'icon-download-alt',
|
||||
label: '#actions_export',
|
||||
additionalOptions: true,
|
||||
},
|
||||
},
|
||||
...repositoryManifests,
|
||||
];
|
||||
@@ -0,0 +1,21 @@
|
||||
import { UmbExportMemberTypeRepository } from './repository/index.js';
|
||||
import { blobDownload } from '@umbraco-cms/backoffice/utils';
|
||||
import { UmbEntityActionBase } from '@umbraco-cms/backoffice/entity-action';
|
||||
|
||||
export class UmbExportMemberTypeEntityAction extends UmbEntityActionBase<object> {
|
||||
#repository = new UmbExportMemberTypeRepository(this);
|
||||
|
||||
override async execute() {
|
||||
if (!this.args.unique) throw new Error('Unique is not available');
|
||||
|
||||
const { data, error } = await this.#repository.requestExport(this.args.unique);
|
||||
|
||||
if (error) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
blobDownload(data, `${this.args.unique}.udt`, 'text/xml');
|
||||
}
|
||||
}
|
||||
|
||||
export default UmbExportMemberTypeEntityAction;
|
||||
@@ -0,0 +1 @@
|
||||
export const UMB_EXPORT_MEMBER_TYPE_REPOSITORY_ALIAS = 'Umb.Repository.MemberType.Export';
|
||||
@@ -0,0 +1,2 @@
|
||||
export { UmbExportMemberTypeRepository } from './member-type-export.repository.js';
|
||||
export { UMB_EXPORT_MEMBER_TYPE_REPOSITORY_ALIAS } from './constants.js';
|
||||
@@ -0,0 +1,10 @@
|
||||
import { UMB_EXPORT_MEMBER_TYPE_REPOSITORY_ALIAS } from './constants.js';
|
||||
|
||||
export const manifests: Array<UmbExtensionManifest> = [
|
||||
{
|
||||
type: 'repository',
|
||||
alias: UMB_EXPORT_MEMBER_TYPE_REPOSITORY_ALIAS,
|
||||
name: 'Export Member Type Repository',
|
||||
api: () => import('./member-type-export.repository.js'),
|
||||
},
|
||||
];
|
||||
@@ -0,0 +1,24 @@
|
||||
import { UmbExportMemberTypeServerDataSource } from './member-type-export.server.data-source.js';
|
||||
import { UMB_NOTIFICATION_CONTEXT } from '@umbraco-cms/backoffice/notification';
|
||||
import { UmbRepositoryBase } from '@umbraco-cms/backoffice/repository';
|
||||
|
||||
export class UmbExportMemberTypeRepository extends UmbRepositoryBase {
|
||||
#exportSource = new UmbExportMemberTypeServerDataSource(this);
|
||||
|
||||
async requestExport(unique: string) {
|
||||
const { data, error } = await this.#exportSource.export(unique);
|
||||
|
||||
if (!error) {
|
||||
const notificationContext = await this.getContext(UMB_NOTIFICATION_CONTEXT);
|
||||
if (!notificationContext) {
|
||||
throw new Error('Notification context not found');
|
||||
}
|
||||
const notification = { data: { message: `Exported` } };
|
||||
notificationContext.peek('positive', notification);
|
||||
}
|
||||
|
||||
return { data, error };
|
||||
}
|
||||
}
|
||||
|
||||
export { UmbExportMemberTypeRepository as api };
|
||||
@@ -0,0 +1,33 @@
|
||||
import { MemberTypeService } from '@umbraco-cms/backoffice/external/backend-api';
|
||||
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
|
||||
import { tryExecute } from '@umbraco-cms/backoffice/resources';
|
||||
|
||||
/**
|
||||
* Export Member Server Data Source
|
||||
* @export
|
||||
* @class UmbExportMemberTypeServerDataSource
|
||||
*/
|
||||
export class UmbExportMemberTypeServerDataSource {
|
||||
#host: UmbControllerHost;
|
||||
|
||||
/**
|
||||
* Creates an instance of UmbExportMemberTypeServerDataSource.
|
||||
* @param {UmbControllerHost} host
|
||||
* @memberof UmbExportMemberTypeServerDataSource
|
||||
*/
|
||||
constructor(host: UmbControllerHost) {
|
||||
this.#host = host;
|
||||
}
|
||||
|
||||
/**
|
||||
* Export an item for the given id to the destination unique
|
||||
* @param {unique} unique
|
||||
* @returns {*}
|
||||
* @memberof UmbExportMemberTypeServerDataSource
|
||||
*/
|
||||
async export(unique: string) {
|
||||
if (!unique) throw new Error('Unique is missing');
|
||||
|
||||
return tryExecute(this.#host, MemberTypeService.getMemberTypeByIdExport({ path: { id: unique } }));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from './modal/constants.js';
|
||||
export * from './repository/constants.js';
|
||||
@@ -0,0 +1,21 @@
|
||||
import { UMB_MEMBER_TYPE_ROOT_ENTITY_TYPE } from '../../entity.js';
|
||||
import { manifests as repositoryManifests } from './repository/manifests.js';
|
||||
import { manifests as modalManifests } from './modal/manifests.js';
|
||||
|
||||
export const manifests: Array<UmbExtensionManifest> = [
|
||||
{
|
||||
type: 'entityAction',
|
||||
kind: 'default',
|
||||
alias: 'Umb.EntityAction.MemberType.Import',
|
||||
name: 'Export Member Type Entity Action',
|
||||
forEntityTypes: [UMB_MEMBER_TYPE_ROOT_ENTITY_TYPE],
|
||||
api: () => import('./member-type-import.action.js'),
|
||||
meta: {
|
||||
icon: 'icon-page-up',
|
||||
label: '#actions_import',
|
||||
additionalOptions: true,
|
||||
},
|
||||
},
|
||||
...repositoryManifests,
|
||||
...modalManifests,
|
||||
];
|
||||
@@ -0,0 +1,25 @@
|
||||
import { UMB_MEMBER_TYPE_IMPORT_MODAL } from './modal/member-type-import-modal.token.js';
|
||||
import { UMB_ACTION_EVENT_CONTEXT } from '@umbraco-cms/backoffice/action';
|
||||
import { UmbEntityActionBase, UmbRequestReloadChildrenOfEntityEvent } from '@umbraco-cms/backoffice/entity-action';
|
||||
import { umbOpenModal } from '@umbraco-cms/backoffice/modal';
|
||||
|
||||
export class UmbImportMemberTypeEntityAction extends UmbEntityActionBase<object> {
|
||||
override async execute() {
|
||||
await umbOpenModal(this, UMB_MEMBER_TYPE_IMPORT_MODAL, {
|
||||
data: { unique: this.args.unique },
|
||||
}).catch(() => {});
|
||||
|
||||
const actionEventContext = await this.getContext(UMB_ACTION_EVENT_CONTEXT);
|
||||
if (!actionEventContext) {
|
||||
throw new Error('Action event context not found.');
|
||||
}
|
||||
const event = new UmbRequestReloadChildrenOfEntityEvent({
|
||||
unique: this.args.unique,
|
||||
entityType: this.args.entityType,
|
||||
});
|
||||
|
||||
actionEventContext.dispatchEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
export default UmbImportMemberTypeEntityAction;
|
||||
@@ -0,0 +1 @@
|
||||
export * from './member-type-import-modal.token.js';
|
||||
@@ -0,0 +1,10 @@
|
||||
import type { ManifestModal } from '@umbraco-cms/backoffice/modal';
|
||||
|
||||
export const manifests: Array<ManifestModal> = [
|
||||
{
|
||||
type: 'modal',
|
||||
alias: 'Umb.Modal.MemberType.Import',
|
||||
name: 'Member Type Import Modal',
|
||||
element: () => import('./member-type-import-modal.element.js'),
|
||||
},
|
||||
];
|
||||
@@ -0,0 +1,171 @@
|
||||
import { UmbMemberTypeImportRepository } from '../repository/member-type-import.repository.js';
|
||||
import type { UmbMemberTypeImportModalData, UmbMemberTypeImportModalValue } from './member-type-import-modal.token.js';
|
||||
import { css, html, customElement, state, when } from '@umbraco-cms/backoffice/external/lit';
|
||||
import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
|
||||
import { UmbModalBaseElement } from '@umbraco-cms/backoffice/modal';
|
||||
import type { UmbDropzoneMediaElement } from '@umbraco-cms/backoffice/media';
|
||||
import type { UmbDropzoneChangeEvent } from '@umbraco-cms/backoffice/dropzone';
|
||||
|
||||
interface UmbMemberTypePreview {
|
||||
unique: string;
|
||||
name: string;
|
||||
alias: string;
|
||||
icon: string;
|
||||
}
|
||||
|
||||
@customElement('umb-member-type-import-modal')
|
||||
export class UmbMemberTypeImportModalLayout extends UmbModalBaseElement<
|
||||
UmbMemberTypeImportModalData,
|
||||
UmbMemberTypeImportModalValue
|
||||
> {
|
||||
#memberTypeImportRepository = new UmbMemberTypeImportRepository(this);
|
||||
#temporaryUnique?: string;
|
||||
#fileReader;
|
||||
|
||||
@state()
|
||||
private _fileContent: Array<UmbMemberTypePreview> = [];
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.#fileReader = new FileReader();
|
||||
this.#fileReader.onload = (e) => {
|
||||
if (typeof e.target?.result === 'string') {
|
||||
const fileContent = e.target.result;
|
||||
this.#memberTypePreviewBuilder(fileContent);
|
||||
} else {
|
||||
this.#requestReset();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#onUploadComplete(evt: UmbDropzoneChangeEvent) {
|
||||
evt.preventDefault();
|
||||
const target = evt.target as UmbDropzoneMediaElement;
|
||||
const data = target.value;
|
||||
if (!data?.length) return;
|
||||
|
||||
const file = data[0];
|
||||
|
||||
if (file.temporaryFile) {
|
||||
this.#temporaryUnique = file.temporaryFile.temporaryUnique;
|
||||
this.#fileReader.readAsText(file.temporaryFile.file);
|
||||
}
|
||||
}
|
||||
|
||||
async #onFileImport() {
|
||||
if (!this.#temporaryUnique) return;
|
||||
const { error } = await this.#memberTypeImportRepository.requestImport(this.#temporaryUnique);
|
||||
if (error) return;
|
||||
this._submitModal();
|
||||
}
|
||||
|
||||
#memberTypePreviewBuilder(htmlString: string) {
|
||||
const parser = new DOMParser();
|
||||
const doc = parser.parseFromString(htmlString, 'text/xml');
|
||||
const childNodes = doc.childNodes;
|
||||
|
||||
const elements: Array<Element> = [];
|
||||
|
||||
childNodes.forEach((node) => {
|
||||
if (node.nodeType === Node.ELEMENT_NODE && node.nodeName === 'MemberType') {
|
||||
elements.push(node as Element);
|
||||
}
|
||||
});
|
||||
|
||||
this._fileContent = this.#memberTypePreviewItemBuilder(elements);
|
||||
}
|
||||
|
||||
#memberTypePreviewItemBuilder(elements: Array<Element>) {
|
||||
const memberTypes: Array<UmbMemberTypePreview> = [];
|
||||
elements.forEach((MemberType) => {
|
||||
const info = MemberType.getElementsByTagName('Info')[0];
|
||||
const unique = info.getElementsByTagName('Key')[0].textContent ?? '';
|
||||
const name = info.getElementsByTagName('Name')[0].textContent ?? '';
|
||||
const alias = info.getElementsByTagName('Alias')[0].textContent ?? '';
|
||||
const icon = info.getElementsByTagName('Icon')[0].textContent ?? '';
|
||||
|
||||
memberTypes.push({ unique, name, alias, icon });
|
||||
});
|
||||
return memberTypes;
|
||||
}
|
||||
|
||||
#requestReset() {
|
||||
this._fileContent = [];
|
||||
this.#temporaryUnique = undefined;
|
||||
}
|
||||
|
||||
override render() {
|
||||
return html` <umb-body-layout headline=${this.localize.term('general_import')}>
|
||||
<uui-box> ${this.#renderUploadZone()} </uui-box>
|
||||
<uui-button
|
||||
slot="actions"
|
||||
type="button"
|
||||
label=${this.localize.term('general_cancel')}
|
||||
@click=${this._rejectModal}></uui-button>
|
||||
<uui-button
|
||||
slot="actions"
|
||||
type="button"
|
||||
look="primary"
|
||||
?disabled=${!this.#temporaryUnique}
|
||||
label=${this.localize.term('actions_import')}
|
||||
@click=${this.#onFileImport}></uui-button>
|
||||
</umb-body-layout>`;
|
||||
}
|
||||
|
||||
#renderUploadZone() {
|
||||
return html`
|
||||
${when(
|
||||
this._fileContent.length,
|
||||
() =>
|
||||
html`<uui-ref-node name=${this._fileContent[0].name} alias=${this._fileContent[0].alias} readonly standalone>
|
||||
<umb-icon slot="icon" name=${this._fileContent[0].icon}></umb-icon>
|
||||
<uui-button
|
||||
slot="actions"
|
||||
@click=${this.#requestReset}
|
||||
label=${this.localize.term('general_remove')}></uui-button>
|
||||
</uui-ref-node>`,
|
||||
() =>
|
||||
html`<div id="wrapper">
|
||||
<umb-input-dropzone id="dropzone" accept=".udt" @change=${this.#onUploadComplete}
|
||||
><umb-localize slot="text" key="member_dragAndDropYourFilesIntoTheArea"
|
||||
>Drag and drop your file(s) into the area
|
||||
</umb-localize></umb-input-dropzone
|
||||
>
|
||||
</div>`,
|
||||
)}
|
||||
`;
|
||||
}
|
||||
|
||||
static override styles = [
|
||||
UmbTextStyles,
|
||||
css`
|
||||
#wrapper {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
position: relative;
|
||||
gap: var(--uui-size-space-3);
|
||||
border: 2px dashed var(--uui-color-divider-standalone);
|
||||
background-color: var(--uui-color-surface-alt);
|
||||
padding: var(--uui-size-space-6);
|
||||
}
|
||||
|
||||
#dropzone {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#import {
|
||||
margin-top: var(--uui-size-space-6);
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
|
||||
export default UmbMemberTypeImportModalLayout;
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'umb-member-type-import-modal': UmbMemberTypeImportModalLayout;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import { UmbModalToken } from '@umbraco-cms/backoffice/modal';
|
||||
|
||||
export interface UmbMemberTypeImportModalData {
|
||||
unique: string | null;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
|
||||
export interface UmbMemberTypeImportModalValue {}
|
||||
|
||||
export const UMB_MEMBER_TYPE_IMPORT_MODAL = new UmbModalToken<UmbMemberTypeImportModalData, UmbMemberTypeImportModalValue>(
|
||||
'Umb.Modal.MemberType.Import',
|
||||
{
|
||||
modal: {
|
||||
type: 'sidebar',
|
||||
size: 'small',
|
||||
},
|
||||
},
|
||||
);
|
||||
@@ -0,0 +1 @@
|
||||
export const UMB_MEMBER_TYPE_IMPORT_REPOSITORY_ALIAS = 'Umb.Repository.MemberType.Import';
|
||||
@@ -0,0 +1,2 @@
|
||||
export { UmbMemberTypeImportRepository } from './member-type-import.repository.js';
|
||||
export { UMB_MEMBER_TYPE_IMPORT_REPOSITORY_ALIAS } from './constants.js';
|
||||
@@ -0,0 +1,10 @@
|
||||
import { UMB_MEMBER_TYPE_IMPORT_REPOSITORY_ALIAS } from './constants.js';
|
||||
|
||||
export const manifests: Array<UmbExtensionManifest> = [
|
||||
{
|
||||
type: 'repository',
|
||||
alias: UMB_MEMBER_TYPE_IMPORT_REPOSITORY_ALIAS,
|
||||
name: 'Import Member Type Repository',
|
||||
api: () => import('./member-type-import.repository.js'),
|
||||
},
|
||||
];
|
||||
@@ -0,0 +1,24 @@
|
||||
import { UmbMemberTypeImportServerDataSource } from './member-type-import.server.data-source.js';
|
||||
import { UMB_NOTIFICATION_CONTEXT } from '@umbraco-cms/backoffice/notification';
|
||||
import { UmbRepositoryBase } from '@umbraco-cms/backoffice/repository';
|
||||
|
||||
export class UmbMemberTypeImportRepository extends UmbRepositoryBase {
|
||||
#importSource = new UmbMemberTypeImportServerDataSource(this);
|
||||
|
||||
async requestImport(temporaryUnique: string) {
|
||||
const { data, error } = await this.#importSource.import(temporaryUnique);
|
||||
|
||||
if (!error) {
|
||||
const notificationContext = await this.getContext(UMB_NOTIFICATION_CONTEXT);
|
||||
if (!notificationContext) {
|
||||
throw new Error('Notification context not found');
|
||||
}
|
||||
const notification = { data: { message: `Imported` } };
|
||||
notificationContext.peek('positive', notification);
|
||||
}
|
||||
|
||||
return { data, error };
|
||||
}
|
||||
}
|
||||
|
||||
export { UmbMemberTypeImportRepository as api };
|
||||
@@ -0,0 +1,37 @@
|
||||
import { MemberTypeService, type ImportMemberTypeRequestModel } from '@umbraco-cms/backoffice/external/backend-api';
|
||||
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
|
||||
import { tryExecute } from '@umbraco-cms/backoffice/resources';
|
||||
|
||||
/**
|
||||
* Member Type Import Server Data Source
|
||||
* @Import
|
||||
* @class UmbMemberTypeImportServerDataSource
|
||||
*/
|
||||
export class UmbMemberTypeImportServerDataSource {
|
||||
#host: UmbControllerHost;
|
||||
|
||||
/**
|
||||
* Creates an instance of UmbMemberTypeImportServerDataSource.
|
||||
* @param {UmbControllerHost} host
|
||||
* @memberof UmbMemberTypeImportServerDataSource
|
||||
*/
|
||||
constructor(host: UmbControllerHost) {
|
||||
this.#host = host;
|
||||
}
|
||||
|
||||
/**
|
||||
* Import an item for the given id to the destination unique
|
||||
* @param {temporaryUnique} temporaryUnique
|
||||
* @returns {*}
|
||||
* @memberof UmbMemberTypeImportServerDataSource
|
||||
*/
|
||||
async import(temporaryUnique: string) {
|
||||
if (!temporaryUnique) throw new Error('Unique is missing');
|
||||
|
||||
const body: ImportMemberTypeRequestModel = {
|
||||
file: { id: temporaryUnique },
|
||||
};
|
||||
|
||||
return tryExecute(this.#host, MemberTypeService.postMemberTypeImport({ body }));
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,13 @@
|
||||
import { UMB_MEMBER_TYPE_DETAIL_REPOSITORY_ALIAS, UMB_MEMBER_TYPE_ITEM_REPOSITORY_ALIAS } from '../constants.js';
|
||||
import { UMB_MEMBER_TYPE_ENTITY_TYPE } from '../entity.js';
|
||||
import {
|
||||
UMB_MEMBER_TYPE_ENTITY_TYPE,
|
||||
UMB_MEMBER_TYPE_DETAIL_REPOSITORY_ALIAS,
|
||||
UMB_MEMBER_TYPE_ITEM_REPOSITORY_ALIAS,
|
||||
} from '../constants.js';
|
||||
import { manifests as createManifests } from './create/manifests.js';
|
||||
import { manifests as moveManifests } from './move-to/manifests.js';
|
||||
import { manifests as duplicateManifests } from './duplicate/manifests.js';
|
||||
import { manifests as exportManifests } from './export/manifests.js';
|
||||
import { manifests as importManifests } from './import/manifests.js';
|
||||
import type { UmbExtensionManifestKind } from '@umbraco-cms/backoffice/extension-registry';
|
||||
|
||||
export const manifests: Array<UmbExtensionManifest | UmbExtensionManifestKind> = [
|
||||
@@ -17,5 +23,8 @@ export const manifests: Array<UmbExtensionManifest | UmbExtensionManifestKind> =
|
||||
},
|
||||
},
|
||||
...createManifests,
|
||||
...moveManifests,
|
||||
...duplicateManifests,
|
||||
...exportManifests,
|
||||
...importManifests,
|
||||
];
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
export * from './repository/constants.js';
|
||||
@@ -0,0 +1 @@
|
||||
export { UmbMoveMemberTypeRepository } from './repository/index.js';
|
||||
@@ -0,0 +1,21 @@
|
||||
import { UMB_MEMBER_TYPE_ENTITY_TYPE } from '../../entity.js';
|
||||
import { UMB_MEMBER_TYPE_TREE_REPOSITORY_ALIAS, UMB_MEMBER_TYPE_TREE_ALIAS } from '../../constants.js';
|
||||
import { UMB_MOVE_MEMBER_TYPE_REPOSITORY_ALIAS } from './constants.js';
|
||||
import { manifests as repositoryManifests } from './repository/manifests.js';
|
||||
|
||||
export const manifests: Array<UmbExtensionManifest> = [
|
||||
{
|
||||
type: 'entityAction',
|
||||
kind: 'moveTo',
|
||||
alias: 'Umb.EntityAction.MemberType.MoveTo',
|
||||
name: 'Move Member Type Entity Action',
|
||||
forEntityTypes: [UMB_MEMBER_TYPE_ENTITY_TYPE],
|
||||
meta: {
|
||||
treeRepositoryAlias: UMB_MEMBER_TYPE_TREE_REPOSITORY_ALIAS,
|
||||
moveRepositoryAlias: UMB_MOVE_MEMBER_TYPE_REPOSITORY_ALIAS,
|
||||
treeAlias: UMB_MEMBER_TYPE_TREE_ALIAS,
|
||||
foldersOnly: true,
|
||||
},
|
||||
},
|
||||
...repositoryManifests,
|
||||
];
|
||||
@@ -0,0 +1 @@
|
||||
export const UMB_MOVE_MEMBER_TYPE_REPOSITORY_ALIAS = 'Umb.Repository.MemberType.Move';
|
||||
@@ -0,0 +1 @@
|
||||
export { UmbMoveMemberTypeRepository } from './member-type-move.repository.js';
|
||||
@@ -0,0 +1,10 @@
|
||||
import { UMB_MOVE_MEMBER_TYPE_REPOSITORY_ALIAS } from './constants.js';
|
||||
|
||||
export const manifests: Array<UmbExtensionManifest> = [
|
||||
{
|
||||
type: 'repository',
|
||||
alias: UMB_MOVE_MEMBER_TYPE_REPOSITORY_ALIAS,
|
||||
name: 'Move Member Type Repository',
|
||||
api: () => import('./member-type-move.repository.js'),
|
||||
},
|
||||
];
|
||||
@@ -0,0 +1,25 @@
|
||||
import { UmbMoveMemberTypeServerDataSource } from './member-type-move.server.data-source.js';
|
||||
import { UMB_NOTIFICATION_CONTEXT } from '@umbraco-cms/backoffice/notification';
|
||||
import type { UmbMoveRepository, UmbMoveToRequestArgs } from '@umbraco-cms/backoffice/tree';
|
||||
import { UmbRepositoryBase } from '@umbraco-cms/backoffice/repository';
|
||||
|
||||
export class UmbMoveMemberTypeRepository extends UmbRepositoryBase implements UmbMoveRepository {
|
||||
#moveSource = new UmbMoveMemberTypeServerDataSource(this);
|
||||
|
||||
async requestMoveTo(args: UmbMoveToRequestArgs) {
|
||||
const { error } = await this.#moveSource.moveTo(args);
|
||||
|
||||
if (!error) {
|
||||
const notificationContext = await this.getContext(UMB_NOTIFICATION_CONTEXT);
|
||||
if (!notificationContext) {
|
||||
throw new Error(`Failed to load notification context`);
|
||||
}
|
||||
const notification = { data: { message: `Moved` } };
|
||||
notificationContext.peek('positive', notification);
|
||||
}
|
||||
|
||||
return { error };
|
||||
}
|
||||
}
|
||||
|
||||
export { UmbMoveMemberTypeRepository as api };
|
||||
@@ -0,0 +1,44 @@
|
||||
import { MemberTypeService } from '@umbraco-cms/backoffice/external/backend-api';
|
||||
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
|
||||
import { tryExecute } from '@umbraco-cms/backoffice/resources';
|
||||
import type { UmbMoveDataSource, UmbMoveToRequestArgs } from '@umbraco-cms/backoffice/tree';
|
||||
|
||||
/**
|
||||
* Move Member Type Server Data Source
|
||||
* @class UmbMoveMemberTypeServerDataSource
|
||||
*/
|
||||
export class UmbMoveMemberTypeServerDataSource implements UmbMoveDataSource {
|
||||
#host: UmbControllerHost;
|
||||
|
||||
/**
|
||||
* Creates an instance of UmbMoveMemberTypeServerDataSource.
|
||||
* @param {UmbControllerHost} host - The controller host for this controller to be appended to
|
||||
* @memberof UmbMoveMemberTypeServerDataSource
|
||||
*/
|
||||
constructor(host: UmbControllerHost) {
|
||||
this.#host = host;
|
||||
}
|
||||
|
||||
/**
|
||||
* Move an item for the given id to the target unique
|
||||
* @param {string} unique
|
||||
* @param {(string | null)} targetUnique
|
||||
* @param args
|
||||
* @returns {*}
|
||||
* @memberof UmbMoveMemberTypeServerDataSource
|
||||
*/
|
||||
async moveTo(args: UmbMoveToRequestArgs) {
|
||||
if (!args.unique) throw new Error('Unique is missing');
|
||||
if (args.destination.unique === undefined) throw new Error('Destination unique is missing');
|
||||
|
||||
return tryExecute(
|
||||
this.#host,
|
||||
MemberTypeService.putMemberTypeByIdMove({
|
||||
path: { id: args.unique },
|
||||
body: {
|
||||
target: args.destination.unique ? { id: args.destination.unique } : null,
|
||||
},
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
export const UMB_MEMBER_TYPE_ENTITY_TYPE = 'member-type';
|
||||
export const UMB_MEMBER_TYPE_ROOT_ENTITY_TYPE = 'member-type-root';
|
||||
export const UMB_MEMBER_TYPE_FOLDER_ENTITY_TYPE = 'member-type-folder';
|
||||
|
||||
export type UmbMemberTypeEntityType = typeof UMB_MEMBER_TYPE_ENTITY_TYPE;
|
||||
export type UmbMemberTypeRootEntityType = typeof UMB_MEMBER_TYPE_ROOT_ENTITY_TYPE;
|
||||
export type UmbMemberTypeFolderEntityType = typeof UMB_MEMBER_TYPE_FOLDER_ENTITY_TYPE;
|
||||
|
||||
@@ -130,7 +130,7 @@ export class UmbMemberTypeDetailServerDataSource implements UmbDetailDataSource<
|
||||
* @returns {*}
|
||||
* @memberof UmbMemberTypeDetailServerDataSource
|
||||
*/
|
||||
async create(model: UmbMemberTypeDetailModel) {
|
||||
async create(model: UmbMemberTypeDetailModel, parentUnique: string | null = null) {
|
||||
if (!model) throw new Error('Member Type is missing');
|
||||
|
||||
// TODO: make data mapper to prevent errors
|
||||
@@ -162,6 +162,7 @@ export class UmbMemberTypeDetailServerDataSource implements UmbDetailDataSource<
|
||||
}),
|
||||
containers: model.containers,
|
||||
id: model.unique,
|
||||
parent: parentUnique ? { id: parentUnique } : null,
|
||||
compositions: model.compositions.map((composition) => {
|
||||
return {
|
||||
memberType: { id: composition.contentType.unique },
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import type { UmbMemberTypeEntityType } from '../../entity.js';
|
||||
import type { UmbMemberTypeEntityType, UmbMemberTypeFolderEntityType } from '../../entity.js';
|
||||
|
||||
export interface UmbMemberTypeItemModel {
|
||||
entityType: UmbMemberTypeEntityType;
|
||||
entityType: UmbMemberTypeEntityType | UmbMemberTypeFolderEntityType;
|
||||
unique: string;
|
||||
name: string;
|
||||
icon: string;
|
||||
|
||||
@@ -7,4 +7,5 @@ export const UMB_MEMBER_TYPE_TREE_ALIAS = 'Umb.Tree.MemberType';
|
||||
|
||||
export { UMB_MEMBER_TYPE_TREE_STORE_CONTEXT } from './member-type-tree.store.context-token.js';
|
||||
|
||||
export * from './folder/constants.js';
|
||||
export * from './tree-item-children/constants.js';
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from './repository/constants.js';
|
||||
export * from './workspace/constants.js';
|
||||
@@ -0,0 +1,29 @@
|
||||
import { UMB_MEMBER_TYPE_FOLDER_ENTITY_TYPE } from '../../entity.js';
|
||||
import { UMB_MEMBER_TYPE_FOLDER_REPOSITORY_ALIAS } from './repository/constants.js';
|
||||
import { manifests as repositoryManifests } from './repository/manifests.js';
|
||||
import { manifests as workspaceManifests } from './workspace/manifests.js';
|
||||
|
||||
export const manifests: Array<UmbExtensionManifest> = [
|
||||
{
|
||||
type: 'entityAction',
|
||||
kind: 'folderUpdate',
|
||||
alias: 'Umb.EntityAction.MemberType.Folder.Update',
|
||||
name: 'Rename Member Type Folder Entity Action',
|
||||
forEntityTypes: [UMB_MEMBER_TYPE_FOLDER_ENTITY_TYPE],
|
||||
meta: {
|
||||
folderRepositoryAlias: UMB_MEMBER_TYPE_FOLDER_REPOSITORY_ALIAS,
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'entityAction',
|
||||
kind: 'folderDelete',
|
||||
alias: 'Umb.EntityAction.MemberType.Folder.Delete',
|
||||
name: 'Delete Member Type Folder Entity Action',
|
||||
forEntityTypes: [UMB_MEMBER_TYPE_FOLDER_ENTITY_TYPE],
|
||||
meta: {
|
||||
folderRepositoryAlias: UMB_MEMBER_TYPE_FOLDER_REPOSITORY_ALIAS,
|
||||
},
|
||||
},
|
||||
...repositoryManifests,
|
||||
...workspaceManifests,
|
||||
];
|
||||
@@ -0,0 +1,4 @@
|
||||
export const UMB_MEMBER_TYPE_FOLDER_REPOSITORY_ALIAS = 'Umb.Repository.MemberType.Folder';
|
||||
export const UMB_MEMBER_TYPE_FOLDER_STORE_ALIAS = 'Umb.Store.MemberType.Folder';
|
||||
export * from './member-type-folder.repository.js';
|
||||
export { UMB_MEMBER_TYPE_FOLDER_STORE_CONTEXT } from './member-type-folder.store.context-token.js';
|
||||
@@ -0,0 +1 @@
|
||||
export * from './member-type-folder.repository.js';
|
||||
@@ -0,0 +1,16 @@
|
||||
import { UMB_MEMBER_TYPE_FOLDER_REPOSITORY_ALIAS, UMB_MEMBER_TYPE_FOLDER_STORE_ALIAS } from './constants.js';
|
||||
|
||||
export const manifests: Array<UmbExtensionManifest> = [
|
||||
{
|
||||
type: 'repository',
|
||||
alias: UMB_MEMBER_TYPE_FOLDER_REPOSITORY_ALIAS,
|
||||
name: 'Member Type Folder Repository',
|
||||
api: () => import('./member-type-folder.repository.js'),
|
||||
},
|
||||
{
|
||||
type: 'store',
|
||||
alias: UMB_MEMBER_TYPE_FOLDER_STORE_ALIAS,
|
||||
name: 'Member Type Folder Store',
|
||||
api: () => import('./member-type-folder.store.js'),
|
||||
},
|
||||
];
|
||||
@@ -0,0 +1,13 @@
|
||||
import { UmbMemberTypeFolderServerDataSource } from './member-type-folder.server.data-source.js';
|
||||
import { UMB_MEMBER_TYPE_FOLDER_STORE_CONTEXT } from './member-type-folder.store.context-token.js';
|
||||
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
|
||||
import { UmbDetailRepositoryBase } from '@umbraco-cms/backoffice/repository';
|
||||
import type { UmbFolderModel } from '@umbraco-cms/backoffice/tree';
|
||||
|
||||
export class UmbMemberTypeFolderRepository extends UmbDetailRepositoryBase<UmbFolderModel> {
|
||||
constructor(host: UmbControllerHost) {
|
||||
super(host, UmbMemberTypeFolderServerDataSource, UMB_MEMBER_TYPE_FOLDER_STORE_CONTEXT);
|
||||
}
|
||||
}
|
||||
|
||||
export default UmbMemberTypeFolderRepository;
|
||||
@@ -0,0 +1,144 @@
|
||||
import { UMB_MEMBER_TYPE_FOLDER_ENTITY_TYPE } from '../../../entity.js';
|
||||
import type { UmbFolderModel } from '@umbraco-cms/backoffice/tree';
|
||||
import { MemberTypeService } from '@umbraco-cms/backoffice/external/backend-api';
|
||||
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
|
||||
import { tryExecute } from '@umbraco-cms/backoffice/resources';
|
||||
import { UmbId } from '@umbraco-cms/backoffice/id';
|
||||
import type { UmbDetailDataSource } from '@umbraco-cms/backoffice/repository';
|
||||
|
||||
/**
|
||||
* A data source for a Member Type folder that fetches data from the server
|
||||
* @class UmbMemberTypeFolderServerDataSource
|
||||
* @implements {RepositoryDetailDataSource}
|
||||
*/
|
||||
export class UmbMemberTypeFolderServerDataSource implements UmbDetailDataSource<UmbFolderModel> {
|
||||
#host: UmbControllerHost;
|
||||
|
||||
/**
|
||||
* Creates an instance of UmbMemberTypeFolderServerDataSource.
|
||||
* @param {UmbControllerHost} host - The controller host for this controller to be appended to
|
||||
* @memberof UmbMemberTypeFolderServerDataSource
|
||||
*/
|
||||
constructor(host: UmbControllerHost) {
|
||||
this.#host = host;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a scaffold for a Member Type folder
|
||||
* @param {Partial<UmbFolderModel>} [preset]
|
||||
* @returns {*}
|
||||
* @memberof UmbMemberTypeFolderServerDataSource
|
||||
*/
|
||||
async createScaffold(preset?: Partial<UmbFolderModel>) {
|
||||
const scaffold: UmbFolderModel = {
|
||||
entityType: UMB_MEMBER_TYPE_FOLDER_ENTITY_TYPE,
|
||||
unique: UmbId.new(),
|
||||
name: '',
|
||||
...preset,
|
||||
};
|
||||
|
||||
return { data: scaffold };
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches a Member Type folder from the server
|
||||
* @param {string} unique
|
||||
* @returns {*}
|
||||
* @memberof UmbMemberTypeFolderServerDataSource
|
||||
*/
|
||||
async read(unique: string) {
|
||||
if (!unique) throw new Error('Unique is missing');
|
||||
|
||||
const { data, error } = await tryExecute(
|
||||
this.#host,
|
||||
MemberTypeService.getMemberTypeFolderById({
|
||||
path: { id: unique },
|
||||
}),
|
||||
);
|
||||
|
||||
if (data) {
|
||||
const mappedData = {
|
||||
entityType: UMB_MEMBER_TYPE_FOLDER_ENTITY_TYPE,
|
||||
unique: data.id,
|
||||
name: data.name,
|
||||
};
|
||||
|
||||
return { data: mappedData };
|
||||
}
|
||||
|
||||
return { error };
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Member Type folder on the server
|
||||
* @param {UmbFolderModel} model
|
||||
* @returns {*}
|
||||
* @memberof UmbMemberTypeFolderServerDataSource
|
||||
*/
|
||||
async create(model: UmbFolderModel, parentUnique: string | null) {
|
||||
if (!model) throw new Error('Data is missing');
|
||||
if (!model.unique) throw new Error('Unique is missing');
|
||||
if (!model.name) throw new Error('Name is missing');
|
||||
|
||||
const body = {
|
||||
id: model.unique,
|
||||
parent: parentUnique ? { id: parentUnique } : null,
|
||||
name: model.name,
|
||||
};
|
||||
|
||||
const { error } = await tryExecute(
|
||||
this.#host,
|
||||
MemberTypeService.postMemberTypeFolder({
|
||||
body,
|
||||
}),
|
||||
);
|
||||
|
||||
if (!error) {
|
||||
return this.read(model.unique);
|
||||
}
|
||||
|
||||
return { error };
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates a Member Type folder on the server
|
||||
* @param {UmbUpdateFolderModel} model
|
||||
* @returns {*}
|
||||
* @memberof UmbMemberTypeFolderServerDataSource
|
||||
*/
|
||||
async update(model: UmbFolderModel) {
|
||||
if (!model) throw new Error('Data is missing');
|
||||
if (!model.unique) throw new Error('Unique is missing');
|
||||
if (!model.name) throw new Error('Folder name is missing');
|
||||
|
||||
const { error } = await tryExecute(
|
||||
this.#host,
|
||||
MemberTypeService.putMemberTypeFolderById({
|
||||
path: { id: model.unique },
|
||||
body: { name: model.name },
|
||||
}),
|
||||
);
|
||||
|
||||
if (!error) {
|
||||
return this.read(model.unique);
|
||||
}
|
||||
|
||||
return { error };
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a Member Type folder on the server
|
||||
* @param {string} unique
|
||||
* @returns {*}
|
||||
* @memberof UmbMemberTypeServerDataSource
|
||||
*/
|
||||
async delete(unique: string) {
|
||||
if (!unique) throw new Error('Unique is missing');
|
||||
return tryExecute(
|
||||
this.#host,
|
||||
MemberTypeService.deleteMemberTypeFolderById({
|
||||
path: { id: unique },
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
import type { UmbMemberTypeFolderStore } from './member-type-folder.store.js';
|
||||
import { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
|
||||
|
||||
export const UMB_MEMBER_TYPE_FOLDER_STORE_CONTEXT = new UmbContextToken<UmbMemberTypeFolderStore>(
|
||||
'UmbMemberTypeFolderStore',
|
||||
);
|
||||
@@ -0,0 +1,22 @@
|
||||
import { UMB_MEMBER_TYPE_FOLDER_STORE_CONTEXT } from './member-type-folder.store.context-token.js';
|
||||
import { UmbDetailStoreBase } from '@umbraco-cms/backoffice/store';
|
||||
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
|
||||
import type { UmbFolderModel } from '@umbraco-cms/backoffice/tree';
|
||||
|
||||
/**
|
||||
* @class UmbMemberTypeStore
|
||||
* @augments {UmbStoreBase}
|
||||
* @description - Data Store for Member Types
|
||||
*/
|
||||
export class UmbMemberTypeFolderStore extends UmbDetailStoreBase<UmbFolderModel> {
|
||||
/**
|
||||
* Creates an instance of UmbMemberTypeStore.
|
||||
* @param {UmbControllerHost} host - The controller host for this controller to be appended to
|
||||
* @memberof UmbMemberTypeStore
|
||||
*/
|
||||
constructor(host: UmbControllerHost) {
|
||||
super(host, UMB_MEMBER_TYPE_FOLDER_STORE_CONTEXT.toString());
|
||||
}
|
||||
}
|
||||
|
||||
export { UmbMemberTypeFolderStore as api };
|
||||
@@ -0,0 +1,6 @@
|
||||
import type { UMB_MEMBER_TYPE_FOLDER_ENTITY_TYPE } from '../../entity.js';
|
||||
import type { UmbMemberTypeTreeItemModel } from '../types.js';
|
||||
|
||||
export interface UmbMemberTypeFolderTreeItemModel extends UmbMemberTypeTreeItemModel {
|
||||
entityType: typeof UMB_MEMBER_TYPE_FOLDER_ENTITY_TYPE;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
export const UMB_MEMBER_TYPE_FOLDER_WORKSPACE_ALIAS = 'Umb.Workspace.MemberType.Folder';
|
||||
export * from './member-type-folder.workspace.context-token.js';
|
||||
export * from './paths.js';
|
||||
@@ -0,0 +1,34 @@
|
||||
import { UMB_MEMBER_TYPE_FOLDER_ENTITY_TYPE } from '../../../entity.js';
|
||||
import { UMB_MEMBER_TYPE_FOLDER_WORKSPACE_ALIAS } from './constants.js';
|
||||
import { UMB_WORKSPACE_CONDITION_ALIAS, UmbSubmitWorkspaceAction } from '@umbraco-cms/backoffice/workspace';
|
||||
|
||||
export const manifests: Array<UmbExtensionManifest> = [
|
||||
{
|
||||
type: 'workspace',
|
||||
kind: 'routable',
|
||||
alias: UMB_MEMBER_TYPE_FOLDER_WORKSPACE_ALIAS,
|
||||
name: 'Member Type Folder Workspace',
|
||||
api: () => import('./member-type-folder-workspace.context.js'),
|
||||
meta: {
|
||||
entityType: UMB_MEMBER_TYPE_FOLDER_ENTITY_TYPE,
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'workspaceAction',
|
||||
kind: 'default',
|
||||
alias: 'Umb.WorkspaceAction.MemberType.Folder.Submit',
|
||||
name: 'Submit Member Type Folder Workspace Action',
|
||||
api: UmbSubmitWorkspaceAction,
|
||||
meta: {
|
||||
label: '#buttons_save',
|
||||
look: 'primary',
|
||||
color: 'positive',
|
||||
},
|
||||
conditions: [
|
||||
{
|
||||
alias: UMB_WORKSPACE_CONDITION_ALIAS,
|
||||
match: UMB_MEMBER_TYPE_FOLDER_WORKSPACE_ALIAS,
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
@@ -0,0 +1,17 @@
|
||||
import { html, customElement } from '@umbraco-cms/backoffice/external/lit';
|
||||
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
|
||||
|
||||
@customElement('umb-member-type-folder-workspace-editor')
|
||||
export class UmbMemberTypeFolderWorkspaceEditorElement extends UmbLitElement {
|
||||
override render() {
|
||||
return html`<umb-folder-workspace-editor></umb-folder-workspace-editor>`;
|
||||
}
|
||||
}
|
||||
|
||||
export { UmbMemberTypeFolderWorkspaceEditorElement as element };
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
['umb-member-type-folder-workspace-editor']: UmbMemberTypeFolderWorkspaceEditorElement;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
import { UMB_MEMBER_TYPE_FOLDER_ENTITY_TYPE } from '../../../entity.js';
|
||||
import { UMB_MEMBER_TYPE_FOLDER_REPOSITORY_ALIAS } from '../constants.js';
|
||||
import type { UmbMemberTypeFolderRepository } from '../repository/index.js';
|
||||
import { UMB_MEMBER_TYPE_FOLDER_WORKSPACE_ALIAS } from './constants.js';
|
||||
import { UmbMemberTypeFolderWorkspaceEditorElement } from './member-type-folder-editor.element.js';
|
||||
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
|
||||
import {
|
||||
UmbEntityNamedDetailWorkspaceContextBase,
|
||||
type UmbRoutableWorkspaceContext,
|
||||
type UmbSubmittableWorkspaceContext,
|
||||
} from '@umbraco-cms/backoffice/workspace';
|
||||
import type { IRoutingInfo, PageComponent } from '@umbraco-cms/backoffice/router';
|
||||
import type { UmbFolderModel } from '@umbraco-cms/backoffice/tree';
|
||||
|
||||
export class UmbMemberTypeFolderWorkspaceContext
|
||||
extends UmbEntityNamedDetailWorkspaceContextBase<UmbFolderModel, UmbMemberTypeFolderRepository>
|
||||
implements UmbSubmittableWorkspaceContext, UmbRoutableWorkspaceContext
|
||||
{
|
||||
constructor(host: UmbControllerHost) {
|
||||
super(host, {
|
||||
workspaceAlias: UMB_MEMBER_TYPE_FOLDER_WORKSPACE_ALIAS,
|
||||
entityType: UMB_MEMBER_TYPE_FOLDER_ENTITY_TYPE,
|
||||
detailRepositoryAlias: UMB_MEMBER_TYPE_FOLDER_REPOSITORY_ALIAS,
|
||||
});
|
||||
|
||||
this.routes.setRoutes([
|
||||
{
|
||||
path: 'edit/:unique',
|
||||
component: UmbMemberTypeFolderWorkspaceEditorElement,
|
||||
setup: (component: PageComponent, info: IRoutingInfo) => {
|
||||
const unique = info.match.params.unique;
|
||||
this.load(unique);
|
||||
},
|
||||
},
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
export { UmbMemberTypeFolderWorkspaceContext as api };
|
||||
@@ -0,0 +1,14 @@
|
||||
import { UMB_MEMBER_TYPE_FOLDER_ENTITY_TYPE } from '../../../entity.js';
|
||||
import type { UmbMemberTypeFolderWorkspaceContext } from './member-type-folder-workspace.context.js';
|
||||
import { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
|
||||
import type { UmbWorkspaceContext } from '@umbraco-cms/backoffice/workspace';
|
||||
|
||||
export const UMB_MEMBER_TYPE_FOLDER_WORKSPACE_CONTEXT = new UmbContextToken<
|
||||
UmbWorkspaceContext,
|
||||
UmbMemberTypeFolderWorkspaceContext
|
||||
>(
|
||||
'UmbWorkspaceContext',
|
||||
undefined,
|
||||
(context): context is UmbMemberTypeFolderWorkspaceContext =>
|
||||
context.getEntityType?.() === UMB_MEMBER_TYPE_FOLDER_ENTITY_TYPE,
|
||||
);
|
||||
@@ -0,0 +1,14 @@
|
||||
import { UMB_MEMBER_TYPE_FOLDER_ENTITY_TYPE } from '../../../entity.js';
|
||||
import { UmbPathPattern } from '@umbraco-cms/backoffice/router';
|
||||
import { UMB_SETTINGS_SECTION_PATHNAME } from '@umbraco-cms/backoffice/settings';
|
||||
import { UMB_WORKSPACE_PATH_PATTERN } from '@umbraco-cms/backoffice/workspace';
|
||||
|
||||
export const UMB_MEMBER_TYPE_FOLDER_WORKSPACE_PATH = UMB_WORKSPACE_PATH_PATTERN.generateAbsolute({
|
||||
sectionName: UMB_SETTINGS_SECTION_PATHNAME,
|
||||
entityType: UMB_MEMBER_TYPE_FOLDER_ENTITY_TYPE,
|
||||
});
|
||||
|
||||
export const UMB_EDIT_MEMBER_TYPE_FOLDER_WORKSPACE_PATH_PATTERN = new UmbPathPattern<{ unique: string }>(
|
||||
'edit/:unique',
|
||||
UMB_MEMBER_TYPE_FOLDER_WORKSPACE_PATH,
|
||||
);
|
||||
@@ -1,13 +1,11 @@
|
||||
import { UMB_MEMBER_TYPE_ROOT_WORKSPACE_ALIAS } from '../constants.js';
|
||||
import { UMB_MEMBER_TYPE_ENTITY_TYPE, UMB_MEMBER_TYPE_ROOT_ENTITY_TYPE } from '../entity.js';
|
||||
import {
|
||||
UMB_MEMBER_TYPE_TREE_ALIAS,
|
||||
UMB_MEMBER_TYPE_TREE_ITEM_CHILDREN_COLLECTION_ALIAS,
|
||||
UMB_MEMBER_TYPE_TREE_REPOSITORY_ALIAS,
|
||||
UMB_MEMBER_TYPE_TREE_STORE_ALIAS,
|
||||
} from './constants.js';
|
||||
import { manifests as treeItemChildrenManifest } from './tree-item-children/manifests.js';
|
||||
import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace';
|
||||
import { manifests as folderManifests } from './folder/manifests.js';
|
||||
import { manifests as treeItemChildrenManifests } from './tree-item-children/manifests.js';
|
||||
|
||||
export const manifests: Array<UmbExtensionManifest> = [
|
||||
{
|
||||
@@ -38,23 +36,6 @@ export const manifests: Array<UmbExtensionManifest> = [
|
||||
name: 'Member Type Tree Item',
|
||||
forEntityTypes: [UMB_MEMBER_TYPE_ROOT_ENTITY_TYPE, UMB_MEMBER_TYPE_ENTITY_TYPE],
|
||||
},
|
||||
{
|
||||
type: 'workspaceView',
|
||||
kind: 'collection',
|
||||
alias: 'Umb.WorkspaceView.MemberType.TreeItemChildrenCollection',
|
||||
name: 'Member Type Tree Item Children Collection Workspace View',
|
||||
meta: {
|
||||
label: '#general_design',
|
||||
pathname: 'design',
|
||||
icon: 'icon-member-dashed-line',
|
||||
collectionAlias: UMB_MEMBER_TYPE_TREE_ITEM_CHILDREN_COLLECTION_ALIAS,
|
||||
},
|
||||
conditions: [
|
||||
{
|
||||
alias: UMB_WORKSPACE_CONDITION_ALIAS,
|
||||
oneOf: [UMB_MEMBER_TYPE_ROOT_WORKSPACE_ALIAS],
|
||||
},
|
||||
],
|
||||
},
|
||||
...treeItemChildrenManifest,
|
||||
...folderManifests,
|
||||
...treeItemChildrenManifests,
|
||||
];
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { UMB_MEMBER_TYPE_ROOT_ENTITY_TYPE } from '../entity.js';
|
||||
import { UmbMemberTypeTreeServerDataSource } from './member-type-tree.server.data-source.js';
|
||||
import { UmbMemberTypeTreeServerDataSource } from './server-data-source/member-type-tree.server.data-source.js';
|
||||
import type { UmbMemberTypeTreeItemModel, UmbMemberTypeTreeRootModel } from './types.js';
|
||||
import { UMB_MEMBER_TYPE_TREE_STORE_CONTEXT } from './member-type-tree.store.context-token.js';
|
||||
import { UmbTreeRepositoryBase } from '@umbraco-cms/backoffice/tree';
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
import { UMB_MEMBER_TYPE_ENTITY_TYPE, UMB_MEMBER_TYPE_ROOT_ENTITY_TYPE } from '../entity.js';
|
||||
import type { UmbMemberTypeTreeItemModel } from './types.js';
|
||||
import type { UmbTreeChildrenOfRequestArgs, UmbTreeRootItemsRequestArgs } from '@umbraco-cms/backoffice/tree';
|
||||
import { UmbTreeServerDataSourceBase } from '@umbraco-cms/backoffice/tree';
|
||||
import type { MemberTypeTreeItemResponseModel } from '@umbraco-cms/backoffice/external/backend-api';
|
||||
import { MemberTypeService } from '@umbraco-cms/backoffice/external/backend-api';
|
||||
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
|
||||
|
||||
/**
|
||||
* A data source for the MemberType tree that fetches data from the server
|
||||
* @class UmbMemberTypeTreeServerDataSource
|
||||
* @implements {UmbTreeDataSource}
|
||||
*/
|
||||
export class UmbMemberTypeTreeServerDataSource extends UmbTreeServerDataSourceBase<
|
||||
MemberTypeTreeItemResponseModel,
|
||||
UmbMemberTypeTreeItemModel
|
||||
> {
|
||||
/**
|
||||
* Creates an instance of UmbMemberTypeTreeServerDataSource.
|
||||
* @param {UmbControllerHost} host - The controller host for this controller to be appended to
|
||||
* @memberof UmbMemberTypeTreeServerDataSource
|
||||
*/
|
||||
constructor(host: UmbControllerHost) {
|
||||
super(host, {
|
||||
getRootItems,
|
||||
getChildrenOf,
|
||||
getAncestorsOf,
|
||||
mapper,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const getRootItems = (args: UmbTreeRootItemsRequestArgs) =>
|
||||
// eslint-disable-next-line local-rules/no-direct-api-import
|
||||
MemberTypeService.getTreeMemberTypeRoot({ query: { skip: args.skip, take: args.take } });
|
||||
|
||||
const getChildrenOf = (args: UmbTreeChildrenOfRequestArgs) => {
|
||||
if (args.parent.unique === null) {
|
||||
return getRootItems(args);
|
||||
} else {
|
||||
throw new Error('Not supported for the member type tree');
|
||||
}
|
||||
};
|
||||
|
||||
const getAncestorsOf = () => {
|
||||
throw new Error('Not supported for the member type tree');
|
||||
};
|
||||
|
||||
const mapper = (item: MemberTypeTreeItemResponseModel): UmbMemberTypeTreeItemModel => {
|
||||
return {
|
||||
unique: item.id,
|
||||
parent: {
|
||||
unique: item.parent ? item.parent.id : null,
|
||||
entityType: item.parent ? UMB_MEMBER_TYPE_ENTITY_TYPE : UMB_MEMBER_TYPE_ROOT_ENTITY_TYPE,
|
||||
},
|
||||
name: item.name,
|
||||
entityType: UMB_MEMBER_TYPE_ENTITY_TYPE,
|
||||
hasChildren: item.hasChildren,
|
||||
isFolder: false,
|
||||
icon: item.icon,
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,75 @@
|
||||
import {
|
||||
UMB_MEMBER_TYPE_ENTITY_TYPE,
|
||||
UMB_MEMBER_TYPE_FOLDER_ENTITY_TYPE,
|
||||
UMB_MEMBER_TYPE_ROOT_ENTITY_TYPE,
|
||||
} from '../../entity.js';
|
||||
import { UmbManagementApiMemberTypeTreeDataRequestManager } from './member-type-tree.server.request-manager.js';
|
||||
import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api';
|
||||
import type { MemberTypeTreeItemResponseModel } from '@umbraco-cms/backoffice/external/backend-api';
|
||||
import type {
|
||||
UmbTreeAncestorsOfRequestArgs,
|
||||
UmbTreeChildrenOfRequestArgs,
|
||||
UmbTreeDataSource,
|
||||
UmbTreeRootItemsRequestArgs,
|
||||
} from '@umbraco-cms/backoffice/tree';
|
||||
import type { UmbMemberTypeTreeItemModel } from '../types.js';
|
||||
|
||||
/**
|
||||
* A data source for the Member Type tree that fetches data from the server
|
||||
* @class UmbMemberTypeTreeServerDataSource
|
||||
*/
|
||||
export class UmbMemberTypeTreeServerDataSource
|
||||
extends UmbControllerBase
|
||||
implements UmbTreeDataSource<UmbMemberTypeTreeItemModel>
|
||||
{
|
||||
#treeRequestManager = new UmbManagementApiMemberTypeTreeDataRequestManager(this);
|
||||
|
||||
async getRootItems(args: UmbTreeRootItemsRequestArgs) {
|
||||
const { data, error } = await this.#treeRequestManager.getRootItems(args);
|
||||
|
||||
const mappedData = data
|
||||
? {
|
||||
...data,
|
||||
items: data?.items.map((item) => this.#mapItem(item)),
|
||||
}
|
||||
: undefined;
|
||||
|
||||
return { data: mappedData, error };
|
||||
}
|
||||
|
||||
async getChildrenOf(args: UmbTreeChildrenOfRequestArgs) {
|
||||
const { data, error } = await this.#treeRequestManager.getChildrenOf(args);
|
||||
|
||||
const mappedData = data
|
||||
? {
|
||||
...data,
|
||||
items: data?.items.map((item) => this.#mapItem(item)),
|
||||
}
|
||||
: undefined;
|
||||
|
||||
return { data: mappedData, error };
|
||||
}
|
||||
|
||||
async getAncestorsOf(args: UmbTreeAncestorsOfRequestArgs) {
|
||||
const { data, error } = await this.#treeRequestManager.getAncestorsOf(args);
|
||||
|
||||
const mappedData = data?.map((item) => this.#mapItem(item));
|
||||
|
||||
return { data: mappedData, error };
|
||||
}
|
||||
|
||||
#mapItem(item: MemberTypeTreeItemResponseModel): UmbMemberTypeTreeItemModel {
|
||||
return {
|
||||
unique: item.id,
|
||||
parent: {
|
||||
unique: item.parent ? item.parent.id : null,
|
||||
entityType: item.parent ? UMB_MEMBER_TYPE_FOLDER_ENTITY_TYPE : UMB_MEMBER_TYPE_ROOT_ENTITY_TYPE,
|
||||
},
|
||||
name: item.name,
|
||||
entityType: item.isFolder ? UMB_MEMBER_TYPE_FOLDER_ENTITY_TYPE : UMB_MEMBER_TYPE_ENTITY_TYPE,
|
||||
hasChildren: item.hasChildren,
|
||||
isFolder: item.isFolder,
|
||||
icon: item.icon,
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/* eslint-disable local-rules/no-direct-api-import */
|
||||
|
||||
import { MemberTypeService } from '@umbraco-cms/backoffice/external/backend-api';
|
||||
import { UmbManagementApiTreeDataRequestManager } from '@umbraco-cms/backoffice/management-api';
|
||||
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
|
||||
import type {
|
||||
MemberTypeTreeItemResponseModel,
|
||||
PagedMemberTypeTreeItemResponseModel,
|
||||
SubsetMemberTypeTreeItemResponseModel,
|
||||
} from '@umbraco-cms/backoffice/external/backend-api';
|
||||
import type {
|
||||
UmbManagementApiTreeAncestorsOfRequestArgs,
|
||||
UmbManagementApiTreeChildrenOfRequestArgs,
|
||||
UmbManagementApiTreeRootItemsRequestArgs,
|
||||
UmbManagementApiTreeSiblingsFromRequestArgs,
|
||||
} from '@umbraco-cms/backoffice/management-api';
|
||||
|
||||
export class UmbManagementApiMemberTypeTreeDataRequestManager extends UmbManagementApiTreeDataRequestManager<
|
||||
MemberTypeTreeItemResponseModel,
|
||||
UmbManagementApiTreeRootItemsRequestArgs,
|
||||
PagedMemberTypeTreeItemResponseModel,
|
||||
UmbManagementApiTreeChildrenOfRequestArgs,
|
||||
PagedMemberTypeTreeItemResponseModel,
|
||||
UmbManagementApiTreeAncestorsOfRequestArgs,
|
||||
Array<MemberTypeTreeItemResponseModel>,
|
||||
UmbManagementApiTreeSiblingsFromRequestArgs,
|
||||
SubsetMemberTypeTreeItemResponseModel
|
||||
> {
|
||||
constructor(host: UmbControllerHost) {
|
||||
super(host, {
|
||||
getRootItems: (args) =>
|
||||
MemberTypeService.getTreeMemberTypeRoot({
|
||||
query: {
|
||||
foldersOnly: args.foldersOnly,
|
||||
skip: args.paging.skip,
|
||||
take: args.paging.take,
|
||||
},
|
||||
}),
|
||||
|
||||
getChildrenOf: (args) =>
|
||||
MemberTypeService.getTreeMemberTypeChildren({
|
||||
query: {
|
||||
parentId: args.parent.unique,
|
||||
foldersOnly: args.foldersOnly,
|
||||
skip: args.paging.skip,
|
||||
take: args.paging.take,
|
||||
},
|
||||
}),
|
||||
|
||||
getAncestorsOf: (args) =>
|
||||
MemberTypeService.getTreeMemberTypeAncestors({
|
||||
query: {
|
||||
descendantId: args.treeItem.unique,
|
||||
},
|
||||
}),
|
||||
|
||||
getSiblingsFrom: (args) =>
|
||||
MemberTypeService.getTreeMemberTypeSiblings({
|
||||
query: {
|
||||
foldersOnly: args.foldersOnly,
|
||||
target: args.paging.target.unique,
|
||||
before: args.paging.takeBefore,
|
||||
after: args.paging.takeAfter,
|
||||
},
|
||||
}),
|
||||
});
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user