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.")
|
.WithDetail("The import failed due to not being able to convert the file into proper xml.")
|
||||||
.Build()),
|
.Build()),
|
||||||
MediaTypeImportOperationStatus.MediaTypeExists => BadRequest(problemDetailsBuilder
|
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.")
|
.WithDetail("The import failed because the media type that was being imported already exits.")
|
||||||
.Build()),
|
.Build()),
|
||||||
MediaTypeImportOperationStatus.TypeMismatch => BadRequest(problemDetailsBuilder
|
MediaTypeImportOperationStatus.TypeMismatch => BadRequest(problemDetailsBuilder
|
||||||
@@ -42,6 +42,6 @@ public abstract class MediaTypeControllerBase : ManagementApiControllerBase
|
|||||||
.WithTitle("Invalid Id")
|
.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.")
|
.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()),
|
.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.Authorization;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Umbraco.Cms.Api.Management.ViewModels.MemberType;
|
||||||
using Umbraco.Cms.Core;
|
using Umbraco.Cms.Core;
|
||||||
using Umbraco.Cms.Core.Models;
|
using Umbraco.Cms.Core.Models;
|
||||||
using Umbraco.Cms.Core.Services;
|
using Umbraco.Cms.Core.Services;
|
||||||
@@ -24,9 +25,12 @@ public class CopyMemberTypeController : MemberTypeControllerBase
|
|||||||
[ProducesResponseType(StatusCodes.Status201Created)]
|
[ProducesResponseType(StatusCodes.Status201Created)]
|
||||||
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
|
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
|
||||||
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
|
[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
|
return result.Success
|
||||||
? CreatedAtId<ByKeyMemberTypeController>(controller => nameof(controller.ByKey), result.Result!.Key)
|
? 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 Microsoft.AspNetCore.Mvc;
|
||||||
using Umbraco.Cms.Api.Management.Controllers.DocumentType;
|
using Umbraco.Cms.Api.Management.Controllers.DocumentType;
|
||||||
using Umbraco.Cms.Api.Management.Routing;
|
using Umbraco.Cms.Api.Management.Routing;
|
||||||
@@ -18,4 +19,29 @@ public abstract class MemberTypeControllerBase : ManagementApiControllerBase
|
|||||||
|
|
||||||
protected IActionResult StructureOperationStatusResult(ContentTypeStructureOperationStatus status)
|
protected IActionResult StructureOperationStatusResult(ContentTypeStructureOperationStatus status)
|
||||||
=> DocumentTypeControllerBase.ContentTypeStructureOperationStatusResult(status, "member");
|
=> 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}")]
|
[VersionedApiBackOfficeRoute($"{Constants.Web.RoutePath.Tree}/{Constants.UdiEntityType.MemberType}")]
|
||||||
[ApiExplorerSettings(GroupName = "Member Type")]
|
[ApiExplorerSettings(GroupName = "Member Type")]
|
||||||
[Authorize(Policy = AuthorizationPolicies.TreeAccessMembersOrMemberTypes)]
|
[Authorize(Policy = AuthorizationPolicies.TreeAccessMembersOrMemberTypes)]
|
||||||
public class MemberTypeTreeControllerBase : NamedEntityTreeControllerBase<MemberTypeTreeItemResponseModel>
|
public class MemberTypeTreeControllerBase : FolderTreeControllerBase<MemberTypeTreeItemResponseModel>
|
||||||
{
|
{
|
||||||
private readonly IMemberTypeService _memberTypeService;
|
private readonly IMemberTypeService _memberTypeService;
|
||||||
|
|
||||||
@@ -37,6 +37,8 @@ public class MemberTypeTreeControllerBase : NamedEntityTreeControllerBase<Member
|
|||||||
|
|
||||||
protected override UmbracoObjectTypes ItemObjectType => UmbracoObjectTypes.MemberType;
|
protected override UmbracoObjectTypes ItemObjectType => UmbracoObjectTypes.MemberType;
|
||||||
|
|
||||||
|
protected override UmbracoObjectTypes FolderObjectType => UmbracoObjectTypes.MemberTypeContainer;
|
||||||
|
|
||||||
protected override MemberTypeTreeItemResponseModel[] MapTreeItemViewModels(Guid? parentKey, IEntitySlim[] entities)
|
protected override MemberTypeTreeItemResponseModel[] MapTreeItemViewModels(Guid? parentKey, IEntitySlim[] entities)
|
||||||
{
|
{
|
||||||
var memberTypes = _memberTypeService
|
var memberTypes = _memberTypeService
|
||||||
|
|||||||
@@ -32,5 +32,8 @@ public class RootMemberTypeTreeController : MemberTypeTreeControllerBase
|
|||||||
int skip = 0,
|
int skip = 0,
|
||||||
int take = 100,
|
int take = 100,
|
||||||
bool foldersOnly = false)
|
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.Http;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Umbraco.Cms.Api.Common.ViewModels.Pagination;
|
using Umbraco.Cms.Api.Common.ViewModels.Pagination;
|
||||||
using Umbraco.Cms.Api.Management.Services.Flags;
|
using Umbraco.Cms.Api.Management.Services.Flags;
|
||||||
using Umbraco.Cms.Api.Management.ViewModels.Tree;
|
using Umbraco.Cms.Api.Management.ViewModels.Tree;
|
||||||
@@ -9,10 +10,14 @@ namespace Umbraco.Cms.Api.Management.Controllers.MemberType.Tree;
|
|||||||
|
|
||||||
public class SiblingMemberTypeTreeController : MemberTypeTreeControllerBase
|
public class SiblingMemberTypeTreeController : MemberTypeTreeControllerBase
|
||||||
{
|
{
|
||||||
public SiblingMemberTypeTreeController(
|
[Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 18.")]
|
||||||
IEntityService entityService,
|
public SiblingMemberTypeTreeController(IEntityService entityService, IMemberTypeService memberTypeService)
|
||||||
FlagProviderCollection flagProviders,
|
: base(entityService, memberTypeService)
|
||||||
IMemberTypeService memberTypeService)
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
[ActivatorUtilitiesConstructor]
|
||||||
|
public SiblingMemberTypeTreeController(IEntityService entityService, FlagProviderCollection flagProviders, IMemberTypeService memberTypeService)
|
||||||
: base(entityService, flagProviders, memberTypeService)
|
: base(entityService, flagProviders, memberTypeService)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -25,5 +30,8 @@ public class SiblingMemberTypeTreeController : MemberTypeTreeControllerBase
|
|||||||
int before,
|
int before,
|
||||||
int after,
|
int after,
|
||||||
bool foldersOnly = false)
|
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(IContentType contentType);
|
||||||
|
|
||||||
FileContentResult Create(IMediaType mediaType);
|
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;
|
||||||
using Umbraco.Cms.Core.Models.ContentTypeEditing;
|
using Umbraco.Cms.Core.Models.ContentTypeEditing;
|
||||||
using Umbraco.Cms.Core.Services;
|
using Umbraco.Cms.Core.Services;
|
||||||
@@ -24,6 +24,7 @@ internal sealed class MemberTypeEditingPresentationFactory : ContentTypeEditingP
|
|||||||
|
|
||||||
createModel.Key = requestModel.Id;
|
createModel.Key = requestModel.Id;
|
||||||
createModel.Compositions = MapCompositions(requestModel.Compositions);
|
createModel.Compositions = MapCompositions(requestModel.Compositions);
|
||||||
|
createModel.ContainerKey = requestModel.Parent?.Id;
|
||||||
|
|
||||||
MapPropertyTypeSensitivityAndVisibility(createModel.Properties, requestModel.Properties);
|
MapPropertyTypeSensitivityAndVisibility(createModel.Properties, requestModel.Properties);
|
||||||
|
|
||||||
|
|||||||
@@ -27,6 +27,12 @@ public class UdtFileContentFactory : IUdtFileContentFactory
|
|||||||
return XmlTofile(mediaType, xml);
|
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) =>
|
private static FileContentResult XmlTofile(IContentTypeBase contentTypeBase, XElement xml) =>
|
||||||
new(Encoding.UTF8.GetBytes(xml.ToDataString()), MediaTypeNames.Application.Octet)
|
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": {
|
"/umbraco/management/api/v1/imaging/resize/urls": {
|
||||||
"get": {
|
"get": {
|
||||||
"tags": [
|
"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": {
|
"responses": {
|
||||||
"201": {
|
"201": {
|
||||||
"description": "Created",
|
"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": {
|
"/umbraco/management/api/v1/member-type/available-compositions": {
|
||||||
"post": {
|
"post": {
|
||||||
"tags": [
|
"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": {
|
"/umbraco/management/api/v1/tree/member-type/root": {
|
||||||
"get": {
|
"get": {
|
||||||
"tags": [
|
"tags": [
|
||||||
@@ -20712,6 +21442,14 @@
|
|||||||
"format": "int32",
|
"format": "int32",
|
||||||
"default": 100
|
"default": 100
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "foldersOnly",
|
||||||
|
"in": "query",
|
||||||
|
"schema": {
|
||||||
|
"type": "boolean",
|
||||||
|
"default": false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"responses": {
|
"responses": {
|
||||||
@@ -20773,6 +21511,14 @@
|
|||||||
"type": "integer",
|
"type": "integer",
|
||||||
"format": "int32"
|
"format": "int32"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "foldersOnly",
|
||||||
|
"in": "query",
|
||||||
|
"schema": {
|
||||||
|
"type": "boolean",
|
||||||
|
"default": false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"responses": {
|
"responses": {
|
||||||
@@ -36266,6 +37012,20 @@
|
|||||||
},
|
},
|
||||||
"additionalProperties": false
|
"additionalProperties": false
|
||||||
},
|
},
|
||||||
|
"CopyMemberTypeRequestModel": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"target": {
|
||||||
|
"oneOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/components/schemas/ReferenceByIdModel"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"nullable": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"additionalProperties": false
|
||||||
|
},
|
||||||
"CreateDataTypeRequestModel": {
|
"CreateDataTypeRequestModel": {
|
||||||
"required": [
|
"required": [
|
||||||
"editorAlias",
|
"editorAlias",
|
||||||
@@ -37361,6 +38121,14 @@
|
|||||||
"format": "uuid",
|
"format": "uuid",
|
||||||
"nullable": true
|
"nullable": true
|
||||||
},
|
},
|
||||||
|
"parent": {
|
||||||
|
"oneOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/components/schemas/ReferenceByIdModel"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"nullable": true
|
||||||
|
},
|
||||||
"compositions": {
|
"compositions": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
@@ -40574,7 +41342,7 @@
|
|||||||
},
|
},
|
||||||
"actionParameters": {
|
"actionParameters": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"additionalProperties": {},
|
"additionalProperties": { },
|
||||||
"nullable": true
|
"nullable": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -40824,6 +41592,22 @@
|
|||||||
},
|
},
|
||||||
"additionalProperties": false
|
"additionalProperties": false
|
||||||
},
|
},
|
||||||
|
"ImportMemberTypeRequestModel": {
|
||||||
|
"required": [
|
||||||
|
"file"
|
||||||
|
],
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"file": {
|
||||||
|
"oneOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/components/schemas/ReferenceByIdModel"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"additionalProperties": false
|
||||||
|
},
|
||||||
"IndexResponseModel": {
|
"IndexResponseModel": {
|
||||||
"required": [
|
"required": [
|
||||||
"canRebuild",
|
"canRebuild",
|
||||||
@@ -41199,7 +41983,7 @@
|
|||||||
},
|
},
|
||||||
"extensions": {
|
"extensions": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {}
|
"items": { }
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"additionalProperties": false
|
"additionalProperties": false
|
||||||
@@ -42852,6 +43636,7 @@
|
|||||||
"hasChildren",
|
"hasChildren",
|
||||||
"icon",
|
"icon",
|
||||||
"id",
|
"id",
|
||||||
|
"isFolder",
|
||||||
"name"
|
"name"
|
||||||
],
|
],
|
||||||
"type": "object",
|
"type": "object",
|
||||||
@@ -42884,6 +43669,9 @@
|
|||||||
"name": {
|
"name": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
"isFolder": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
"icon": {
|
"icon": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
}
|
||||||
@@ -43129,6 +43917,20 @@
|
|||||||
},
|
},
|
||||||
"additionalProperties": false
|
"additionalProperties": false
|
||||||
},
|
},
|
||||||
|
"MoveMemberTypeRequestModel": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"target": {
|
||||||
|
"oneOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/components/schemas/ReferenceByIdModel"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"nullable": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"additionalProperties": false
|
||||||
|
},
|
||||||
"NamedEntityTreeItemResponseModel": {
|
"NamedEntityTreeItemResponseModel": {
|
||||||
"required": [
|
"required": [
|
||||||
"flags",
|
"flags",
|
||||||
@@ -45071,7 +45873,7 @@
|
|||||||
"nullable": true
|
"nullable": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"additionalProperties": {}
|
"additionalProperties": { }
|
||||||
},
|
},
|
||||||
"ProblemDetailsBuilderModel": {
|
"ProblemDetailsBuilderModel": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
@@ -48718,8 +49520,7 @@
|
|||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"subscribeToNewsletter": {
|
"subscribeToNewsletter": {
|
||||||
"type": "boolean",
|
"type": "boolean"
|
||||||
"readOnly": true
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"additionalProperties": false
|
"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;
|
namespace Umbraco.Cms.Api.Management.ViewModels.MemberType;
|
||||||
|
|
||||||
public class CreateMemberTypeRequestModel
|
public class CreateMemberTypeRequestModel
|
||||||
: CreateContentTypeRequestModelBase<CreateMemberTypePropertyTypeRequestModel, CreateMemberTypePropertyTypeContainerRequestModel>
|
: CreateContentTypeWithParentRequestModelBase<CreateMemberTypePropertyTypeRequestModel, CreateMemberTypePropertyTypeContainerRequestModel>
|
||||||
{
|
{
|
||||||
public IEnumerable<MemberTypeComposition> Compositions { get; set; } = Enumerable.Empty<MemberTypeComposition>();
|
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;
|
public string Icon { get; set; } = string.Empty;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -430,6 +430,7 @@ namespace Umbraco.Cms.Core.DependencyInjection
|
|||||||
Services.AddUnique<ITemporaryFileToXmlImportService, TemporaryFileToXmlImportService>();
|
Services.AddUnique<ITemporaryFileToXmlImportService, TemporaryFileToXmlImportService>();
|
||||||
Services.AddUnique<IContentTypeImportService, ContentTypeImportService>();
|
Services.AddUnique<IContentTypeImportService, ContentTypeImportService>();
|
||||||
Services.AddUnique<IMediaTypeImportService, MediaTypeImportService>();
|
Services.AddUnique<IMediaTypeImportService, MediaTypeImportService>();
|
||||||
|
Services.AddUnique<IMemberTypeImportService, MemberTypeImportService>();
|
||||||
|
|
||||||
// add validation services
|
// add validation services
|
||||||
Services.AddUnique<IElementSwitchValidator, ElementSwitchValidator>();
|
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 class MemberTypeCreateModel : MemberTypeModelBase
|
||||||
{
|
{
|
||||||
public Guid? Key { get; set; }
|
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.Models.ContentTypeEditing;
|
||||||
using Umbraco.Cms.Core.Services.OperationStatus;
|
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)
|
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)
|
if (result.Success is false)
|
||||||
{
|
{
|
||||||
return result;
|
return result;
|
||||||
@@ -80,7 +80,7 @@ internal sealed class MemberTypeEditingService : ContentTypeEditingServiceBase<I
|
|||||||
|
|
||||||
protected override UmbracoObjectTypes ContentTypeObjectType => UmbracoObjectTypes.MemberType;
|
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();
|
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)
|
public Attempt<OperationResult<MoveOperationStatusType>?> Move(TItem moving, int containerId)
|
||||||
{
|
{
|
||||||
EventMessages eventMessages = EventMessagesFactory.Get();
|
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>>();
|
var moveInfo = new List<MoveEventInfo<TItem>>();
|
||||||
|
|||||||
@@ -374,7 +374,11 @@ internal sealed class EntityXmlSerializer : IEntityXmlSerializer
|
|||||||
return xml;
|
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(
|
var info = new XElement(
|
||||||
"Info",
|
"Info",
|
||||||
@@ -410,7 +414,7 @@ internal sealed class EntityXmlSerializer : IEntityXmlSerializer
|
|||||||
SerializePropertyGroups(mediaType.PropertyGroups)); // TODO Rename to PropertyGroups
|
SerializePropertyGroups(mediaType.PropertyGroups)); // TODO Rename to PropertyGroups
|
||||||
|
|
||||||
var xml = new XElement(
|
var xml = new XElement(
|
||||||
IEntityXmlSerializer.MediaTypeElementName,
|
elementName,
|
||||||
info,
|
info,
|
||||||
structure,
|
structure,
|
||||||
genericProperties,
|
genericProperties,
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ public interface IEntityXmlSerializer
|
|||||||
{
|
{
|
||||||
internal const string DocumentTypeElementName = "DocumentType";
|
internal const string DocumentTypeElementName = "DocumentType";
|
||||||
internal const string MediaTypeElementName = "MediaType";
|
internal const string MediaTypeElementName = "MediaType";
|
||||||
|
internal const string MemberTypeElementName = "MemberType";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Exports an IContent item as an XElement.
|
/// Exports an IContent item as an XElement.
|
||||||
@@ -80,5 +81,7 @@ public interface IEntityXmlSerializer
|
|||||||
|
|
||||||
XElement Serialize(IMediaType mediaType);
|
XElement Serialize(IMediaType mediaType);
|
||||||
|
|
||||||
|
XElement Serialize(IMemberType memberType) => throw new NotImplementedException();
|
||||||
|
|
||||||
XElement Serialize(IContentType contentType);
|
XElement Serialize(IContentType contentType);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,13 +10,21 @@ public interface IPackageDataInstallation
|
|||||||
InstallationSummary InstallPackageData(CompiledPackage compiledPackage, int userId);
|
InstallationSummary InstallPackageData(CompiledPackage compiledPackage, int userId);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Imports and saves package xml as <see cref="IContentType"/>
|
/// Imports and saves package xml as <see cref="IMediaType"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="docTypeElements">Xml to import</param>
|
/// <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="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);
|
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>(
|
IReadOnlyList<TContentBase> ImportContentBase<TContentBase, TContentTypeComposition>(
|
||||||
IEnumerable<CompiledPackageContentBase> docs,
|
IEnumerable<CompiledPackageContentBase> docs,
|
||||||
IDictionary<string, TContentTypeComposition> importedDocumentTypes,
|
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),
|
=> Attempt<UmbracoEntityTypes>.Succeed(UmbracoEntityTypes.DocumentType),
|
||||||
IEntityXmlSerializer.MediaTypeElementName
|
IEntityXmlSerializer.MediaTypeElementName
|
||||||
=> Attempt<UmbracoEntityTypes>.Succeed(UmbracoEntityTypes.MediaType),
|
=> Attempt<UmbracoEntityTypes>.Succeed(UmbracoEntityTypes.MediaType),
|
||||||
|
IEntityXmlSerializer.MemberTypeElementName
|
||||||
|
=> Attempt<UmbracoEntityTypes>.Succeed(UmbracoEntityTypes.MemberType),
|
||||||
_ => Attempt<UmbracoEntityTypes>.Fail()
|
_ => 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 IEntityService _entityService;
|
||||||
private readonly IContentTypeService _contentTypeService;
|
private readonly IContentTypeService _contentTypeService;
|
||||||
private readonly IContentService _contentService;
|
private readonly IContentService _contentService;
|
||||||
|
private readonly IMemberTypeService _memberTypeService;
|
||||||
|
|
||||||
public PackageDataInstallation(
|
public PackageDataInstallation(
|
||||||
IDataValueEditorFactory dataValueEditorFactory,
|
IDataValueEditorFactory dataValueEditorFactory,
|
||||||
@@ -58,7 +59,8 @@ namespace Umbraco.Cms.Infrastructure.Packaging
|
|||||||
IMediaService mediaService,
|
IMediaService mediaService,
|
||||||
IMediaTypeService mediaTypeService,
|
IMediaTypeService mediaTypeService,
|
||||||
ITemplateContentParserService templateContentParserService,
|
ITemplateContentParserService templateContentParserService,
|
||||||
ITemplateService templateService)
|
ITemplateService templateService,
|
||||||
|
IMemberTypeService memberTypeService)
|
||||||
{
|
{
|
||||||
_dataValueEditorFactory = dataValueEditorFactory;
|
_dataValueEditorFactory = dataValueEditorFactory;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
@@ -76,10 +78,48 @@ namespace Umbraco.Cms.Infrastructure.Packaging
|
|||||||
_mediaTypeService = mediaTypeService;
|
_mediaTypeService = mediaTypeService;
|
||||||
_templateContentParserService = templateContentParserService;
|
_templateContentParserService = templateContentParserService;
|
||||||
_templateService = templateService;
|
_templateService = templateService;
|
||||||
|
_memberTypeService = memberTypeService;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Also remove factory service registration when this constructor is removed
|
[Obsolete("Please use the constructor with all parameters. Scheduled for removal in Umbraco 19.")]
|
||||||
[Obsolete("Use the constructor with Infrastructure.IScopeProvider and without global settings and hosting environment instead.")]
|
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(
|
public PackageDataInstallation(
|
||||||
IDataValueEditorFactory dataValueEditorFactory,
|
IDataValueEditorFactory dataValueEditorFactory,
|
||||||
ILogger<PackageDataInstallation> logger,
|
ILogger<PackageDataInstallation> logger,
|
||||||
@@ -107,7 +147,7 @@ namespace Umbraco.Cms.Infrastructure.Packaging
|
|||||||
contentTypeService,
|
contentTypeService,
|
||||||
contentService,
|
contentService,
|
||||||
propertyEditors,
|
propertyEditors,
|
||||||
(Umbraco.Cms.Infrastructure.Scoping.IScopeProvider)scopeProvider,
|
(IScopeProvider)scopeProvider,
|
||||||
shortStringHelper,
|
shortStringHelper,
|
||||||
serializer,
|
serializer,
|
||||||
mediaService,
|
mediaService,
|
||||||
@@ -163,27 +203,27 @@ namespace Umbraco.Cms.Infrastructure.Packaging
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// 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>
|
|
||||||
public IReadOnlyList<IMediaType> ImportMediaTypes(IEnumerable<XElement> docTypeElements, int userId)
|
public IReadOnlyList<IMediaType> ImportMediaTypes(IEnumerable<XElement> docTypeElements, int userId)
|
||||||
|
#pragma warning disable CS0618 // Type or member is obsolete
|
||||||
=> ImportMediaTypes(docTypeElements, userId, out _);
|
=> ImportMediaTypes(docTypeElements, userId, out _);
|
||||||
|
#pragma warning restore CS0618 // Type or member is obsolete
|
||||||
|
|
||||||
/// <summary>
|
[Obsolete("This method is not used in Umbraco outside of this class so will be made private in Umbraco 19.")]
|
||||||
/// 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>
|
|
||||||
public IReadOnlyList<IMediaType> ImportMediaTypes(IEnumerable<XElement> docTypeElements, int userId,
|
public IReadOnlyList<IMediaType> ImportMediaTypes(IEnumerable<XElement> docTypeElements, int userId,
|
||||||
out IEnumerable<EntityContainer> entityContainersInstalled)
|
out IEnumerable<EntityContainer> entityContainersInstalled)
|
||||||
=> ImportDocumentTypes(docTypeElements.ToList(), true, userId, _mediaTypeService,
|
=> ImportDocumentTypes(docTypeElements.ToList(), true, userId, _mediaTypeService,
|
||||||
out entityContainersInstalled);
|
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
|
#endregion
|
||||||
|
|
||||||
#region Content
|
#region Content
|
||||||
@@ -805,26 +845,23 @@ namespace Umbraco.Cms.Infrastructure.Packaging
|
|||||||
{
|
{
|
||||||
if (typeof(T) == typeof(IContentType))
|
if (typeof(T) == typeof(IContentType))
|
||||||
{
|
{
|
||||||
if (parent is null)
|
return parent is null
|
||||||
{
|
? new ContentType(_shortStringHelper, parentId) { Alias = alias, Key = key } as T
|
||||||
return new ContentType(_shortStringHelper, parentId) { Alias = alias, Key = key } as T;
|
: new ContentType(_shortStringHelper, (IContentType)parent, alias) { Key = key } as T;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return new ContentType(_shortStringHelper, (IContentType)parent, alias) { Key = key } as T;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof(T) == typeof(IMediaType))
|
if (typeof(T) == typeof(IMediaType))
|
||||||
{
|
{
|
||||||
if (parent is null)
|
return parent is null
|
||||||
{
|
? new MediaType(_shortStringHelper, parentId) { Alias = alias, Key = key } as T
|
||||||
return new MediaType(_shortStringHelper, parentId) { Alias = alias, Key = key } as T;
|
: new MediaType(_shortStringHelper, (IMediaType)parent, alias) { Key = key } as T;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
if (typeof(T) == typeof(IMemberType))
|
||||||
{
|
{
|
||||||
return new MediaType(_shortStringHelper, (IMediaType)parent, alias) { Key = key } as T;
|
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");
|
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;
|
target?: ReferenceByIdModel | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type CopyMemberTypeRequestModel = {
|
||||||
|
target?: ReferenceByIdModel | null;
|
||||||
|
};
|
||||||
|
|
||||||
export type CreateDataTypeRequestModel = {
|
export type CreateDataTypeRequestModel = {
|
||||||
name: string;
|
name: string;
|
||||||
editorAlias: string;
|
editorAlias: string;
|
||||||
@@ -327,6 +331,7 @@ export type CreateMemberTypeRequestModel = {
|
|||||||
properties: Array<CreateMemberTypePropertyTypeRequestModel>;
|
properties: Array<CreateMemberTypePropertyTypeRequestModel>;
|
||||||
containers: Array<CreateMemberTypePropertyTypeContainerRequestModel>;
|
containers: Array<CreateMemberTypePropertyTypeContainerRequestModel>;
|
||||||
id?: string | null;
|
id?: string | null;
|
||||||
|
parent?: ReferenceByIdModel | null;
|
||||||
compositions: Array<MemberTypeCompositionModel>;
|
compositions: Array<MemberTypeCompositionModel>;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1110,6 +1115,10 @@ export type ImportMediaTypeRequestModel = {
|
|||||||
file: ReferenceByIdModel;
|
file: ReferenceByIdModel;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type ImportMemberTypeRequestModel = {
|
||||||
|
file: ReferenceByIdModel;
|
||||||
|
};
|
||||||
|
|
||||||
export type IndexResponseModel = {
|
export type IndexResponseModel = {
|
||||||
name: string;
|
name: string;
|
||||||
healthStatus: HealthStatusResponseModel;
|
healthStatus: HealthStatusResponseModel;
|
||||||
@@ -1566,6 +1575,7 @@ export type MemberTypeTreeItemResponseModel = {
|
|||||||
parent?: ReferenceByIdModel | null;
|
parent?: ReferenceByIdModel | null;
|
||||||
flags: Array<FlagModel>;
|
flags: Array<FlagModel>;
|
||||||
name: string;
|
name: string;
|
||||||
|
isFolder: boolean;
|
||||||
icon: string;
|
icon: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1636,6 +1646,10 @@ export type MoveMediaTypeRequestModel = {
|
|||||||
target?: ReferenceByIdModel | null;
|
target?: ReferenceByIdModel | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type MoveMemberTypeRequestModel = {
|
||||||
|
target?: ReferenceByIdModel | null;
|
||||||
|
};
|
||||||
|
|
||||||
export type NamedEntityTreeItemResponseModel = {
|
export type NamedEntityTreeItemResponseModel = {
|
||||||
hasChildren: boolean;
|
hasChildren: boolean;
|
||||||
id: string;
|
id: string;
|
||||||
@@ -2923,7 +2937,7 @@ export type UserInstallRequestModel = {
|
|||||||
name: string;
|
name: string;
|
||||||
email: string;
|
email: string;
|
||||||
password: string;
|
password: string;
|
||||||
readonly subscribeToNewsletter: boolean;
|
subscribeToNewsletter: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type UserItemResponseModel = {
|
export type UserItemResponseModel = {
|
||||||
@@ -3158,12 +3172,6 @@ export type UpgradeSettingsResponseModelWritable = {
|
|||||||
oldVersion: string;
|
oldVersion: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type UserInstallRequestModelWritable = {
|
|
||||||
name: string;
|
|
||||||
email: string;
|
|
||||||
password: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type GetCultureData = {
|
export type GetCultureData = {
|
||||||
body?: never;
|
body?: never;
|
||||||
path?: never;
|
path?: never;
|
||||||
@@ -10718,7 +10726,7 @@ export type GetMemberTypeByIdCompositionReferencesResponses = {
|
|||||||
export type GetMemberTypeByIdCompositionReferencesResponse = GetMemberTypeByIdCompositionReferencesResponses[keyof GetMemberTypeByIdCompositionReferencesResponses];
|
export type GetMemberTypeByIdCompositionReferencesResponse = GetMemberTypeByIdCompositionReferencesResponses[keyof GetMemberTypeByIdCompositionReferencesResponses];
|
||||||
|
|
||||||
export type PostMemberTypeByIdCopyData = {
|
export type PostMemberTypeByIdCopyData = {
|
||||||
body?: never;
|
body?: CopyMemberTypeRequestModel;
|
||||||
path: {
|
path: {
|
||||||
id: string;
|
id: string;
|
||||||
};
|
};
|
||||||
@@ -10754,6 +10762,115 @@ export type PostMemberTypeByIdCopyResponses = {
|
|||||||
201: unknown;
|
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 = {
|
export type PostMemberTypeAvailableCompositionsData = {
|
||||||
body?: MemberTypeCompositionRequestModel;
|
body?: MemberTypeCompositionRequestModel;
|
||||||
path?: never;
|
path?: never;
|
||||||
@@ -10952,12 +11069,109 @@ export type PutMemberTypeFolderByIdResponses = {
|
|||||||
200: unknown;
|
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 = {
|
export type GetTreeMemberTypeRootData = {
|
||||||
body?: never;
|
body?: never;
|
||||||
path?: never;
|
path?: never;
|
||||||
query?: {
|
query?: {
|
||||||
skip?: number;
|
skip?: number;
|
||||||
take?: number;
|
take?: number;
|
||||||
|
foldersOnly?: boolean;
|
||||||
};
|
};
|
||||||
url: '/umbraco/management/api/v1/tree/member-type/root';
|
url: '/umbraco/management/api/v1/tree/member-type/root';
|
||||||
};
|
};
|
||||||
@@ -10989,6 +11203,7 @@ export type GetTreeMemberTypeSiblingsData = {
|
|||||||
target?: string;
|
target?: string;
|
||||||
before?: number;
|
before?: number;
|
||||||
after?: number;
|
after?: number;
|
||||||
|
foldersOnly?: boolean;
|
||||||
};
|
};
|
||||||
url: '/umbraco/management/api/v1/tree/member-type/siblings';
|
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> {
|
export class UmbDefaultMediaTypeCreateOptionAction extends UmbEntityCreateOptionActionBase<MetaEntityCreateOptionAction> {
|
||||||
override async getHref() {
|
override async getHref() {
|
||||||
const parentEntityType = this.args.entityType as UmbMediaTypeRootEntityType | UmbMediaTypeFolderEntityType;
|
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;
|
const parentUnique = this.args.unique ?? null;
|
||||||
|
|
||||||
|
|||||||
@@ -8,4 +8,8 @@ export * from './search/constants.js';
|
|||||||
export * from './tree/constants.js';
|
export * from './tree/constants.js';
|
||||||
export * from './workspace/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 './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 { UMB_CREATE_MEMBER_TYPE_WORKSPACE_PATH_PATTERN } from '../../../paths.js';
|
||||||
import { UmbEntityCreateOptionActionBase } from '@umbraco-cms/backoffice/entity-create-option-action';
|
import { UmbEntityCreateOptionActionBase } from '@umbraco-cms/backoffice/entity-create-option-action';
|
||||||
import type { MetaEntityCreateOptionAction } 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> {
|
export class UmbDefaultMemberTypeCreateOptionAction extends UmbEntityCreateOptionActionBase<MetaEntityCreateOptionAction> {
|
||||||
override async getHref() {
|
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');
|
if (!parentEntityType) throw new Error('Entity type is required to create a member type');
|
||||||
|
|
||||||
const parentUnique = this.args.unique ?? null;
|
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';
|
import type { UmbExtensionManifestKind } from '@umbraco-cms/backoffice/extension-registry';
|
||||||
|
|
||||||
export const manifests: Array<UmbExtensionManifest | UmbExtensionManifestKind> = [
|
export const manifests: Array<UmbExtensionManifest | UmbExtensionManifestKind> = [
|
||||||
@@ -8,10 +8,12 @@ export const manifests: Array<UmbExtensionManifest | UmbExtensionManifestKind> =
|
|||||||
name: 'Default Member Type Entity Create Option Action',
|
name: 'Default Member Type Entity Create Option Action',
|
||||||
weight: 1000,
|
weight: 1000,
|
||||||
api: () => import('./default-member-type-create-option-action.js'),
|
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: {
|
meta: {
|
||||||
icon: 'icon-user',
|
icon: 'icon-user',
|
||||||
label: '#content_membertype',
|
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 defaultManifests } from './default/manifests.js';
|
||||||
|
import { manifests as folderManifests } from './folder/manifests.js';
|
||||||
import type { UmbExtensionManifestKind } from '@umbraco-cms/backoffice/extension-registry';
|
import type { UmbExtensionManifestKind } from '@umbraco-cms/backoffice/extension-registry';
|
||||||
|
|
||||||
export const manifests: Array<UmbExtensionManifest | UmbExtensionManifestKind> = [
|
export const manifests: Array<UmbExtensionManifest | UmbExtensionManifestKind> = [
|
||||||
@@ -8,7 +13,9 @@ export const manifests: Array<UmbExtensionManifest | UmbExtensionManifestKind> =
|
|||||||
kind: 'create',
|
kind: 'create',
|
||||||
alias: 'Umb.EntityAction.MemberType.Create',
|
alias: 'Umb.EntityAction.MemberType.Create',
|
||||||
name: 'Create Member Type Entity Action',
|
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,
|
...defaultManifests,
|
||||||
|
...folderManifests,
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -1,18 +1,23 @@
|
|||||||
import { UMB_MEMBER_TYPE_ENTITY_TYPE } from '../../entity.js';
|
import {
|
||||||
import { UMB_MEMBER_TYPE_TREE_REPOSITORY_ALIAS } from '../../constants.js';
|
UMB_MEMBER_TYPE_ENTITY_TYPE,
|
||||||
import { UMB_DUPLICATE_MEMBER_TYPE_REPOSITORY_ALIAS } from './repository/index.js';
|
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';
|
import { manifests as repositoryManifests } from './repository/manifests.js';
|
||||||
|
|
||||||
export const manifests: Array<UmbExtensionManifest> = [
|
export const manifests: Array<UmbExtensionManifest> = [
|
||||||
{
|
{
|
||||||
type: 'entityAction',
|
type: 'entityAction',
|
||||||
kind: 'duplicate',
|
kind: 'duplicateTo',
|
||||||
alias: 'Umb.EntityAction.MemberType.Duplicate',
|
alias: 'Umb.EntityAction.MemberType.DuplicateTo',
|
||||||
name: 'Duplicate Member Type Entity Action',
|
name: 'Duplicate Document To Entity Action',
|
||||||
forEntityTypes: [UMB_MEMBER_TYPE_ENTITY_TYPE],
|
forEntityTypes: [UMB_MEMBER_TYPE_ENTITY_TYPE],
|
||||||
meta: {
|
meta: {
|
||||||
duplicateRepositoryAlias: UMB_DUPLICATE_MEMBER_TYPE_REPOSITORY_ALIAS,
|
duplicateRepositoryAlias: UMB_DUPLICATE_MEMBER_TYPE_REPOSITORY_ALIAS,
|
||||||
|
treeAlias: UMB_MEMBER_TYPE_TREE_ALIAS,
|
||||||
treeRepositoryAlias: UMB_MEMBER_TYPE_TREE_REPOSITORY_ALIAS,
|
treeRepositoryAlias: UMB_MEMBER_TYPE_TREE_REPOSITORY_ALIAS,
|
||||||
|
foldersOnly: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
...repositoryManifests,
|
...repositoryManifests,
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
import { UmbDuplicateMemberTypeServerDataSource } from './member-type-duplicate.server.data-source.js';
|
import { UmbDuplicateMemberTypeServerDataSource } from './member-type-duplicate.server.data-source.js';
|
||||||
import { UMB_NOTIFICATION_CONTEXT } from '@umbraco-cms/backoffice/notification';
|
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';
|
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);
|
#duplicateSource = new UmbDuplicateMemberTypeServerDataSource(this);
|
||||||
|
|
||||||
async requestDuplicate(args: UmbDuplicateRequestArgs) {
|
async requestDuplicateTo(args: UmbDuplicateToRequestArgs) {
|
||||||
const { error } = await this.#duplicateSource.duplicate(args);
|
const { error } = await this.#duplicateSource.duplicateTo(args);
|
||||||
|
|
||||||
if (!error) {
|
if (!error) {
|
||||||
const notificationContext = await this.getContext(UMB_NOTIFICATION_CONTEXT);
|
const notificationContext = await this.getContext(UMB_NOTIFICATION_CONTEXT);
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
import { MemberTypeService } 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';
|
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
|
||||||
import { tryExecute } from '@umbraco-cms/backoffice/resources';
|
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
|
* @class UmbDuplicateMemberTypeServerDataSource
|
||||||
*/
|
*/
|
||||||
export class UmbDuplicateMemberTypeServerDataSource implements UmbDuplicateDataSource {
|
export class UmbDuplicateMemberTypeServerDataSource implements UmbDuplicateToDataSource {
|
||||||
#host: UmbControllerHost;
|
#host: UmbControllerHost;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -20,18 +20,22 @@ export class UmbDuplicateMemberTypeServerDataSource implements UmbDuplicateDataS
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Duplicate an item for the given unique
|
* Duplicate an item for the given unique to the destination unique
|
||||||
* @param {UmbDuplicateRequestArgs} args
|
* @param {UmbDuplicateToRequestArgs} args
|
||||||
* @returns {*}
|
* @returns {*}
|
||||||
* @memberof UmbDuplicateDataTypeServerDataSource
|
* @memberof UmbDuplicateMemberTypeServerDataSource
|
||||||
*/
|
*/
|
||||||
async duplicate(args: UmbDuplicateRequestArgs) {
|
async duplicateTo(args: UmbDuplicateToRequestArgs) {
|
||||||
if (!args.unique) throw new Error('Unique is missing');
|
if (!args.unique) throw new Error('Unique is missing');
|
||||||
|
if (args.destination.unique === undefined) throw new Error('Destination unique is missing');
|
||||||
|
|
||||||
return tryExecute(
|
return tryExecute(
|
||||||
this.#host,
|
this.#host,
|
||||||
MemberTypeService.postMemberTypeByIdCopy({
|
MemberTypeService.postMemberTypeByIdCopy({
|
||||||
path: { id: args.unique },
|
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 {
|
||||||
import { UMB_MEMBER_TYPE_ENTITY_TYPE } from '../entity.js';
|
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 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 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';
|
import type { UmbExtensionManifestKind } from '@umbraco-cms/backoffice/extension-registry';
|
||||||
|
|
||||||
export const manifests: Array<UmbExtensionManifest | UmbExtensionManifestKind> = [
|
export const manifests: Array<UmbExtensionManifest | UmbExtensionManifestKind> = [
|
||||||
@@ -17,5 +23,8 @@ export const manifests: Array<UmbExtensionManifest | UmbExtensionManifestKind> =
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
...createManifests,
|
...createManifests,
|
||||||
|
...moveManifests,
|
||||||
...duplicateManifests,
|
...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_ENTITY_TYPE = 'member-type';
|
||||||
export const UMB_MEMBER_TYPE_ROOT_ENTITY_TYPE = 'member-type-root';
|
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 UmbMemberTypeEntityType = typeof UMB_MEMBER_TYPE_ENTITY_TYPE;
|
||||||
export type UmbMemberTypeRootEntityType = typeof UMB_MEMBER_TYPE_ROOT_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 {*}
|
* @returns {*}
|
||||||
* @memberof UmbMemberTypeDetailServerDataSource
|
* @memberof UmbMemberTypeDetailServerDataSource
|
||||||
*/
|
*/
|
||||||
async create(model: UmbMemberTypeDetailModel) {
|
async create(model: UmbMemberTypeDetailModel, parentUnique: string | null = null) {
|
||||||
if (!model) throw new Error('Member Type is missing');
|
if (!model) throw new Error('Member Type is missing');
|
||||||
|
|
||||||
// TODO: make data mapper to prevent errors
|
// TODO: make data mapper to prevent errors
|
||||||
@@ -162,6 +162,7 @@ export class UmbMemberTypeDetailServerDataSource implements UmbDetailDataSource<
|
|||||||
}),
|
}),
|
||||||
containers: model.containers,
|
containers: model.containers,
|
||||||
id: model.unique,
|
id: model.unique,
|
||||||
|
parent: parentUnique ? { id: parentUnique } : null,
|
||||||
compositions: model.compositions.map((composition) => {
|
compositions: model.compositions.map((composition) => {
|
||||||
return {
|
return {
|
||||||
memberType: { id: composition.contentType.unique },
|
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 {
|
export interface UmbMemberTypeItemModel {
|
||||||
entityType: UmbMemberTypeEntityType;
|
entityType: UmbMemberTypeEntityType | UmbMemberTypeFolderEntityType;
|
||||||
unique: string;
|
unique: string;
|
||||||
name: string;
|
name: string;
|
||||||
icon: 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 { 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';
|
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_ENTITY_TYPE, UMB_MEMBER_TYPE_ROOT_ENTITY_TYPE } from '../entity.js';
|
||||||
import {
|
import {
|
||||||
UMB_MEMBER_TYPE_TREE_ALIAS,
|
UMB_MEMBER_TYPE_TREE_ALIAS,
|
||||||
UMB_MEMBER_TYPE_TREE_ITEM_CHILDREN_COLLECTION_ALIAS,
|
|
||||||
UMB_MEMBER_TYPE_TREE_REPOSITORY_ALIAS,
|
UMB_MEMBER_TYPE_TREE_REPOSITORY_ALIAS,
|
||||||
UMB_MEMBER_TYPE_TREE_STORE_ALIAS,
|
UMB_MEMBER_TYPE_TREE_STORE_ALIAS,
|
||||||
} from './constants.js';
|
} from './constants.js';
|
||||||
import { manifests as treeItemChildrenManifest } from './tree-item-children/manifests.js';
|
import { manifests as folderManifests } from './folder/manifests.js';
|
||||||
import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace';
|
import { manifests as treeItemChildrenManifests } from './tree-item-children/manifests.js';
|
||||||
|
|
||||||
export const manifests: Array<UmbExtensionManifest> = [
|
export const manifests: Array<UmbExtensionManifest> = [
|
||||||
{
|
{
|
||||||
@@ -38,23 +36,6 @@ export const manifests: Array<UmbExtensionManifest> = [
|
|||||||
name: 'Member Type Tree Item',
|
name: 'Member Type Tree Item',
|
||||||
forEntityTypes: [UMB_MEMBER_TYPE_ROOT_ENTITY_TYPE, UMB_MEMBER_TYPE_ENTITY_TYPE],
|
forEntityTypes: [UMB_MEMBER_TYPE_ROOT_ENTITY_TYPE, UMB_MEMBER_TYPE_ENTITY_TYPE],
|
||||||
},
|
},
|
||||||
{
|
...folderManifests,
|
||||||
type: 'workspaceView',
|
...treeItemChildrenManifests,
|
||||||
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,
|
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { UMB_MEMBER_TYPE_ROOT_ENTITY_TYPE } from '../entity.js';
|
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 type { UmbMemberTypeTreeItemModel, UmbMemberTypeTreeRootModel } from './types.js';
|
||||||
import { UMB_MEMBER_TYPE_TREE_STORE_CONTEXT } from './member-type-tree.store.context-token.js';
|
import { UMB_MEMBER_TYPE_TREE_STORE_CONTEXT } from './member-type-tree.store.context-token.js';
|
||||||
import { UmbTreeRepositoryBase } from '@umbraco-cms/backoffice/tree';
|
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