diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Member/References/AreReferencedMemberController.cs b/src/Umbraco.Cms.Api.Management/Controllers/Member/References/AreReferencedMemberController.cs new file mode 100644 index 0000000000..1b46a981ce --- /dev/null +++ b/src/Umbraco.Cms.Api.Management/Controllers/Member/References/AreReferencedMemberController.cs @@ -0,0 +1,51 @@ +using Asp.Versioning; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using Umbraco.Cms.Api.Common.ViewModels.Pagination; +using Umbraco.Cms.Api.Management.ViewModels; +using Umbraco.Cms.Core; +using Umbraco.Cms.Core.Mapping; +using Umbraco.Cms.Core.Models; +using Umbraco.Cms.Core.Services; + +namespace Umbraco.Cms.Api.Management.Controllers.Member.References; + +[ApiVersion("1.0")] +public class AreReferencedMemberController : MemberControllerBase +{ + private readonly ITrackedReferencesService _trackedReferencesSkipTakeService; + private readonly IUmbracoMapper _umbracoMapper; + + public AreReferencedMemberController(ITrackedReferencesService trackedReferencesSkipTakeService, IUmbracoMapper umbracoMapper) + { + _trackedReferencesSkipTakeService = trackedReferencesSkipTakeService; + _umbracoMapper = umbracoMapper; + } + + /// + /// Gets a page list of the items used in any kind of relation from selected keys. + /// + /// + /// Used when bulk deleting content/media and bulk unpublishing content (delete and unpublish on List view). + /// This is basically finding children of relations. + /// + // [HttpGet("item")] + [HttpGet("are-referenced")] + [MapToApiVersion("1.0")] + [ProducesResponseType(typeof(PagedViewModel), StatusCodes.Status200OK)] + public async Task>> GetPagedReferencedItems( + CancellationToken cancellationToken, + [FromQuery(Name="id")] HashSet ids, + int skip = 0, + int take = 20) + { + PagedModel distinctByKeyItemsWithReferencedRelations = await _trackedReferencesSkipTakeService.GetPagedKeysWithDependentReferencesAsync(ids, Constants.ObjectTypes.Member, skip, take); + var pagedViewModel = new PagedViewModel + { + Total = distinctByKeyItemsWithReferencedRelations.Total, + Items = _umbracoMapper.MapEnumerable(distinctByKeyItemsWithReferencedRelations.Items), + }; + + return pagedViewModel; + } +} diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Member/References/ReferencedByMemberController.cs b/src/Umbraco.Cms.Api.Management/Controllers/Member/References/ReferencedByMemberController.cs new file mode 100644 index 0000000000..69237278a5 --- /dev/null +++ b/src/Umbraco.Cms.Api.Management/Controllers/Member/References/ReferencedByMemberController.cs @@ -0,0 +1,50 @@ +using Asp.Versioning; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using Umbraco.Cms.Api.Common.ViewModels.Pagination; +using Umbraco.Cms.Api.Management.Factories; +using Umbraco.Cms.Api.Management.ViewModels.TrackedReferences; +using Umbraco.Cms.Core.Models; +using Umbraco.Cms.Core.Services; + +namespace Umbraco.Cms.Api.Management.Controllers.Member.References; + +[ApiVersion("1.0")] +public class ReferencedByMemberController : MemberControllerBase +{ + private readonly ITrackedReferencesService _trackedReferencesService; + private readonly IRelationTypePresentationFactory _relationTypePresentationFactory; + + public ReferencedByMemberController(ITrackedReferencesService trackedReferencesService, IRelationTypePresentationFactory relationTypePresentationFactory) + { + _trackedReferencesService = trackedReferencesService; + _relationTypePresentationFactory = relationTypePresentationFactory; + } + + /// + /// Gets a page list of tracked references for the current item, so you can see where an item is being used. + /// + /// + /// Used by info tabs on content, media etc. and for the delete and unpublish of single items. + /// This is basically finding parents of relations. + /// + [HttpGet("{id:guid}/referenced-by")] + [MapToApiVersion("1.0")] + [ProducesResponseType(typeof(PagedViewModel), StatusCodes.Status200OK)] + public async Task>> ReferencedBy( + CancellationToken cancellationToken, + Guid id, + int skip = 0, + int take = 20) + { + PagedModel relationItems = await _trackedReferencesService.GetPagedRelationsForItemAsync(id, skip, take, true); + + var pagedViewModel = new PagedViewModel + { + Total = relationItems.Total, + Items = await _relationTypePresentationFactory.CreateReferenceResponseModelsAsync(relationItems.Items), + }; + + return pagedViewModel; + } +} diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Member/References/ReferencedDescendantsMemberController.cs b/src/Umbraco.Cms.Api.Management/Controllers/Member/References/ReferencedDescendantsMemberController.cs new file mode 100644 index 0000000000..aa86950e6e --- /dev/null +++ b/src/Umbraco.Cms.Api.Management/Controllers/Member/References/ReferencedDescendantsMemberController.cs @@ -0,0 +1,50 @@ +using Asp.Versioning; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using Umbraco.Cms.Api.Common.ViewModels.Pagination; +using Umbraco.Cms.Api.Management.ViewModels; +using Umbraco.Cms.Core.Mapping; +using Umbraco.Cms.Core.Models; +using Umbraco.Cms.Core.Services; + +namespace Umbraco.Cms.Api.Management.Controllers.Member.References; + +[ApiVersion("1.0")] +public class ReferencedDescendantsMemberController : MemberControllerBase +{ + private readonly ITrackedReferencesService _trackedReferencesSkipTakeService; + private readonly IUmbracoMapper _umbracoMapper; + + public ReferencedDescendantsMemberController(ITrackedReferencesService trackedReferencesSkipTakeService, IUmbracoMapper umbracoMapper) + { + _trackedReferencesSkipTakeService = trackedReferencesSkipTakeService; + _umbracoMapper = umbracoMapper; + } + + /// + /// Gets a page list of the child nodes of the current item used in any kind of relation. + /// + /// + /// Used when deleting and unpublishing a single item to check if this item has any descending items that are in any + /// kind of relation. + /// This is basically finding the descending items which are children in relations. + /// + [HttpGet("{id:guid}/referenced-descendants")] + [MapToApiVersion("1.0")] + [ProducesResponseType(typeof(PagedViewModel), StatusCodes.Status200OK)] + public async Task>> ReferencedDescendants( + CancellationToken cancellationToken, + Guid id, + int skip = 0, + int take = 20) + { + PagedModel relationItems = await _trackedReferencesSkipTakeService.GetPagedDescendantsInReferencesAsync(id, skip, take, true); + var pagedViewModel = new PagedViewModel + { + Total = relationItems.Total, + Items = _umbracoMapper.MapEnumerable(relationItems.Items), + }; + + return pagedViewModel; + } +} diff --git a/src/Umbraco.Cms.Api.Management/Factories/RelationTypePresentationFactory.cs b/src/Umbraco.Cms.Api.Management/Factories/RelationTypePresentationFactory.cs index 0d58784b79..c45d03bc28 100644 --- a/src/Umbraco.Cms.Api.Management/Factories/RelationTypePresentationFactory.cs +++ b/src/Umbraco.Cms.Api.Management/Factories/RelationTypePresentationFactory.cs @@ -58,6 +58,7 @@ public class RelationTypePresentationFactory : IRelationTypePresentationFactory { Constants.UdiEntityType.Document => MapDocumentReference(relationItemModel, slimEntities), Constants.UdiEntityType.Media => _umbracoMapper.Map(relationItemModel), + Constants.UdiEntityType.Member => _umbracoMapper.Map(relationItemModel), _ => _umbracoMapper.Map(relationItemModel), }).WhereNotNull().ToArray(); diff --git a/src/Umbraco.Cms.Api.Management/Mapping/TrackedReferences/TrackedReferenceViewModelsMapDefinition.cs b/src/Umbraco.Cms.Api.Management/Mapping/TrackedReferences/TrackedReferenceViewModelsMapDefinition.cs index 7a3874271c..e9f2700f5a 100644 --- a/src/Umbraco.Cms.Api.Management/Mapping/TrackedReferences/TrackedReferenceViewModelsMapDefinition.cs +++ b/src/Umbraco.Cms.Api.Management/Mapping/TrackedReferences/TrackedReferenceViewModelsMapDefinition.cs @@ -1,4 +1,4 @@ -using Umbraco.Cms.Api.Management.ViewModels; +using Umbraco.Cms.Api.Management.ViewModels; using Umbraco.Cms.Core.Mapping; using Umbraco.Cms.Core.Models; using Umbraco.Cms.Api.Management.ViewModels.TrackedReferences; @@ -11,6 +11,7 @@ public class TrackedReferenceViewModelsMapDefinition : IMapDefinition { mapper.Define((source, context) => new DocumentReferenceResponseModel(), Map); mapper.Define((source, context) => new MediaReferenceResponseModel(), Map); + mapper.Define((source, context) => new MemberReferenceResponseModel(), Map); mapper.Define((source, context) => new DefaultReferenceResponseModel(), Map); mapper.Define((source, context) => new ReferenceByIdModel(), Map); mapper.Define((source, context) => new ReferenceByIdModel(), Map); @@ -43,6 +44,19 @@ public class TrackedReferenceViewModelsMapDefinition : IMapDefinition }; } + // Umbraco.Code.MapAll + private void Map(RelationItemModel source, MemberReferenceResponseModel target, MapperContext context) + { + target.Id = source.NodeKey; + target.Name = source.NodeName; + target.MemberType = new TrackedReferenceMemberType + { + Alias = source.ContentTypeAlias, + Icon = source.ContentTypeIcon, + Name = source.ContentTypeName, + }; + } + // Umbraco.Code.MapAll private void Map(RelationItemModel source, DefaultReferenceResponseModel target, MapperContext context) { diff --git a/src/Umbraco.Cms.Api.Management/OpenApi.json b/src/Umbraco.Cms.Api.Management/OpenApi.json index 4b496bbe8f..7928c27617 100644 --- a/src/Umbraco.Cms.Api.Management/OpenApi.json +++ b/src/Umbraco.Cms.Api.Management/OpenApi.json @@ -6245,6 +6245,13 @@ "type": "string" } }, + { + "name": "isElement", + "in": "query", + "schema": { + "type": "boolean" + } + }, { "name": "skip", "in": "query", @@ -9926,6 +9933,13 @@ "type": "string" } }, + { + "name": "trashed", + "in": "query", + "schema": { + "type": "boolean" + } + }, { "name": "skip", "in": "query", @@ -15623,6 +15637,13 @@ "type": "string" } }, + { + "name": "trashed", + "in": "query", + "schema": { + "type": "boolean" + } + }, { "name": "skip", "in": "query", @@ -20028,6 +20049,134 @@ ] } }, + "/umbraco/management/api/v1/member/{id}/referenced-by": { + "get": { + "tags": [ + "Member" + ], + "operationId": "GetMemberByIdReferencedBy", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + }, + { + "name": "skip", + "in": "query", + "schema": { + "type": "integer", + "format": "int32", + "default": 0 + } + }, + { + "name": "take", + "in": "query", + "schema": { + "type": "integer", + "format": "int32", + "default": 20 + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "oneOf": [ + { + "$ref": "#/components/schemas/PagedIReferenceResponseModel" + } + ] + } + } + } + }, + "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/{id}/referenced-descendants": { + "get": { + "tags": [ + "Member" + ], + "operationId": "GetMemberByIdReferencedDescendants", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + }, + { + "name": "skip", + "in": "query", + "schema": { + "type": "integer", + "format": "int32", + "default": 0 + } + }, + { + "name": "take", + "in": "query", + "schema": { + "type": "integer", + "format": "int32", + "default": 20 + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "oneOf": [ + { + "$ref": "#/components/schemas/PagedReferenceByIdModel" + } + ] + } + } + } + }, + "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/{id}/validate": { "put": { "tags": [ @@ -20170,6 +20319,73 @@ ] } }, + "/umbraco/management/api/v1/member/are-referenced": { + "get": { + "tags": [ + "Member" + ], + "operationId": "GetMemberAreReferenced", + "parameters": [ + { + "name": "id", + "in": "query", + "schema": { + "uniqueItems": true, + "type": "array", + "items": { + "type": "string", + "format": "uuid" + } + } + }, + { + "name": "skip", + "in": "query", + "schema": { + "type": "integer", + "format": "int32", + "default": 0 + } + }, + { + "name": "take", + "in": "query", + "schema": { + "type": "integer", + "format": "int32", + "default": 20 + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "oneOf": [ + { + "$ref": "#/components/schemas/PagedReferenceByIdModel" + } + ] + } + } + } + }, + "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/configuration": { "get": { "tags": [ @@ -39861,6 +40077,41 @@ ], "type": "string" }, + "MemberReferenceResponseModel": { + "required": [ + "$type", + "id", + "memberType" + ], + "type": "object", + "properties": { + "$type": { + "type": "string" + }, + "id": { + "type": "string", + "format": "uuid" + }, + "name": { + "type": "string", + "nullable": true + }, + "memberType": { + "oneOf": [ + { + "$ref": "#/components/schemas/TrackedReferenceMemberTypeModel" + } + ] + } + }, + "additionalProperties": false, + "discriminator": { + "propertyName": "$type", + "mapping": { + "MemberReferenceResponseModel": "#/components/schemas/MemberReferenceResponseModel" + } + } + }, "MemberResponseModel": { "required": [ "email", @@ -41271,6 +41522,9 @@ }, { "$ref": "#/components/schemas/MediaReferenceResponseModel" + }, + { + "$ref": "#/components/schemas/MemberReferenceResponseModel" } ] } @@ -43943,6 +44197,24 @@ }, "additionalProperties": false }, + "TrackedReferenceMemberTypeModel": { + "type": "object", + "properties": { + "icon": { + "type": "string", + "nullable": true + }, + "alias": { + "type": "string", + "nullable": true + }, + "name": { + "type": "string", + "nullable": true + } + }, + "additionalProperties": false + }, "UnknownTypePermissionPresentationModel": { "required": [ "$type", @@ -46287,4 +46559,4 @@ } } } -} \ No newline at end of file +} diff --git a/src/Umbraco.Cms.Api.Management/ViewModels/TrackedReferences/DefaultReferenceResponseModel.cs b/src/Umbraco.Cms.Api.Management/ViewModels/TrackedReferences/DefaultReferenceResponseModel.cs index 66780c9b47..f74b0d2840 100644 --- a/src/Umbraco.Cms.Api.Management/ViewModels/TrackedReferences/DefaultReferenceResponseModel.cs +++ b/src/Umbraco.Cms.Api.Management/ViewModels/TrackedReferences/DefaultReferenceResponseModel.cs @@ -1,11 +1,7 @@ -namespace Umbraco.Cms.Api.Management.ViewModels.TrackedReferences; +namespace Umbraco.Cms.Api.Management.ViewModels.TrackedReferences; -public class DefaultReferenceResponseModel : IReferenceResponseModel +public class DefaultReferenceResponseModel : ReferenceResponseModel { - public Guid Id { get; set; } - - public string? Name { get; set; } - public string? Type { get; set; } public string? Icon { get; set; } diff --git a/src/Umbraco.Cms.Api.Management/ViewModels/TrackedReferences/DocumentReferenceResponseModel.cs b/src/Umbraco.Cms.Api.Management/ViewModels/TrackedReferences/DocumentReferenceResponseModel.cs index e2bb767f99..a24ab23990 100644 --- a/src/Umbraco.Cms.Api.Management/ViewModels/TrackedReferences/DocumentReferenceResponseModel.cs +++ b/src/Umbraco.Cms.Api.Management/ViewModels/TrackedReferences/DocumentReferenceResponseModel.cs @@ -1,13 +1,9 @@ -using Umbraco.Cms.Api.Management.ViewModels.Document; +using Umbraco.Cms.Api.Management.ViewModels.Document; namespace Umbraco.Cms.Api.Management.ViewModels.TrackedReferences; -public class DocumentReferenceResponseModel : IReferenceResponseModel +public class DocumentReferenceResponseModel : ReferenceResponseModel { - public Guid Id { get; set; } - - public string? Name { get; set; } - public bool? Published { get; set; } public TrackedReferenceDocumentType DocumentType { get; set; } = new(); diff --git a/src/Umbraco.Cms.Api.Management/ViewModels/TrackedReferences/MediaReferenceResponseModel.cs b/src/Umbraco.Cms.Api.Management/ViewModels/TrackedReferences/MediaReferenceResponseModel.cs index c9b910d0b1..5358088bb3 100644 --- a/src/Umbraco.Cms.Api.Management/ViewModels/TrackedReferences/MediaReferenceResponseModel.cs +++ b/src/Umbraco.Cms.Api.Management/ViewModels/TrackedReferences/MediaReferenceResponseModel.cs @@ -1,10 +1,6 @@ -namespace Umbraco.Cms.Api.Management.ViewModels.TrackedReferences; +namespace Umbraco.Cms.Api.Management.ViewModels.TrackedReferences; -public class MediaReferenceResponseModel : IReferenceResponseModel +public class MediaReferenceResponseModel : ReferenceResponseModel { - public Guid Id { get; set; } - - public string? Name { get; set; } - public TrackedReferenceMediaType MediaType { get; set; } = new(); } diff --git a/src/Umbraco.Cms.Api.Management/ViewModels/TrackedReferences/MemberReferenceResponseModel.cs b/src/Umbraco.Cms.Api.Management/ViewModels/TrackedReferences/MemberReferenceResponseModel.cs new file mode 100644 index 0000000000..8e33a2a175 --- /dev/null +++ b/src/Umbraco.Cms.Api.Management/ViewModels/TrackedReferences/MemberReferenceResponseModel.cs @@ -0,0 +1,6 @@ +namespace Umbraco.Cms.Api.Management.ViewModels.TrackedReferences; + +public class MemberReferenceResponseModel : ReferenceResponseModel +{ + public TrackedReferenceMemberType MemberType { get; set; } = new(); +} diff --git a/src/Umbraco.Cms.Api.Management/ViewModels/TrackedReferences/ReferenceResponseModel.cs b/src/Umbraco.Cms.Api.Management/ViewModels/TrackedReferences/ReferenceResponseModel.cs new file mode 100644 index 0000000000..dae755fd33 --- /dev/null +++ b/src/Umbraco.Cms.Api.Management/ViewModels/TrackedReferences/ReferenceResponseModel.cs @@ -0,0 +1,8 @@ +namespace Umbraco.Cms.Api.Management.ViewModels.TrackedReferences; + +public abstract class ReferenceResponseModel : IReferenceResponseModel +{ + public Guid Id { get; set; } + + public string? Name { get; set; } +} diff --git a/src/Umbraco.Cms.Api.Management/ViewModels/TrackedReferences/TrackedReferenceMemberType.cs b/src/Umbraco.Cms.Api.Management/ViewModels/TrackedReferences/TrackedReferenceMemberType.cs new file mode 100644 index 0000000000..501ababd1f --- /dev/null +++ b/src/Umbraco.Cms.Api.Management/ViewModels/TrackedReferences/TrackedReferenceMemberType.cs @@ -0,0 +1,5 @@ +namespace Umbraco.Cms.Api.Management.ViewModels.TrackedReferences; + +public class TrackedReferenceMemberType : TrackedReferenceContentType +{ +} diff --git a/src/Umbraco.Core/Constants-Conventions.cs b/src/Umbraco.Core/Constants-Conventions.cs index 647226b6d7..989b947adc 100644 --- a/src/Umbraco.Core/Constants-Conventions.cs +++ b/src/Umbraco.Core/Constants-Conventions.cs @@ -233,17 +233,27 @@ public static partial class Constants public const string RelatedMediaName = "Related Media"; /// - /// Alias for default relation type "Related Media" + /// Alias for default relation type "Related Media". /// public const string RelatedMediaAlias = "umbMedia"; + /// + /// Name for default relation type "Related Member". + /// + public const string RelatedMemberName = "Related Member"; + + /// + /// Alias for default relation type "Related Member". + /// + public const string RelatedMemberAlias = "umbMember"; + /// /// Name for default relation type "Related Document". /// public const string RelatedDocumentName = "Related Document"; /// - /// Alias for default relation type "Related Document" + /// Alias for default relation type "Related Document". /// public const string RelatedDocumentAlias = "umbDocument"; @@ -284,7 +294,7 @@ public static partial class Constants /// Developers should not manually use these relation types since they will all be cleared whenever an entity /// (content, media or member) is saved since they are auto-populated based on property values. /// - public static string[] AutomaticRelationTypes { get; } = { RelatedMediaAlias, RelatedDocumentAlias }; + public static string[] AutomaticRelationTypes { get; } = { RelatedMediaAlias, RelatedMemberAlias, RelatedDocumentAlias }; // TODO: return a list of built in types so we can use that to prevent deletion in the UI } diff --git a/src/Umbraco.Core/Models/Editors/UmbracoEntityReference.cs b/src/Umbraco.Core/Models/Editors/UmbracoEntityReference.cs index 3f02be10b1..3c22042b99 100644 --- a/src/Umbraco.Core/Models/Editors/UmbracoEntityReference.cs +++ b/src/Umbraco.Core/Models/Editors/UmbracoEntityReference.cs @@ -34,6 +34,9 @@ public struct UmbracoEntityReference : IEquatable case Constants.UdiEntityType.Media: RelationTypeAlias = Constants.Conventions.RelationTypes.RelatedMediaAlias; break; + case Constants.UdiEntityType.Member: + RelationTypeAlias = Constants.Conventions.RelationTypes.RelatedMemberAlias; + break; default: // No relation type alias convention for this entity type, so leave it empty RelationTypeAlias = string.Empty; diff --git a/src/Umbraco.Core/Models/RelationTypeExtensions.cs b/src/Umbraco.Core/Models/RelationTypeExtensions.cs index 6a22f607be..81d6801330 100644 --- a/src/Umbraco.Core/Models/RelationTypeExtensions.cs +++ b/src/Umbraco.Core/Models/RelationTypeExtensions.cs @@ -11,6 +11,7 @@ public static class RelationTypeExtensions public static bool IsSystemRelationType(this IRelationType relationType) => relationType.Alias == Constants.Conventions.RelationTypes.RelatedDocumentAlias || relationType.Alias == Constants.Conventions.RelationTypes.RelatedMediaAlias + || relationType.Alias == Constants.Conventions.RelationTypes.RelatedMemberAlias || relationType.Alias == Constants.Conventions.RelationTypes.RelateDocumentOnCopyAlias || relationType.Alias == Constants.Conventions.RelationTypes.RelateParentDocumentOnDeleteAlias || relationType.Alias == Constants.Conventions.RelationTypes.RelateParentMediaFolderOnDeleteAlias; diff --git a/src/Umbraco.Core/PropertyEditors/DataValueReferenceFactoryCollection.cs b/src/Umbraco.Core/PropertyEditors/DataValueReferenceFactoryCollection.cs index 4a83a65405..888b1dfdf2 100644 --- a/src/Umbraco.Core/PropertyEditors/DataValueReferenceFactoryCollection.cs +++ b/src/Umbraco.Core/PropertyEditors/DataValueReferenceFactoryCollection.cs @@ -91,7 +91,7 @@ public class DataValueReferenceFactoryCollection : BuilderCollectionBase DataValueEditorFactory.Create(Attribute!); - private class MemberPickerPropertyValueEditor : DataValueEditor + private class MemberPickerPropertyValueEditor : DataValueEditor, IDataValueReference { private readonly IMemberService _memberService; @@ -61,5 +61,20 @@ public class MemberPickerPropertyEditor : DataEditor => editorValue.Value is string stringValue && Guid.TryParse(stringValue, out Guid memberKey) ? new GuidUdi(Constants.UdiEntityType.Member, memberKey) : null; + + public IEnumerable GetReferences(object? value) + { + var asString = value is string str ? str : value?.ToString(); + + if (string.IsNullOrEmpty(asString)) + { + yield break; + } + + if (UdiParser.TryParse(asString, out Udi? udi)) + { + yield return new UmbracoEntityReference(udi); + } + } } } diff --git a/src/Umbraco.Infrastructure/Migrations/Install/DatabaseDataCreator.cs b/src/Umbraco.Infrastructure/Migrations/Install/DatabaseDataCreator.cs index b495bf7b00..f6d43e0a82 100644 --- a/src/Umbraco.Infrastructure/Migrations/Install/DatabaseDataCreator.cs +++ b/src/Umbraco.Infrastructure/Migrations/Install/DatabaseDataCreator.cs @@ -2307,6 +2307,9 @@ internal class DatabaseDataCreator Constants.Conventions.RelationTypes.RelatedMediaName, null, null, false, true); CreateRelationTypeData(5, Constants.Conventions.RelationTypes.RelatedDocumentAlias, Constants.Conventions.RelationTypes.RelatedDocumentName, null, null, false, true); + CreateRelationTypeData(6, Constants.Conventions.RelationTypes.RelatedMemberAlias, + Constants.Conventions.RelationTypes.RelatedMemberName, null, null, false, true); + } private void CreateRelationTypeData(int id, string alias, string name, Guid? parentObjectType, diff --git a/src/Umbraco.Infrastructure/Migrations/Upgrade/UmbracoPlan.cs b/src/Umbraco.Infrastructure/Migrations/Upgrade/UmbracoPlan.cs index fe14f785d8..395504cfdc 100644 --- a/src/Umbraco.Infrastructure/Migrations/Upgrade/UmbracoPlan.cs +++ b/src/Umbraco.Infrastructure/Migrations/Upgrade/UmbracoPlan.cs @@ -114,5 +114,6 @@ public class UmbracoPlan : MigrationPlan // To 15.4.0 To("{A9E72794-4036-4563-B543-1717C73B8879}"); + To("{33D62294-D0DE-4A86-A830-991EB36B96DA}"); } } diff --git a/src/Umbraco.Infrastructure/Migrations/Upgrade/V_15_4_0/AddRelationTypeForMembers.cs b/src/Umbraco.Infrastructure/Migrations/Upgrade/V_15_4_0/AddRelationTypeForMembers.cs new file mode 100644 index 0000000000..bcc3422946 --- /dev/null +++ b/src/Umbraco.Infrastructure/Migrations/Upgrade/V_15_4_0/AddRelationTypeForMembers.cs @@ -0,0 +1,46 @@ +using Microsoft.Extensions.Logging; +using Umbraco.Cms.Core; +using Umbraco.Cms.Core.Models; +using Umbraco.Cms.Core.Services; +using Umbraco.Cms.Infrastructure.Migrations.Install; + +namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_15_4_0; + +/// +/// Migration to add an automatic relation type for members if it doesn't already exist. +/// +public class AddRelationTypeForMembers : MigrationBase +{ + private readonly IRelationService _relationService; + + /// + /// Initializes a new instance of the class. + /// + public AddRelationTypeForMembers(IMigrationContext context, IRelationService relationService) + : base(context) => _relationService = relationService; + + /// + protected override void Migrate() + { + Logger.LogDebug("Adding automatic relation type for members if it doesn't already exist"); + + IRelationType? relationType = _relationService.GetRelationTypeByAlias(Constants.Conventions.RelationTypes.RelatedMemberAlias); + if (relationType != null) + { + Logger.LogDebug("Automatic relation type for members already exists."); + return; + } + + // Generate a new unique relation type key that is the same as would have come from a new install. + Guid key = DatabaseDataCreator.CreateUniqueRelationTypeId( + Constants.Conventions.RelationTypes.RelatedMemberAlias, + Constants.Conventions.RelationTypes.RelatedMemberName); + + // Create new relation type using service, so the repository cache gets updated as well. + relationType = new RelationType(Constants.Conventions.RelationTypes.RelatedMemberName, Constants.Conventions.RelationTypes.RelatedMemberAlias, false, null, null, true) + { + Key = key + }; + _relationService.Save(relationType); + } +} diff --git a/src/Umbraco.Web.UI.Client/devops/circular/index.js b/src/Umbraco.Web.UI.Client/devops/circular/index.js index 4683c12e7c..ac7c0f4970 100644 --- a/src/Umbraco.Web.UI.Client/devops/circular/index.js +++ b/src/Umbraco.Web.UI.Client/devops/circular/index.js @@ -7,9 +7,9 @@ import madge from 'madge'; import { join } from 'path'; -import { mkdirSync } from 'fs'; +//import { mkdirSync } from 'fs'; -const __dirname = import.meta.dirname; +//const __dirname = import.meta.dirname; const IS_GITHUB_ACTIONS = process.env.GITHUB_ACTIONS === 'true'; const IS_AZURE_PIPELINES = process.env.TF_BUILD === 'true'; const baseDir = process.argv[2] || 'src'; @@ -40,15 +40,23 @@ if (circular.length) { } console.error('\nPlease fix the circular dependencies before proceeding.\n'); + /* + // Curently disabled as we don't have Graphviz installed on the CI servers neither do we use this visualization currently. + // Ideally its an opt in feature that is triggered by a environment variable. try { const imagePath = join(__dirname, '../../madge'); mkdirSync(imagePath, { recursive: true }); const image = await madgeSetup.image(join(imagePath, 'circular.svg'), true); console.log('Circular dependencies graph generated:', image); } catch { console.warn('No image generated. Make sure Graphviz is in your $PATH if you want a visualization'); } + */ - // TODO: Set this to 1 when we have fixed all circular dependencies - process.exit(0); + // TODO: Remove this check and set an exit with argument 1 when we have fixed all circular dependencies. + if (circular.length > 11) { + process.exit(1); + } else { + process.exit(0); + } } console.log('\nNo circular dependencies detected.\n'); diff --git a/src/Umbraco.Web.UI.Client/examples/workspace-context-counter/counter-workspace-context.ts b/src/Umbraco.Web.UI.Client/examples/workspace-context-counter/counter-workspace-context.ts index 86525593be..fb1d017015 100644 --- a/src/Umbraco.Web.UI.Client/examples/workspace-context-counter/counter-workspace-context.ts +++ b/src/Umbraco.Web.UI.Client/examples/workspace-context-counter/counter-workspace-context.ts @@ -1,17 +1,19 @@ import { UmbContextToken } from '@umbraco-cms/backoffice/context-api'; -import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api'; +import { UmbContextBase } from '@umbraco-cms/backoffice/class-api'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; import { UmbNumberState } from '@umbraco-cms/backoffice/observable-api'; // The Example Workspace Context Controller: -export class WorkspaceContextCounter extends UmbControllerBase { +export class WorkspaceContextCounterElement extends UmbContextBase< + WorkspaceContextCounterElement, + typeof EXAMPLE_COUNTER_CONTEXT +> { // We always keep our states private, and expose the values as observables: #counter = new UmbNumberState(0); readonly counter = this.#counter.asObservable(); constructor(host: UmbControllerHost) { - super(host, EXAMPLE_COUNTER_CONTEXT.toString()); - this.provideContext(EXAMPLE_COUNTER_CONTEXT, this); + super(host, EXAMPLE_COUNTER_CONTEXT); } // Lets expose methods to update the state: @@ -21,10 +23,10 @@ export class WorkspaceContextCounter extends UmbControllerBase { } // Declare a api export, so Extension Registry can initialize this class: -export const api = WorkspaceContextCounter; +export const api = WorkspaceContextCounterElement; // Declare a Context Token that other elements can use to request the WorkspaceContextCounter: -export const EXAMPLE_COUNTER_CONTEXT = new UmbContextToken( +export const EXAMPLE_COUNTER_CONTEXT = new UmbContextToken( 'UmbWorkspaceContext', 'example.workspaceContext.counter', ); diff --git a/src/Umbraco.Web.UI.Client/package-lock.json b/src/Umbraco.Web.UI.Client/package-lock.json index c593472c44..60ce722350 100644 --- a/src/Umbraco.Web.UI.Client/package-lock.json +++ b/src/Umbraco.Web.UI.Client/package-lock.json @@ -28,8 +28,8 @@ "@tiptap/pm": "2.11.5", "@tiptap/starter-kit": "2.11.5", "@types/diff": "^7.0.1", - "@umbraco-ui/uui": "1.13.0-rc.2", - "@umbraco-ui/uui-css": "1.13.0-rc.2", + "@umbraco-ui/uui": "^1.13.0", + "@umbraco-ui/uui-css": "^1.13.0", "diff": "^7.0.0", "dompurify": "^3.2.4", "element-internals-polyfill": "^1.3.13", @@ -4455,908 +4455,824 @@ "link": true }, "node_modules/@umbraco-ui/uui": { - "version": "1.13.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui/-/uui-1.13.0-rc.2.tgz", - "integrity": "sha512-b5iIPr6wZ0/op4YZC0mhs12HlBw6GdE/oW8NFMDBClfm/yX8ImuOiFc7VmcrpL1bQ3sq643FOAyYE7A2+m82Tw==", - "license": "MIT", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui/-/uui-1.13.0.tgz", + "integrity": "sha512-O/RvFeW+Mjn24ckmWJeTzMZKYbVrnaHscl9zKGKkMSva3j3mnJs/Q9N6BfihQy3qdZP5ED+2lGomezxfoLjZ7g==", "dependencies": { - "@umbraco-ui/uui-action-bar": "1.13.0-rc.2", - "@umbraco-ui/uui-avatar": "1.13.0-rc.2", - "@umbraco-ui/uui-avatar-group": "1.13.0-rc.2", - "@umbraco-ui/uui-badge": "1.13.0-rc.2", - "@umbraco-ui/uui-base": "1.13.0-rc.2", - "@umbraco-ui/uui-boolean-input": "1.13.0-rc.2", - "@umbraco-ui/uui-box": "1.13.0-rc.2", - "@umbraco-ui/uui-breadcrumbs": "1.13.0-rc.2", - "@umbraco-ui/uui-button": "1.13.0-rc.2", - "@umbraco-ui/uui-button-copy-text": "1.13.0-rc.2", - "@umbraco-ui/uui-button-group": "1.13.0-rc.2", - "@umbraco-ui/uui-button-inline-create": "1.13.0-rc.2", - "@umbraco-ui/uui-card": "1.13.0-rc.2", - "@umbraco-ui/uui-card-block-type": "1.13.0-rc.2", - "@umbraco-ui/uui-card-content-node": "1.13.0-rc.2", - "@umbraco-ui/uui-card-media": "1.13.0-rc.2", - "@umbraco-ui/uui-card-user": "1.13.0-rc.2", - "@umbraco-ui/uui-caret": "1.13.0-rc.2", - "@umbraco-ui/uui-checkbox": "1.13.0-rc.2", - "@umbraco-ui/uui-color-area": "1.13.0-rc.2", - "@umbraco-ui/uui-color-picker": "1.13.0-rc.2", - "@umbraco-ui/uui-color-slider": "1.13.0-rc.2", - "@umbraco-ui/uui-color-swatch": "1.13.0-rc.2", - "@umbraco-ui/uui-color-swatches": "1.13.0-rc.2", - "@umbraco-ui/uui-combobox": "1.13.0-rc.2", - "@umbraco-ui/uui-combobox-list": "1.13.0-rc.2", - "@umbraco-ui/uui-css": "1.13.0-rc.2", - "@umbraco-ui/uui-dialog": "1.13.0-rc.2", - "@umbraco-ui/uui-dialog-layout": "1.13.0-rc.2", - "@umbraco-ui/uui-file-dropzone": "1.13.0-rc.2", - "@umbraco-ui/uui-file-preview": "1.13.0-rc.2", - "@umbraco-ui/uui-form": "1.13.0-rc.2", - "@umbraco-ui/uui-form-layout-item": "1.13.0-rc.2", - "@umbraco-ui/uui-form-validation-message": "1.13.0-rc.2", - "@umbraco-ui/uui-icon": "1.13.0-rc.2", - "@umbraco-ui/uui-icon-registry": "1.13.0-rc.2", - "@umbraco-ui/uui-icon-registry-essential": "1.13.0-rc.2", - "@umbraco-ui/uui-input": "1.13.0-rc.2", - "@umbraco-ui/uui-input-file": "1.13.0-rc.2", - "@umbraco-ui/uui-input-lock": "1.13.0-rc.2", - "@umbraco-ui/uui-input-password": "1.13.0-rc.2", - "@umbraco-ui/uui-keyboard-shortcut": "1.13.0-rc.2", - "@umbraco-ui/uui-label": "1.13.0-rc.2", - "@umbraco-ui/uui-loader": "1.13.0-rc.2", - "@umbraco-ui/uui-loader-bar": "1.13.0-rc.2", - "@umbraco-ui/uui-loader-circle": "1.13.0-rc.2", - "@umbraco-ui/uui-menu-item": "1.13.0-rc.2", - "@umbraco-ui/uui-modal": "1.13.0-rc.2", - "@umbraco-ui/uui-pagination": "1.13.0-rc.2", - "@umbraco-ui/uui-popover": "1.13.0-rc.2", - "@umbraco-ui/uui-popover-container": "1.13.0-rc.2", - "@umbraco-ui/uui-progress-bar": "1.13.0-rc.2", - "@umbraco-ui/uui-radio": "1.13.0-rc.2", - "@umbraco-ui/uui-range-slider": "1.13.0-rc.2", - "@umbraco-ui/uui-ref": "1.13.0-rc.2", - "@umbraco-ui/uui-ref-list": "1.13.0-rc.2", - "@umbraco-ui/uui-ref-node": "1.13.0-rc.2", - "@umbraco-ui/uui-ref-node-data-type": "1.13.0-rc.2", - "@umbraco-ui/uui-ref-node-document-type": "1.13.0-rc.2", - "@umbraco-ui/uui-ref-node-form": "1.13.0-rc.2", - "@umbraco-ui/uui-ref-node-member": "1.13.0-rc.2", - "@umbraco-ui/uui-ref-node-package": "1.13.0-rc.2", - "@umbraco-ui/uui-ref-node-user": "1.13.0-rc.2", - "@umbraco-ui/uui-scroll-container": "1.13.0-rc.2", - "@umbraco-ui/uui-select": "1.13.0-rc.2", - "@umbraco-ui/uui-slider": "1.13.0-rc.2", - "@umbraco-ui/uui-symbol-expand": "1.13.0-rc.2", - "@umbraco-ui/uui-symbol-file": "1.13.0-rc.2", - "@umbraco-ui/uui-symbol-file-dropzone": "1.13.0-rc.2", - "@umbraco-ui/uui-symbol-file-thumbnail": "1.13.0-rc.2", - "@umbraco-ui/uui-symbol-folder": "1.13.0-rc.2", - "@umbraco-ui/uui-symbol-lock": "1.13.0-rc.2", - "@umbraco-ui/uui-symbol-more": "1.13.0-rc.2", - "@umbraco-ui/uui-symbol-sort": "1.13.0-rc.2", - "@umbraco-ui/uui-table": "1.13.0-rc.2", - "@umbraco-ui/uui-tabs": "1.13.0-rc.2", - "@umbraco-ui/uui-tag": "1.13.0-rc.2", - "@umbraco-ui/uui-textarea": "1.13.0-rc.2", - "@umbraco-ui/uui-toast-notification": "1.13.0-rc.2", - "@umbraco-ui/uui-toast-notification-container": "1.13.0-rc.2", - "@umbraco-ui/uui-toast-notification-layout": "1.13.0-rc.2", - "@umbraco-ui/uui-toggle": "1.13.0-rc.2", - "@umbraco-ui/uui-visually-hidden": "1.13.0-rc.2" + "@umbraco-ui/uui-action-bar": "1.13.0", + "@umbraco-ui/uui-avatar": "1.13.0", + "@umbraco-ui/uui-avatar-group": "1.13.0", + "@umbraco-ui/uui-badge": "1.13.0", + "@umbraco-ui/uui-base": "1.13.0", + "@umbraco-ui/uui-boolean-input": "1.13.0", + "@umbraco-ui/uui-box": "1.13.0", + "@umbraco-ui/uui-breadcrumbs": "1.13.0", + "@umbraco-ui/uui-button": "1.13.0", + "@umbraco-ui/uui-button-copy-text": "1.13.0", + "@umbraco-ui/uui-button-group": "1.13.0", + "@umbraco-ui/uui-button-inline-create": "1.13.0", + "@umbraco-ui/uui-card": "1.13.0", + "@umbraco-ui/uui-card-block-type": "1.13.0", + "@umbraco-ui/uui-card-content-node": "1.13.0", + "@umbraco-ui/uui-card-media": "1.13.0", + "@umbraco-ui/uui-card-user": "1.13.0", + "@umbraco-ui/uui-caret": "1.13.0", + "@umbraco-ui/uui-checkbox": "1.13.0", + "@umbraco-ui/uui-color-area": "1.13.0", + "@umbraco-ui/uui-color-picker": "1.13.0", + "@umbraco-ui/uui-color-slider": "1.13.0", + "@umbraco-ui/uui-color-swatch": "1.13.0", + "@umbraco-ui/uui-color-swatches": "1.13.0", + "@umbraco-ui/uui-combobox": "1.13.0", + "@umbraco-ui/uui-combobox-list": "1.13.0", + "@umbraco-ui/uui-css": "1.13.0", + "@umbraco-ui/uui-dialog": "1.13.0", + "@umbraco-ui/uui-dialog-layout": "1.13.0", + "@umbraco-ui/uui-file-dropzone": "1.13.0", + "@umbraco-ui/uui-file-preview": "1.13.0", + "@umbraco-ui/uui-form": "1.13.0", + "@umbraco-ui/uui-form-layout-item": "1.13.0", + "@umbraco-ui/uui-form-validation-message": "1.13.0", + "@umbraco-ui/uui-icon": "1.13.0", + "@umbraco-ui/uui-icon-registry": "1.13.0", + "@umbraco-ui/uui-icon-registry-essential": "1.13.0", + "@umbraco-ui/uui-input": "1.13.0", + "@umbraco-ui/uui-input-file": "1.13.0", + "@umbraco-ui/uui-input-lock": "1.13.0", + "@umbraco-ui/uui-input-password": "1.13.0", + "@umbraco-ui/uui-keyboard-shortcut": "1.13.0", + "@umbraco-ui/uui-label": "1.13.0", + "@umbraco-ui/uui-loader": "1.13.0", + "@umbraco-ui/uui-loader-bar": "1.13.0", + "@umbraco-ui/uui-loader-circle": "1.13.0", + "@umbraco-ui/uui-menu-item": "1.13.0", + "@umbraco-ui/uui-modal": "1.13.0", + "@umbraco-ui/uui-pagination": "1.13.0", + "@umbraco-ui/uui-popover": "1.13.0", + "@umbraco-ui/uui-popover-container": "1.13.0", + "@umbraco-ui/uui-progress-bar": "1.13.0", + "@umbraco-ui/uui-radio": "1.13.0", + "@umbraco-ui/uui-range-slider": "1.13.0", + "@umbraco-ui/uui-ref": "1.13.0", + "@umbraco-ui/uui-ref-list": "1.13.0", + "@umbraco-ui/uui-ref-node": "1.13.0", + "@umbraco-ui/uui-ref-node-data-type": "1.13.0", + "@umbraco-ui/uui-ref-node-document-type": "1.13.0", + "@umbraco-ui/uui-ref-node-form": "1.13.0", + "@umbraco-ui/uui-ref-node-member": "1.13.0", + "@umbraco-ui/uui-ref-node-package": "1.13.0", + "@umbraco-ui/uui-ref-node-user": "1.13.0", + "@umbraco-ui/uui-scroll-container": "1.13.0", + "@umbraco-ui/uui-select": "1.13.0", + "@umbraco-ui/uui-slider": "1.13.0", + "@umbraco-ui/uui-symbol-expand": "1.13.0", + "@umbraco-ui/uui-symbol-file": "1.13.0", + "@umbraco-ui/uui-symbol-file-dropzone": "1.13.0", + "@umbraco-ui/uui-symbol-file-thumbnail": "1.13.0", + "@umbraco-ui/uui-symbol-folder": "1.13.0", + "@umbraco-ui/uui-symbol-lock": "1.13.0", + "@umbraco-ui/uui-symbol-more": "1.13.0", + "@umbraco-ui/uui-symbol-sort": "1.13.0", + "@umbraco-ui/uui-table": "1.13.0", + "@umbraco-ui/uui-tabs": "1.13.0", + "@umbraco-ui/uui-tag": "1.13.0", + "@umbraco-ui/uui-textarea": "1.13.0", + "@umbraco-ui/uui-toast-notification": "1.13.0", + "@umbraco-ui/uui-toast-notification-container": "1.13.0", + "@umbraco-ui/uui-toast-notification-layout": "1.13.0", + "@umbraco-ui/uui-toggle": "1.13.0", + "@umbraco-ui/uui-visually-hidden": "1.13.0" } }, "node_modules/@umbraco-ui/uui-action-bar": { - "version": "1.13.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-action-bar/-/uui-action-bar-1.13.0-rc.2.tgz", - "integrity": "sha512-o9itNsWQdN0fIn+8W3bNwPEV/IVb4sjW0NFBmL3sa6TOgiHHPyH4/A73xjNy5zexeH0VbNb8IJCgKXv4hpSgCw==", - "license": "MIT", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-action-bar/-/uui-action-bar-1.13.0.tgz", + "integrity": "sha512-0AGQ1zsUZT1wHKx+01JkRKLNtpjCS/SqEy/NVHUyYIGPimr6NQDM9Ok00LZKpZVwxcvArdy38XaAz6SijlaTqg==", "dependencies": { - "@umbraco-ui/uui-base": "1.13.0-rc.2", - "@umbraco-ui/uui-button-group": "1.13.0-rc.2" + "@umbraco-ui/uui-base": "1.13.0", + "@umbraco-ui/uui-button-group": "1.13.0" } }, "node_modules/@umbraco-ui/uui-avatar": { - "version": "1.13.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-avatar/-/uui-avatar-1.13.0-rc.2.tgz", - "integrity": "sha512-msdEZLVKwKqC+pD1ymVcs1NKQKvloCx+Og5UnIg5J/KlOnvhrII1BqW99tp1hjcrh6/l+FecbNq1oCZOyYYyUw==", - "license": "MIT", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-avatar/-/uui-avatar-1.13.0.tgz", + "integrity": "sha512-w+DwB9PUcnR0y0CzeNQA2638PjF2Dswiyuoxa2ryggcy38ihypj0Fj8FpzRSe5rax2JMtpJnuoDPwUpqVwGfOQ==", "dependencies": { - "@umbraco-ui/uui-base": "1.13.0-rc.2" + "@umbraco-ui/uui-base": "1.13.0" } }, "node_modules/@umbraco-ui/uui-avatar-group": { - "version": "1.13.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-avatar-group/-/uui-avatar-group-1.13.0-rc.2.tgz", - "integrity": "sha512-jUbDvaa6+fQ2T5JQKQh8L599pP/xD6uDj8ARlFVdPxVAjQ61ayqAgp/2JulUrdg3rcE+w7p2g5pXXMEUBjYIIQ==", - "license": "MIT", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-avatar-group/-/uui-avatar-group-1.13.0.tgz", + "integrity": "sha512-G8lIknUuhy+swW9Xz7qN3fp0L5Xhx4d5C2Q9WbW316GeseLYCm2eRhXDLpiEzIMxoVYtA9P0gbkuxLFDkznc+Q==", "dependencies": { - "@umbraco-ui/uui-avatar": "1.13.0-rc.2", - "@umbraco-ui/uui-base": "1.13.0-rc.2" + "@umbraco-ui/uui-avatar": "1.13.0", + "@umbraco-ui/uui-base": "1.13.0" } }, "node_modules/@umbraco-ui/uui-badge": { - "version": "1.13.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-badge/-/uui-badge-1.13.0-rc.2.tgz", - "integrity": "sha512-t9Rturd0/eQkJ6t6GFPsSpuGmlwTJYHOeCEy4lDjwRumNGWXnPTlULrxeSsQPvPyNuFoa69kgTeL1xd2fn/fRg==", - "license": "MIT", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-badge/-/uui-badge-1.13.0.tgz", + "integrity": "sha512-z7Z5IZwcfFJDFIPnBDfuCv+YkBHafn15oi4rNmNVynaM/iFJ+W3NAE7EmdWMDZzuDeQngbFpoRx1Ub7I4mqsng==", "dependencies": { - "@umbraco-ui/uui-base": "1.13.0-rc.2" + "@umbraco-ui/uui-base": "1.13.0" } }, "node_modules/@umbraco-ui/uui-base": { - "version": "1.13.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-base/-/uui-base-1.13.0-rc.2.tgz", - "integrity": "sha512-+bMilDGWT0LhH2hCQn0rImT1pECncl3sF4iBKGZ7IJyxaQ80v571f+gsMAJzkxb0ClsDQUQQ/MZyFxymSG6twA==", - "license": "MIT", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-base/-/uui-base-1.13.0.tgz", + "integrity": "sha512-VG0xlVzuq74qKaWn+eaTcTblR6HCi9YyrNohLLhHVAJuelmcgoPwHdNzkjoaWXlq16XKnB5Kmb6BgEtVmSQZ5w==", "peerDependencies": { "lit": ">=2.8.0" } }, "node_modules/@umbraco-ui/uui-boolean-input": { - "version": "1.13.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-boolean-input/-/uui-boolean-input-1.13.0-rc.2.tgz", - "integrity": "sha512-UlK7V2LZJQA5MpfJWDlpxTaD1JVu3mmu7P33yj9arWgjvTUcIu6RVUMbOoie3BhOdUe3ryZdQXdMNtTBp8X55w==", - "license": "MIT", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-boolean-input/-/uui-boolean-input-1.13.0.tgz", + "integrity": "sha512-WsP+W5/4Fcp9sg0gFlfh8FyIzaczRC4kc2LxT3haljflgQTMVwV4MGGadOYg89hVpD0C4dZaqp69sskLWc6fWQ==", "dependencies": { - "@umbraco-ui/uui-base": "1.13.0-rc.2" + "@umbraco-ui/uui-base": "1.13.0" } }, "node_modules/@umbraco-ui/uui-box": { - "version": "1.13.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-box/-/uui-box-1.13.0-rc.2.tgz", - "integrity": "sha512-fleYkQ+EhkSJFXZTYn9k4qfScbm3aNbnkZWkKMIHamvGk29ocI+0tE75QC4w8rtbvtIzIJrRKV8Rx9aHN4R22g==", - "license": "MIT", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-box/-/uui-box-1.13.0.tgz", + "integrity": "sha512-msIz5NerPKx7bnTyEyMjihnfxSTlslU+FyE4DsUUwZT6vtFxT2Dt74UbO8cg0ut9GoBjR1wpn4qNTW3xRxfdiA==", "dependencies": { - "@umbraco-ui/uui-base": "1.13.0-rc.2", - "@umbraco-ui/uui-css": "1.13.0-rc.2" + "@umbraco-ui/uui-base": "1.13.0", + "@umbraco-ui/uui-css": "1.13.0" } }, "node_modules/@umbraco-ui/uui-breadcrumbs": { - "version": "1.13.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-breadcrumbs/-/uui-breadcrumbs-1.13.0-rc.2.tgz", - "integrity": "sha512-ih0h9CvkF7qCXC3pi3xxCMBAN5cyYUAaa644DcyNXb4mNsP7MDuKcMnLiXf3kgkoboebKhWyWhnM99fg/+p46g==", - "license": "MIT", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-breadcrumbs/-/uui-breadcrumbs-1.13.0.tgz", + "integrity": "sha512-DG/m4bZ3bPTryrN6mDQMmabXPmvKcVlsfjuhJ/UDazq6T/4DVfB6YrXk6q+4N6X4njg88CO/V6ObnyB7RE+flQ==", "dependencies": { - "@umbraco-ui/uui-base": "1.13.0-rc.2" + "@umbraco-ui/uui-base": "1.13.0" } }, "node_modules/@umbraco-ui/uui-button": { - "version": "1.13.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-button/-/uui-button-1.13.0-rc.2.tgz", - "integrity": "sha512-gG4aoIwddJsltcopHr3ZB8t0/DiSFbP++Jo4QMtMRvgxOZ72AgWtSGXNHlPIHhtyt6EhXJH5tPdztRlz8x1mZA==", - "license": "MIT", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-button/-/uui-button-1.13.0.tgz", + "integrity": "sha512-dJWr9fKQFB4CRMJ23oRmkuzN45ESuxDn1nwgLw0TLhJrAWo5uoyTL1k/IuNdg0C3+BqNIzC5B8m5YC2S+BpPlA==", "dependencies": { - "@umbraco-ui/uui-base": "1.13.0-rc.2", - "@umbraco-ui/uui-icon-registry-essential": "1.13.0-rc.2" + "@umbraco-ui/uui-base": "1.13.0", + "@umbraco-ui/uui-icon-registry-essential": "1.13.0" } }, "node_modules/@umbraco-ui/uui-button-copy-text": { - "version": "1.13.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-button-copy-text/-/uui-button-copy-text-1.13.0-rc.2.tgz", - "integrity": "sha512-948Vy0bEpBVu+9Z5BH+fNTlG0yDiOPbg2e2zywmfB1RMkndyj7h1pCrnq51ZcyK7W0oma4eQpOoy0S2vzTJmcw==", - "license": "MIT", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-button-copy-text/-/uui-button-copy-text-1.13.0.tgz", + "integrity": "sha512-/4j4PnxNRAyeD2LYA+dyyCZurOPnGioQfl2iFIE/B2znBvJR2JHrnCLwcAqawI+YhHxGgyKNck7BCKihYQxkow==", "dependencies": { - "@umbraco-ui/uui-base": "1.13.0-rc.2", - "@umbraco-ui/uui-button": "1.13.0-rc.2" + "@umbraco-ui/uui-base": "1.13.0", + "@umbraco-ui/uui-button": "1.13.0" } }, "node_modules/@umbraco-ui/uui-button-group": { - "version": "1.13.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-button-group/-/uui-button-group-1.13.0-rc.2.tgz", - "integrity": "sha512-I31TdnsrkXX8yZybKF6uhZI5byBYkC+OhFv4/93PvcdMNZ7ObENUzhnkd205WmfSyp/JnWSK0x18StBhDeXtkA==", - "license": "MIT", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-button-group/-/uui-button-group-1.13.0.tgz", + "integrity": "sha512-Pksx35rtKriOUO9IP1ETnQDoBnoiRzwheM8fmqeo44jSPsr7emaQrI3BOwqeOuD7KfPRIVnzwLdm14K4Zw6tZA==", "dependencies": { - "@umbraco-ui/uui-base": "1.13.0-rc.2" + "@umbraco-ui/uui-base": "1.13.0" } }, "node_modules/@umbraco-ui/uui-button-inline-create": { - "version": "1.13.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-button-inline-create/-/uui-button-inline-create-1.13.0-rc.2.tgz", - "integrity": "sha512-HzoKX835wYiDup2EQ6ufVN4dJKyJx5slFHjto1abPpVLfp90OXs+68AJRhNm93VcQB/cnXCzlnPAf0v/hgsCsQ==", - "license": "MIT", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-button-inline-create/-/uui-button-inline-create-1.13.0.tgz", + "integrity": "sha512-6XtJ/nZpVDkYFiWEqbr5uz5CJ2Yqled4W7zAsh53QuCCYFgyU6yU9AFtrhPRwC9I27XzmBTQRZgCkQFWuEuL5A==", "dependencies": { - "@umbraco-ui/uui-base": "1.13.0-rc.2" + "@umbraco-ui/uui-base": "1.13.0" } }, "node_modules/@umbraco-ui/uui-card": { - "version": "1.13.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-card/-/uui-card-1.13.0-rc.2.tgz", - "integrity": "sha512-yLezCU19XxniXBC4vZCPG5HnSi47SjipRIsFXF55GUjGokJ9ISLDnU6DLfHTPF7BNV2EXBUXlIN2Pznf4J44gg==", - "license": "MIT", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-card/-/uui-card-1.13.0.tgz", + "integrity": "sha512-fBskLWqFoquKfgFK6bJ4lM0V30XZCZcJjjwTUmSjRFvklyF3csL7W9bKB9hs+aFu0/GDQlVqOBa5tA4RLpcj0w==", "dependencies": { - "@umbraco-ui/uui-base": "1.13.0-rc.2" + "@umbraco-ui/uui-base": "1.13.0" } }, "node_modules/@umbraco-ui/uui-card-block-type": { - "version": "1.13.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-card-block-type/-/uui-card-block-type-1.13.0-rc.2.tgz", - "integrity": "sha512-PqrtLkTSRcsDi/99xFngcjOfcuEUdjKydG5nR0vchPpIoQjyvYOjk27gTTBB9u5Ee7hNNOBkUtgSnkl3V7bNRQ==", - "license": "MIT", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-card-block-type/-/uui-card-block-type-1.13.0.tgz", + "integrity": "sha512-YBDHZ+76oz27+P9v8YSr3OwWs3eftqy2d3Gg/sxh3Y6n9gI2TdXtJgev9GVL2FpifZXM2A1ySzh8MscC2HLJIA==", "dependencies": { - "@umbraco-ui/uui-base": "1.13.0-rc.2", - "@umbraco-ui/uui-card": "1.13.0-rc.2" + "@umbraco-ui/uui-base": "1.13.0", + "@umbraco-ui/uui-card": "1.13.0" } }, "node_modules/@umbraco-ui/uui-card-content-node": { - "version": "1.13.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-card-content-node/-/uui-card-content-node-1.13.0-rc.2.tgz", - "integrity": "sha512-WLstvJBGk9s0qqsQKyPopet0Kj4JefYcPUoxTKPMdXlCXkvvyQvGG2ZQCKPhz+TOTodDceGbh3XpnpYMDA87Wg==", - "license": "MIT", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-card-content-node/-/uui-card-content-node-1.13.0.tgz", + "integrity": "sha512-IYe/AUaJ7Pspd+zSQlJMRIUzzF7+dLnq6ApezC9b93mEEhB4WwX+BbzfHbbhyNxMv9Za9gBKZljIH3RluPWnog==", "dependencies": { - "@umbraco-ui/uui-base": "1.13.0-rc.2", - "@umbraco-ui/uui-card": "1.13.0-rc.2", - "@umbraco-ui/uui-icon": "1.13.0-rc.2" + "@umbraco-ui/uui-base": "1.13.0", + "@umbraco-ui/uui-card": "1.13.0", + "@umbraco-ui/uui-icon": "1.13.0" } }, "node_modules/@umbraco-ui/uui-card-media": { - "version": "1.13.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-card-media/-/uui-card-media-1.13.0-rc.2.tgz", - "integrity": "sha512-EaJ2ZxwhfW0lKHNP+k35rMHOXqVCwRacy/RL604d5Ch1e+V6Wc2t8tWyzEwBuUkPqEALdMH4qBq5U08u3/MZkQ==", - "license": "MIT", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-card-media/-/uui-card-media-1.13.0.tgz", + "integrity": "sha512-ohRFE1FqmYNJ7VXKjzMqjhCfzfabL9bLOpJet0+VXCMHUomHZv9UHQTI1ibp71BMp934vWT3kqGgco6RYqujSQ==", "dependencies": { - "@umbraco-ui/uui-base": "1.13.0-rc.2", - "@umbraco-ui/uui-card": "1.13.0-rc.2", - "@umbraco-ui/uui-symbol-file": "1.13.0-rc.2", - "@umbraco-ui/uui-symbol-folder": "1.13.0-rc.2" + "@umbraco-ui/uui-base": "1.13.0", + "@umbraco-ui/uui-card": "1.13.0", + "@umbraco-ui/uui-symbol-file": "1.13.0", + "@umbraco-ui/uui-symbol-folder": "1.13.0" } }, "node_modules/@umbraco-ui/uui-card-user": { - "version": "1.13.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-card-user/-/uui-card-user-1.13.0-rc.2.tgz", - "integrity": "sha512-L0hR1TM2eFJnY4Q129J/X2Qn/o8ZXYvpDTKFivWocRLEHiEfVzzMycZuZMgZBZwePTVx3x4COizy44YoCmfWPg==", - "license": "MIT", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-card-user/-/uui-card-user-1.13.0.tgz", + "integrity": "sha512-lAB2IuXvNK8l/n+D9s9cNNUUvBdZE2Uy3UDc0QJla3qo2RLsyM4pSgVeS0Ve+GOI1A4vyK8Sfx68cDptW04Vaw==", "dependencies": { - "@umbraco-ui/uui-avatar": "1.13.0-rc.2", - "@umbraco-ui/uui-base": "1.13.0-rc.2", - "@umbraco-ui/uui-card": "1.13.0-rc.2" + "@umbraco-ui/uui-avatar": "1.13.0", + "@umbraco-ui/uui-base": "1.13.0", + "@umbraco-ui/uui-card": "1.13.0" } }, "node_modules/@umbraco-ui/uui-caret": { - "version": "1.13.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-caret/-/uui-caret-1.13.0-rc.2.tgz", - "integrity": "sha512-4o09l3848epNm5w2ZN0fs6pd+24hHvGB+BLyDLt0i2u8jqQmnqbR0Cx1KjttkHfmJw9t0e88kWVZTDl5m6fMgw==", - "license": "MIT", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-caret/-/uui-caret-1.13.0.tgz", + "integrity": "sha512-OCrJISFcRvB6V1+xPS+AjGEp+ue3vyegTRJsLEOVbyCHbrzFwNUKLc2EFYz2rxOGjcFs7Z9M8I6eoLUuMxDQAQ==", "dependencies": { - "@umbraco-ui/uui-base": "1.13.0-rc.2" + "@umbraco-ui/uui-base": "1.13.0" } }, "node_modules/@umbraco-ui/uui-checkbox": { - "version": "1.13.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-checkbox/-/uui-checkbox-1.13.0-rc.2.tgz", - "integrity": "sha512-6GvzgVSAm+A7peb4ay4rS2RBtDJKDH19l2TdTrOR/C/buIVBZr73a9KX4JaU54JQV67GJIs+sbjQr2YbCdFhaQ==", - "license": "MIT", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-checkbox/-/uui-checkbox-1.13.0.tgz", + "integrity": "sha512-9ywXUZgC8kMLEgsx1JFH0iftSeI8zzVDVECYq36+dVuz0iWtXfUjb5ygSoUX0guiACVY5gNba/H+t9R+3FbUgw==", "dependencies": { - "@umbraco-ui/uui-base": "1.13.0-rc.2", - "@umbraco-ui/uui-boolean-input": "1.13.0-rc.2", - "@umbraco-ui/uui-icon-registry-essential": "1.13.0-rc.2" + "@umbraco-ui/uui-base": "1.13.0", + "@umbraco-ui/uui-boolean-input": "1.13.0", + "@umbraco-ui/uui-icon-registry-essential": "1.13.0" } }, "node_modules/@umbraco-ui/uui-color-area": { - "version": "1.13.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-area/-/uui-color-area-1.13.0-rc.2.tgz", - "integrity": "sha512-BZ0b2kkl6N1uuS4kejXM2qc2Vw4T+JEGZVLvEiJzowgKmiMsfRyAXlw3/vlwep+mFpOO66PLHAznF4FoWN90cw==", - "license": "MIT", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-area/-/uui-color-area-1.13.0.tgz", + "integrity": "sha512-X7CyxicQYE5VR5iXSY0IsPym0pSYWFLQ9KDgzVIDM3fvoM+KpiGYrDhGTgrHrTpJ3EE8JO06fPrx/mJ2NyxOyQ==", "dependencies": { - "@umbraco-ui/uui-base": "1.13.0-rc.2", + "@umbraco-ui/uui-base": "1.13.0", "colord": "^2.9.3" } }, "node_modules/@umbraco-ui/uui-color-picker": { - "version": "1.13.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-picker/-/uui-color-picker-1.13.0-rc.2.tgz", - "integrity": "sha512-UKpu9ErjjhdBjkIHuelP9loQDQ0PBvpC5GuqObBhkfggvPe4Aep2bO/Jp+c3QzOhX/Z7E0ZN3gVx/nHc9dyuwg==", - "license": "MIT", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-picker/-/uui-color-picker-1.13.0.tgz", + "integrity": "sha512-ROkz+5+ecZ9GbctpaynL9CeMdXhamY2wPfwjVHyp/QERLXsvhlXIojD0n11Fp4i9FzQsiHb328T5aTnBZ3tqcw==", "dependencies": { - "@umbraco-ui/uui-base": "1.13.0-rc.2", - "@umbraco-ui/uui-popover-container": "1.13.0-rc.2", + "@umbraco-ui/uui-base": "1.13.0", + "@umbraco-ui/uui-popover-container": "1.13.0", "colord": "^2.9.3" } }, "node_modules/@umbraco-ui/uui-color-slider": { - "version": "1.13.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-slider/-/uui-color-slider-1.13.0-rc.2.tgz", - "integrity": "sha512-MoqWEwY8obkfMTJeh7DUJxSsQbKpADyXXg3q6itzDPbn5jssaeBTmm26M3x6WLHOmraU2HkKxjVjtk6OjP1AqQ==", - "license": "MIT", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-slider/-/uui-color-slider-1.13.0.tgz", + "integrity": "sha512-om/OwXDVDNsy0HZIuIv6VXoi5aFBU7KtHfiq7/OLnnWtO5MQREwBCTVthhSFfe7LaZSZnFhFn89hrmw7hfhljQ==", "dependencies": { - "@umbraco-ui/uui-base": "1.13.0-rc.2" + "@umbraco-ui/uui-base": "1.13.0" } }, "node_modules/@umbraco-ui/uui-color-swatch": { - "version": "1.13.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-swatch/-/uui-color-swatch-1.13.0-rc.2.tgz", - "integrity": "sha512-tUzIQoK5iqmTHbubefV1RNdecWCbiF/ru+gZE4Txy9Y4MaE7uyYSBKdeUS7Ch89QfUVA/Of78ESiJLj3wmx0QA==", - "license": "MIT", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-swatch/-/uui-color-swatch-1.13.0.tgz", + "integrity": "sha512-tiT274ldYjDMFeBQBx3yGu7HgYaNrxjNIrcktlsddfWxxjJ3UNu08YdoP4DqJOi6limQhadBllCBa9oyz4iOig==", "dependencies": { - "@umbraco-ui/uui-base": "1.13.0-rc.2", - "@umbraco-ui/uui-icon-registry-essential": "1.13.0-rc.2", + "@umbraco-ui/uui-base": "1.13.0", + "@umbraco-ui/uui-icon-registry-essential": "1.13.0", "colord": "^2.9.3" } }, "node_modules/@umbraco-ui/uui-color-swatches": { - "version": "1.13.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-swatches/-/uui-color-swatches-1.13.0-rc.2.tgz", - "integrity": "sha512-scBuY13syfletW1iMsWSzEUhugeporBe0kGivNZh1naKtjC0EtRvb8ThFi/YH5Xk0Zi1PgVWWB0vpnPDE5sGFg==", - "license": "MIT", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-swatches/-/uui-color-swatches-1.13.0.tgz", + "integrity": "sha512-DAZ9cAxIp+kGFeGteDCgt+Om0vcuacmjtT98N1meP/EkPgJf6y21o3y4oySeQMAhWXznr3DBxyHHKN1Jt3do8Q==", "dependencies": { - "@umbraco-ui/uui-base": "1.13.0-rc.2", - "@umbraco-ui/uui-color-swatch": "1.13.0-rc.2" + "@umbraco-ui/uui-base": "1.13.0", + "@umbraco-ui/uui-color-swatch": "1.13.0" } }, "node_modules/@umbraco-ui/uui-combobox": { - "version": "1.13.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-combobox/-/uui-combobox-1.13.0-rc.2.tgz", - "integrity": "sha512-IdcttSnL+OsZ9SjiEus+prAloAiVR7QLlAvtWcXxbbxTtPXUldfMYP00RL5mzXRNkTQycB3O13goI7rKEnwPeg==", - "license": "MIT", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-combobox/-/uui-combobox-1.13.0.tgz", + "integrity": "sha512-8lKmqQMQkh+yMA4iFonDLwpNf6EZ+pYXhJ2Xcum14WT6UI6BgiQvuM2nmRrkWhqA7Wx0tTAAdP5ILPAl5lENRQ==", "dependencies": { - "@umbraco-ui/uui-base": "1.13.0-rc.2", - "@umbraco-ui/uui-button": "1.13.0-rc.2", - "@umbraco-ui/uui-combobox-list": "1.13.0-rc.2", - "@umbraco-ui/uui-icon": "1.13.0-rc.2", - "@umbraco-ui/uui-popover-container": "1.13.0-rc.2", - "@umbraco-ui/uui-scroll-container": "1.13.0-rc.2", - "@umbraco-ui/uui-symbol-expand": "1.13.0-rc.2" + "@umbraco-ui/uui-base": "1.13.0", + "@umbraco-ui/uui-button": "1.13.0", + "@umbraco-ui/uui-combobox-list": "1.13.0", + "@umbraco-ui/uui-icon": "1.13.0", + "@umbraco-ui/uui-popover-container": "1.13.0", + "@umbraco-ui/uui-scroll-container": "1.13.0", + "@umbraco-ui/uui-symbol-expand": "1.13.0" } }, "node_modules/@umbraco-ui/uui-combobox-list": { - "version": "1.13.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-combobox-list/-/uui-combobox-list-1.13.0-rc.2.tgz", - "integrity": "sha512-YnwCSZ1GFD3tZeHAYqAsCRjIPc/bwltK4nGjaeUyqpSSz0asonDrxbvd/5b+IISqDhYnznGD7jGO0+8HJHmt7w==", - "license": "MIT", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-combobox-list/-/uui-combobox-list-1.13.0.tgz", + "integrity": "sha512-ZVRouGMb7VH5wD8a0kE1t71oUMD1gUvFdACPWTjunpgM0ZXk1wOGGtS3vsEaTAkbQ8gABPpsYnCaWBt0MR+RpA==", "dependencies": { - "@umbraco-ui/uui-base": "1.13.0-rc.2" + "@umbraco-ui/uui-base": "1.13.0" } }, "node_modules/@umbraco-ui/uui-css": { - "version": "1.13.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-css/-/uui-css-1.13.0-rc.2.tgz", - "integrity": "sha512-ny7Roxjr3Go02q6olVW4rkxBAa2hi/PoBi2D0mNOAU+XE2WoYWuCbxnObI9eAoud7L9aJvvFqEnOoQGE2/AGyA==", - "license": "MIT", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-css/-/uui-css-1.13.0.tgz", + "integrity": "sha512-6crDukueGm9t5CBU+d/icouGELQQIQsfi/qT7J6qISRZTvBjoT0FxUxUtpXsIQs1H0qgULhwx8PTKnfQ/AMZFA==", "peerDependencies": { "lit": ">=2.8.0" } }, "node_modules/@umbraco-ui/uui-dialog": { - "version": "1.13.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-dialog/-/uui-dialog-1.13.0-rc.2.tgz", - "integrity": "sha512-7cVVgdBnNPwedtLvRURfOO/WOgCygAL/UcPER1TpQIerB3j4NDITtvwn6VrUpJRIDpiqAGE9tiVCFMt/NNbzZA==", - "license": "MIT", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-dialog/-/uui-dialog-1.13.0.tgz", + "integrity": "sha512-RzePOwJrhBEYBZAwgvNkIro+cVirLxgaIGNFUgnvoWIovHJNOuSso65MtcGON3nvuQ4JxE8SIOTE/hwT04R7Ag==", "dependencies": { - "@umbraco-ui/uui-base": "1.13.0-rc.2", - "@umbraco-ui/uui-css": "1.13.0-rc.2" + "@umbraco-ui/uui-base": "1.13.0", + "@umbraco-ui/uui-css": "1.13.0" } }, "node_modules/@umbraco-ui/uui-dialog-layout": { - "version": "1.13.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-dialog-layout/-/uui-dialog-layout-1.13.0-rc.2.tgz", - "integrity": "sha512-c9KnMcSZ+YlsXLaN/tU/1wlh+hj45XtBWiIOHM8cCFkxe73ZMsNew8n7qaTHwDnxAgHn6zrjE9ba3gtsjbLlEg==", - "license": "MIT", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-dialog-layout/-/uui-dialog-layout-1.13.0.tgz", + "integrity": "sha512-m8eoCEz0dugWmqrmRw2vHae3k7oYjr53JiOkb8viCMh7veQo4EM0zqZgdCwADs1wES8woOX5zdttp9JtqYenRw==", "dependencies": { - "@umbraco-ui/uui-base": "1.13.0-rc.2" + "@umbraco-ui/uui-base": "1.13.0" } }, "node_modules/@umbraco-ui/uui-file-dropzone": { - "version": "1.13.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-file-dropzone/-/uui-file-dropzone-1.13.0-rc.2.tgz", - "integrity": "sha512-Yg8Vfg/KGUTeCxXBtLdunbERwQokIIdv4aF+6BUp7GFdmz/9KWrSipQg5dMV3I2mD+ArnspwBkwyGF8OEBJdzw==", - "license": "MIT", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-file-dropzone/-/uui-file-dropzone-1.13.0.tgz", + "integrity": "sha512-1TFkyeNB3qWWhgc7NYudxXOc3v0cBRuRpVYPA3xocfVkqCG2PgEc7ePW18CtUuuGntGwv0E0Oni2bfSLrqVmuQ==", "dependencies": { - "@umbraco-ui/uui-base": "1.13.0-rc.2", - "@umbraco-ui/uui-symbol-file-dropzone": "1.13.0-rc.2" + "@umbraco-ui/uui-base": "1.13.0", + "@umbraco-ui/uui-symbol-file-dropzone": "1.13.0" } }, "node_modules/@umbraco-ui/uui-file-preview": { - "version": "1.13.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-file-preview/-/uui-file-preview-1.13.0-rc.2.tgz", - "integrity": "sha512-xXpghwcVVTzN+XddoZ5tt0g5m9MRXisYg1CkiVOE1OGDgpph+LMlkSCNNAi4datNpMwtYWxmHoxBmVELVhkEOA==", - "license": "MIT", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-file-preview/-/uui-file-preview-1.13.0.tgz", + "integrity": "sha512-ZEW2q6If0+3WWHnQp9UPdL+rcI4zUKlyvELDU1JDzx/IVDFJb8f7fI5qhzQjl4kXCVI54Ch4WkBie6RDpNSqVg==", "dependencies": { - "@umbraco-ui/uui-base": "1.13.0-rc.2", - "@umbraco-ui/uui-symbol-file": "1.13.0-rc.2", - "@umbraco-ui/uui-symbol-file-thumbnail": "1.13.0-rc.2", - "@umbraco-ui/uui-symbol-folder": "1.13.0-rc.2" + "@umbraco-ui/uui-base": "1.13.0", + "@umbraco-ui/uui-symbol-file": "1.13.0", + "@umbraco-ui/uui-symbol-file-thumbnail": "1.13.0", + "@umbraco-ui/uui-symbol-folder": "1.13.0" } }, "node_modules/@umbraco-ui/uui-form": { - "version": "1.13.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-form/-/uui-form-1.13.0-rc.2.tgz", - "integrity": "sha512-Y68o0tynYhJFPQaKNbyYxuzApj62+5sUHB14b+y2S8Mn8TxYq1wvZF0dYHOKAZsO07se4YQj1xU961j/uiQUlA==", - "license": "MIT", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-form/-/uui-form-1.13.0.tgz", + "integrity": "sha512-Y5Wgl3AcixLbPHJJK2yqdga5NMHx5Jv3YvG69+AdPkgzyNmCtdbDitV8ex2ysNYMO3WbBRdYIjbI5pYRl3xn5Q==", "dependencies": { - "@umbraco-ui/uui-base": "1.13.0-rc.2" + "@umbraco-ui/uui-base": "1.13.0" } }, "node_modules/@umbraco-ui/uui-form-layout-item": { - "version": "1.13.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-form-layout-item/-/uui-form-layout-item-1.13.0-rc.2.tgz", - "integrity": "sha512-09onpcp/x+dx6wRKHSXe+LdrCaQrREah57KxFPOPOzdMOIWmHpg2Ork7TehjA+SRBrptVpKrlpkN44Ho2Q006w==", - "license": "MIT", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-form-layout-item/-/uui-form-layout-item-1.13.0.tgz", + "integrity": "sha512-GKNjsvUBbl2ba9e7b88Vk7HuMO9exnGDRpmQ94PSH/rOUF44ri4mPTPFU2k9DCvIkSs7lxDvotXE7kQ5IPQYBw==", "dependencies": { - "@umbraco-ui/uui-base": "1.13.0-rc.2", - "@umbraco-ui/uui-form-validation-message": "1.13.0-rc.2" + "@umbraco-ui/uui-base": "1.13.0", + "@umbraco-ui/uui-form-validation-message": "1.13.0" } }, "node_modules/@umbraco-ui/uui-form-validation-message": { - "version": "1.13.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-form-validation-message/-/uui-form-validation-message-1.13.0-rc.2.tgz", - "integrity": "sha512-mMg94awkBAIBJKYOKrWx7gMseAPF9hA5dPpYeYGM0hg1ZG2LYZOPCtfrXqNMkFr7l4CRpBOMZKsJtgnmLmkLLg==", - "license": "MIT", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-form-validation-message/-/uui-form-validation-message-1.13.0.tgz", + "integrity": "sha512-x1E84q6L8DbpBkoS+ykdvmoEUcObXYhym6nhh2lK2TAn7vZu+XD+Osd5rgy5ycZ4YtYnCqetlaPwQwAFqFiSHA==", "dependencies": { - "@umbraco-ui/uui-base": "1.13.0-rc.2" + "@umbraco-ui/uui-base": "1.13.0" } }, "node_modules/@umbraco-ui/uui-icon": { - "version": "1.13.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-icon/-/uui-icon-1.13.0-rc.2.tgz", - "integrity": "sha512-jAMFme59JZjWEgtT/xb6Y/ZtABi5m55lDRyxqZ23ob5iraIkNwQ7WEvtBA/FMy5t0JRDyDg3k1zDFJl8P+oWYA==", - "license": "MIT", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-icon/-/uui-icon-1.13.0.tgz", + "integrity": "sha512-TKmQi4n8ZV6v228U6zi9f38g/Nu4ok1cbvoIiSfSvmSYNXD1weuWK5y7Ph7EGr6jL5T5vKbDhjcZUIjzBOVWAA==", "dependencies": { - "@umbraco-ui/uui-base": "1.13.0-rc.2" + "@umbraco-ui/uui-base": "1.13.0" } }, "node_modules/@umbraco-ui/uui-icon-registry": { - "version": "1.13.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-icon-registry/-/uui-icon-registry-1.13.0-rc.2.tgz", - "integrity": "sha512-XdES9Wsgnka1E0mRvPIb2uFNM/I9mTNLof9ax+/Ia2NpKGS5PwlS/RAFLaLGGgCaupm6HdjwnEkTq+/f0SfGRg==", - "license": "MIT", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-icon-registry/-/uui-icon-registry-1.13.0.tgz", + "integrity": "sha512-/w7EN7Exi7ST0olPuxFLFm8rw3Mt2QhZsqQWQXXYnb4hTC+ot27IDahQmlLOx85+h/KH3Qz+Tn2NgM3BEdQQ5w==", "dependencies": { - "@umbraco-ui/uui-base": "1.13.0-rc.2", - "@umbraco-ui/uui-icon": "1.13.0-rc.2" + "@umbraco-ui/uui-base": "1.13.0", + "@umbraco-ui/uui-icon": "1.13.0" } }, "node_modules/@umbraco-ui/uui-icon-registry-essential": { - "version": "1.13.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-icon-registry-essential/-/uui-icon-registry-essential-1.13.0-rc.2.tgz", - "integrity": "sha512-HkuRPb2/5ybQYCsmF3M15gDmsnHIBdBijel8DDuNquiAjcU2/jT+uFAP5HaBOnR7Twu8agY/OFrzrnWAvteIvA==", - "license": "MIT", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-icon-registry-essential/-/uui-icon-registry-essential-1.13.0.tgz", + "integrity": "sha512-CcuBNg06ewGM6OhwjXCQKm5QDYXySCcc7TQajJ14kfMXtdcO8ls6eI2D8t+Hkc4YN7TQaUeGgzMF746f4TiiNQ==", "dependencies": { - "@umbraco-ui/uui-base": "1.13.0-rc.2", - "@umbraco-ui/uui-icon-registry": "1.13.0-rc.2" + "@umbraco-ui/uui-base": "1.13.0", + "@umbraco-ui/uui-icon-registry": "1.13.0" } }, "node_modules/@umbraco-ui/uui-input": { - "version": "1.13.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-input/-/uui-input-1.13.0-rc.2.tgz", - "integrity": "sha512-dydYwzCcMSKnzcJE5mt/e00QZMptXV/F8lWAOgcWv3eAJ7CldKAsMi4X27c43IFtO5c62hMZ5wtZOcXvud96bw==", - "license": "MIT", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-input/-/uui-input-1.13.0.tgz", + "integrity": "sha512-2GwLio1SDBofYLZjds47X6Fxq29ORgQBZaD9xwowFaoWCsG+WIFsE7VaE4KgPASUOQYoMMzFZX3F2TdvbjPEAg==", "dependencies": { - "@umbraco-ui/uui-base": "1.13.0-rc.2" + "@umbraco-ui/uui-base": "1.13.0" } }, "node_modules/@umbraco-ui/uui-input-file": { - "version": "1.13.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-input-file/-/uui-input-file-1.13.0-rc.2.tgz", - "integrity": "sha512-OJ30KIbNAqoJYxgy3E5QhJQ4yy76d50wUIIc5dsEfi3OJDk3eZueU4sdWmH4Izg3hKociOhbFDHLn19Yk7xA3g==", - "license": "MIT", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-input-file/-/uui-input-file-1.13.0.tgz", + "integrity": "sha512-wKmFAzThstZPeCOtNtdAX8SZ09T0mJQEA1g+l6EaCV5ikPLSO0kiqmv3P0p0IDf6WSX29+UhcSp2hOVzR+cELg==", "dependencies": { - "@umbraco-ui/uui-action-bar": "1.13.0-rc.2", - "@umbraco-ui/uui-base": "1.13.0-rc.2", - "@umbraco-ui/uui-button": "1.13.0-rc.2", - "@umbraco-ui/uui-file-dropzone": "1.13.0-rc.2", - "@umbraco-ui/uui-icon": "1.13.0-rc.2", - "@umbraco-ui/uui-icon-registry-essential": "1.13.0-rc.2" + "@umbraco-ui/uui-action-bar": "1.13.0", + "@umbraco-ui/uui-base": "1.13.0", + "@umbraco-ui/uui-button": "1.13.0", + "@umbraco-ui/uui-file-dropzone": "1.13.0", + "@umbraco-ui/uui-icon": "1.13.0", + "@umbraco-ui/uui-icon-registry-essential": "1.13.0" } }, "node_modules/@umbraco-ui/uui-input-lock": { - "version": "1.13.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-input-lock/-/uui-input-lock-1.13.0-rc.2.tgz", - "integrity": "sha512-Xg+j6rD76mx8uaKzOg7mMCodcODjn9aRBppfQejuY69D4azT+6zEIwEUGWKsGxjfrL/ebjJhHs0r02TICU0Mmg==", - "license": "MIT", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-input-lock/-/uui-input-lock-1.13.0.tgz", + "integrity": "sha512-qChhwO5NsA8es9X41HJ73sXtmvKUF90WBBL8PYgESLkL7zQdvhe9wfJhVjZ1WMJkOc6F7uTAJbawuEVXSX0uKA==", "dependencies": { - "@umbraco-ui/uui-base": "1.13.0-rc.2", - "@umbraco-ui/uui-button": "1.13.0-rc.2", - "@umbraco-ui/uui-icon": "1.13.0-rc.2", - "@umbraco-ui/uui-input": "1.13.0-rc.2" + "@umbraco-ui/uui-base": "1.13.0", + "@umbraco-ui/uui-button": "1.13.0", + "@umbraco-ui/uui-icon": "1.13.0", + "@umbraco-ui/uui-input": "1.13.0" } }, "node_modules/@umbraco-ui/uui-input-password": { - "version": "1.13.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-input-password/-/uui-input-password-1.13.0-rc.2.tgz", - "integrity": "sha512-hA63lzi03LhkXyhxtRRLW4WSNc1KtmUd8l9HUWB0V6Nae2a3HghrNr1LY8841jJGYnJb37et6BqADc1qES7jDg==", - "license": "MIT", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-input-password/-/uui-input-password-1.13.0.tgz", + "integrity": "sha512-1ljgXM1Ux2J73J2mNd01Xh1Bk7Por0MXk6fQ4TP/qp4A5ohF6CmiBVNWSBkWLfEY7TNHfvOIIIiDGfc0Ko0UFw==", "dependencies": { - "@umbraco-ui/uui-base": "1.13.0-rc.2", - "@umbraco-ui/uui-icon-registry-essential": "1.13.0-rc.2", - "@umbraco-ui/uui-input": "1.13.0-rc.2" + "@umbraco-ui/uui-base": "1.13.0", + "@umbraco-ui/uui-icon-registry-essential": "1.13.0", + "@umbraco-ui/uui-input": "1.13.0" } }, "node_modules/@umbraco-ui/uui-keyboard-shortcut": { - "version": "1.13.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-keyboard-shortcut/-/uui-keyboard-shortcut-1.13.0-rc.2.tgz", - "integrity": "sha512-9QQLwpiumqOEd/5xwkuexmxf6dqg8ON9vsCwf4kT22nGVQ+7tbU5hUt9Q/Mdme/ivcUZC/RAaLILnXVmGt3YZA==", - "license": "MIT", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-keyboard-shortcut/-/uui-keyboard-shortcut-1.13.0.tgz", + "integrity": "sha512-zKh674a19swyaZiLI/vCws56H4P+lUCIQxu+/U3280zGQqp35vCj0RhvbU2zA4QCCvTEWSrOOQwyu019zEEz5w==", "dependencies": { - "@umbraco-ui/uui-base": "1.13.0-rc.2" + "@umbraco-ui/uui-base": "1.13.0" } }, "node_modules/@umbraco-ui/uui-label": { - "version": "1.13.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-label/-/uui-label-1.13.0-rc.2.tgz", - "integrity": "sha512-CGGYEiQ4VIs0tkHFra0ECjDVypmxSLQ+Onta6iD25ttYknxTCMmU5b1hNWcTomIQ3kpj0loIEa0MWB0c4if/jw==", - "license": "MIT", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-label/-/uui-label-1.13.0.tgz", + "integrity": "sha512-BcfvqdFybY0Vb7TVinfHDLrAyhmtayz5ZGXwnTZpwyg7IP+pPZrFunrhcPPTPIrvJEw/j7qgpfC2AKMsiaZq7A==", "dependencies": { - "@umbraco-ui/uui-base": "1.13.0-rc.2" + "@umbraco-ui/uui-base": "1.13.0" } }, "node_modules/@umbraco-ui/uui-loader": { - "version": "1.13.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-loader/-/uui-loader-1.13.0-rc.2.tgz", - "integrity": "sha512-3em8IE/PwKZUJqGaeW9xvH9pPxbRyjevbqgHNDfYVp5BMMt+p8cdbtbr+4Izs3fYhH1xUkCjktAUVo+QDptJfw==", - "license": "MIT", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-loader/-/uui-loader-1.13.0.tgz", + "integrity": "sha512-AmNcIX7XNtW9dc29TdlMgTcTJBxU7MCae9iivNLLfFrg3VblltCPeeCOcLx77rw/k9o/IWrhLOsN81Q0HPfs7g==", "dependencies": { - "@umbraco-ui/uui-base": "1.13.0-rc.2" + "@umbraco-ui/uui-base": "1.13.0" } }, "node_modules/@umbraco-ui/uui-loader-bar": { - "version": "1.13.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-loader-bar/-/uui-loader-bar-1.13.0-rc.2.tgz", - "integrity": "sha512-X0QNZr8xQvUZJmzhILPTzZtnb+DHhF3nMkpkSEnabsYLCq01a4aPKq6HTc/CnFb5fQHBXAjv8qOR+5kvMcd9Ug==", - "license": "MIT", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-loader-bar/-/uui-loader-bar-1.13.0.tgz", + "integrity": "sha512-wRJl2n6VesXV5z7EOz3W8DKDo2XLbpb4a9HZHauDtnGl9aNQggcFYBXTrLAvqg2Nuir2g52kQT9mDcQiTDxJLQ==", "dependencies": { - "@umbraco-ui/uui-base": "1.13.0-rc.2" + "@umbraco-ui/uui-base": "1.13.0" } }, "node_modules/@umbraco-ui/uui-loader-circle": { - "version": "1.13.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-loader-circle/-/uui-loader-circle-1.13.0-rc.2.tgz", - "integrity": "sha512-my5lkXCzEhNVehFYLUZAIFaxXLND9XlV/5uqTwyFlFWWKjXZU4cloSWFriwoh3bXEXmKf65cBeGu151bNyOtxQ==", - "license": "MIT", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-loader-circle/-/uui-loader-circle-1.13.0.tgz", + "integrity": "sha512-efDzwo7uC7bs60boAvJNtqI7CFTe/4R5xdyi9khSF9w/0WnMRgIsY9h7xQLWCycjC/Nvoe/UwBZQ6P5khkdfaw==", "dependencies": { - "@umbraco-ui/uui-base": "1.13.0-rc.2" + "@umbraco-ui/uui-base": "1.13.0" } }, "node_modules/@umbraco-ui/uui-menu-item": { - "version": "1.13.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-menu-item/-/uui-menu-item-1.13.0-rc.2.tgz", - "integrity": "sha512-O0rJ2W70Wz9KyVyOnv7g4/GJjCDW8qaOUy9dPySlGPF+cg94K0liCiKmsOFCPnqPe2Pq7BsB7KcrYb6CEbSrwA==", - "license": "MIT", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-menu-item/-/uui-menu-item-1.13.0.tgz", + "integrity": "sha512-Rl3y+gXyN4ZLdzhhmCW1dWWC53erFVnVV1OTm2paYk1w13du/T4S+X7J0uyobrc1E3iFTjAFNh0UuvHxRsxtcQ==", "dependencies": { - "@umbraco-ui/uui-base": "1.13.0-rc.2", - "@umbraco-ui/uui-loader-bar": "1.13.0-rc.2", - "@umbraco-ui/uui-symbol-expand": "1.13.0-rc.2" + "@umbraco-ui/uui-base": "1.13.0", + "@umbraco-ui/uui-loader-bar": "1.13.0", + "@umbraco-ui/uui-symbol-expand": "1.13.0" } }, "node_modules/@umbraco-ui/uui-modal": { - "version": "1.13.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-modal/-/uui-modal-1.13.0-rc.2.tgz", - "integrity": "sha512-HvMVbMor48akQljQGTqAasZNiCGxiyUMx43DrbiRfM69ZBMiZndxOnuSNnZEUFBDXC0s8dWu7LmwTZXcu7ATXA==", - "license": "MIT", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-modal/-/uui-modal-1.13.0.tgz", + "integrity": "sha512-uiBmQg4gE3S9lreABkLbr4kSRdZAbkxzavBZ27DTDWjeez5Zn+sqy+FckPGct+HZheTdXgGF+M4YRypZj7gOhg==", "dependencies": { - "@umbraco-ui/uui-base": "1.13.0-rc.2" + "@umbraco-ui/uui-base": "1.13.0" } }, "node_modules/@umbraco-ui/uui-pagination": { - "version": "1.13.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-pagination/-/uui-pagination-1.13.0-rc.2.tgz", - "integrity": "sha512-USdMP45lbFF3KtonULFDpIRuJrD7XhnUC7Vqd0S71BI4XUxDiQkl+qHHLIUR0cqyY9goOtMY/dO6R6saxMwufA==", - "license": "MIT", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-pagination/-/uui-pagination-1.13.0.tgz", + "integrity": "sha512-RtD+szI8P+7y2tKBLLPJyCOlfS504LgQqD4pUOZbxemsQmMe37OZ1CiiqfrNJVEv4TbMHP0WvoRiLFDawICXnw==", "dependencies": { - "@umbraco-ui/uui-base": "1.13.0-rc.2", - "@umbraco-ui/uui-button": "1.13.0-rc.2", - "@umbraco-ui/uui-button-group": "1.13.0-rc.2" + "@umbraco-ui/uui-base": "1.13.0", + "@umbraco-ui/uui-button": "1.13.0", + "@umbraco-ui/uui-button-group": "1.13.0" } }, "node_modules/@umbraco-ui/uui-popover": { - "version": "1.13.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-popover/-/uui-popover-1.13.0-rc.2.tgz", - "integrity": "sha512-qbBcIwk7sxBG2broK/cfilep3BSoTUE0lYmoG9tKvrv9syoJpB+2/iNvRZauzO9JE+sjJHHvi1xAVUn9mlG6Jg==", - "license": "MIT", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-popover/-/uui-popover-1.13.0.tgz", + "integrity": "sha512-fpN0x+9p7cxrKiBYzEbpAYuIFYxWlUDrv4jYw3+oEI1ZP2wlS4dKphxhNtLreGrbaYsSUXe8Vgx9wy3eFawfug==", "dependencies": { - "@umbraco-ui/uui-base": "1.13.0-rc.2" + "@umbraco-ui/uui-base": "1.13.0" } }, "node_modules/@umbraco-ui/uui-popover-container": { - "version": "1.13.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-popover-container/-/uui-popover-container-1.13.0-rc.2.tgz", - "integrity": "sha512-hdpRFUqeR6LkJT14vqRfIKff3vkmomZ0fijK1HRxLHcZ3fg+bXt03B9k+SUV+DCf+HGq8o6qMpW6pEQxjbdnEw==", - "license": "MIT", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-popover-container/-/uui-popover-container-1.13.0.tgz", + "integrity": "sha512-pNvfRLjFzRY7j8bJ1LDGROBZ1+h4HbKqr7O4bs8z8ZfdrxqHb1k/BssbSNt25JFmoHDSRZbFs3yBL9jhVEr/Xg==", "dependencies": { - "@umbraco-ui/uui-base": "1.13.0-rc.2" + "@umbraco-ui/uui-base": "1.13.0" } }, "node_modules/@umbraco-ui/uui-progress-bar": { - "version": "1.13.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-progress-bar/-/uui-progress-bar-1.13.0-rc.2.tgz", - "integrity": "sha512-4lgMfXHRw/am1ZAlnKNeaCVg0m4BZPo+YSpYqdcaNNm/n8pFoFkY0vhpeBwI2kHAbgtlGgr3AO2rXj8kNS500A==", - "license": "MIT", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-progress-bar/-/uui-progress-bar-1.13.0.tgz", + "integrity": "sha512-QRgydD21AJfmv89WWiim8O/7XR0BTsWP73lga2Tbj3OU/8jjw0vcqmjzf0uhOir5SL1Y0Y1CT/SPUjgxc0VC0g==", "dependencies": { - "@umbraco-ui/uui-base": "1.13.0-rc.2" + "@umbraco-ui/uui-base": "1.13.0" } }, "node_modules/@umbraco-ui/uui-radio": { - "version": "1.13.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-radio/-/uui-radio-1.13.0-rc.2.tgz", - "integrity": "sha512-ysjuxkgADGNeQeRc4S6zfGGKaN9SCRBqaDj7oTX4Dof7cAYMlG3Sn1lOWZSYPko16Aq5P8R236PgEAAH/9b5yw==", - "license": "MIT", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-radio/-/uui-radio-1.13.0.tgz", + "integrity": "sha512-SsSqyte7n2KEqEjmtI2ajUX6m0AL6nreSZ53IGViMBim8bTcW4oBq5Wbp3dll+s88WvExppozE2iA1kLgjijOw==", "dependencies": { - "@umbraco-ui/uui-base": "1.13.0-rc.2" + "@umbraco-ui/uui-base": "1.13.0" } }, "node_modules/@umbraco-ui/uui-range-slider": { - "version": "1.13.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-range-slider/-/uui-range-slider-1.13.0-rc.2.tgz", - "integrity": "sha512-VoreL2wykxjXFguQWZeUpNVb7/VQ2ejr7IrqzdfIGZj0kS0Mu86e7dypc5iIZGDAdzkCylljn90kSHbuQQkxfg==", - "license": "MIT", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-range-slider/-/uui-range-slider-1.13.0.tgz", + "integrity": "sha512-gplKOzASnz2spVVkwgj1kYAPFRqp4KRuDFlWyr2IY5luvTajUZC6JOB4aQDs5+OMbgYvF4G+PKFEapuYnR7gNg==", "dependencies": { - "@umbraco-ui/uui-base": "1.13.0-rc.2" + "@umbraco-ui/uui-base": "1.13.0" } }, "node_modules/@umbraco-ui/uui-ref": { - "version": "1.13.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref/-/uui-ref-1.13.0-rc.2.tgz", - "integrity": "sha512-tAuYfBC/F0t3vP2HXPhoYbuh87vAx5yRhk9ZqqKliJjX2mQTPpxypAShxEaWjmxRrMDnpLO5/xASI8IQhgKL0g==", - "license": "MIT", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref/-/uui-ref-1.13.0.tgz", + "integrity": "sha512-jgVgHFa7/5zcg86Rtkecp7XO9FENQUQ7uMZyCAUHYCPur/n0CKNBrVjwQ/PEI0o1VR+eRGUG5iByZgQW1yWTtQ==", "dependencies": { - "@umbraco-ui/uui-base": "1.13.0-rc.2" + "@umbraco-ui/uui-base": "1.13.0" } }, "node_modules/@umbraco-ui/uui-ref-list": { - "version": "1.13.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-list/-/uui-ref-list-1.13.0-rc.2.tgz", - "integrity": "sha512-sT2psZE7T4iQRzmCWXADX1K1kSeyRipOLohDZfKMw1djjtcdwWuCTNwrb4DdyxwCY47/TNudz2w7/26VXcxd1w==", - "license": "MIT", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-list/-/uui-ref-list-1.13.0.tgz", + "integrity": "sha512-9Nw03JwymtGnkqvnEeRhmSS+F7Xlzp7yef4R/WdZEIYASV42vwCIAj5Wdj2JI+Apc0ZVZ4hCQhbfNVsr+e7ddQ==", "dependencies": { - "@umbraco-ui/uui-base": "1.13.0-rc.2" + "@umbraco-ui/uui-base": "1.13.0" } }, "node_modules/@umbraco-ui/uui-ref-node": { - "version": "1.13.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node/-/uui-ref-node-1.13.0-rc.2.tgz", - "integrity": "sha512-N2Efv7YB2rzGgwr8ZwvzKgGtGsX4yGWJGZ2B3ZP6d5m5OPkh6/zyQdOuqXuh2pynIMX7/H85hddr/WlSM+2jxg==", - "license": "MIT", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node/-/uui-ref-node-1.13.0.tgz", + "integrity": "sha512-otjHMgmaekLl3iPwDjLgJ6H7HIWF3QqNLNAiHnGZ1pdShJyLfajvHxnDULeUuI6zRDdjavzz3fhPUnjzyraYpQ==", "dependencies": { - "@umbraco-ui/uui-base": "1.13.0-rc.2", - "@umbraco-ui/uui-icon": "1.13.0-rc.2", - "@umbraco-ui/uui-ref": "1.13.0-rc.2" + "@umbraco-ui/uui-base": "1.13.0", + "@umbraco-ui/uui-icon": "1.13.0", + "@umbraco-ui/uui-ref": "1.13.0" } }, "node_modules/@umbraco-ui/uui-ref-node-data-type": { - "version": "1.13.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-data-type/-/uui-ref-node-data-type-1.13.0-rc.2.tgz", - "integrity": "sha512-MQaWjANvOqfoIqmJLdVhq0155A1t6huxPpvzjL9OB0f8sqIJfWq18zDREqlcfi6lTlXT7UvswNCa6yzDwLNMGA==", - "license": "MIT", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-data-type/-/uui-ref-node-data-type-1.13.0.tgz", + "integrity": "sha512-M5+7ekzpoNJmjD8YvH5TQPb1ENbIwnjyXyUv7IiXV2AtTF/H/g0t4pEU+SYhlrAe61VyW5TedtAMWK+oDKrWUg==", "dependencies": { - "@umbraco-ui/uui-base": "1.13.0-rc.2", - "@umbraco-ui/uui-ref-node": "1.13.0-rc.2" + "@umbraco-ui/uui-base": "1.13.0", + "@umbraco-ui/uui-ref-node": "1.13.0" } }, "node_modules/@umbraco-ui/uui-ref-node-document-type": { - "version": "1.13.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-document-type/-/uui-ref-node-document-type-1.13.0-rc.2.tgz", - "integrity": "sha512-Ca4NHFIQ71/DhRL883bgip0c98Dtqwe3TOiMjOX9qek5VnOik+ZyFQyVBN3jZGk+ndjkTf8P2wB7Hmz/bHaFmQ==", - "license": "MIT", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-document-type/-/uui-ref-node-document-type-1.13.0.tgz", + "integrity": "sha512-AsTjfuAKak/cdaZaJCjuu19YyYwC2FunPP2fz2PuXPr7ULcmo78oYIZY6YJPUsPlBSMN5PIIr9iox3ob6Dd+Rg==", "dependencies": { - "@umbraco-ui/uui-base": "1.13.0-rc.2", - "@umbraco-ui/uui-ref-node": "1.13.0-rc.2" + "@umbraco-ui/uui-base": "1.13.0", + "@umbraco-ui/uui-ref-node": "1.13.0" } }, "node_modules/@umbraco-ui/uui-ref-node-form": { - "version": "1.13.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-form/-/uui-ref-node-form-1.13.0-rc.2.tgz", - "integrity": "sha512-aqvYjfNmZO5wdy79L2Da9bYih8nuib6GC1T9NWWKHnXSITo3f7i50U0I1Q5u1Odd73U2iT9ISqQoXJAy3Ad25Q==", - "license": "MIT", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-form/-/uui-ref-node-form-1.13.0.tgz", + "integrity": "sha512-ySHrq0xH4l69NH12pXzfPrrMG9fRnHF7ul+iKSrPvqUdWnsNpEzYakGvt6XXji1x3ogZEKnKMlzAXrHZDL8LoA==", "dependencies": { - "@umbraco-ui/uui-base": "1.13.0-rc.2", - "@umbraco-ui/uui-ref-node": "1.13.0-rc.2" + "@umbraco-ui/uui-base": "1.13.0", + "@umbraco-ui/uui-ref-node": "1.13.0" } }, "node_modules/@umbraco-ui/uui-ref-node-member": { - "version": "1.13.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-member/-/uui-ref-node-member-1.13.0-rc.2.tgz", - "integrity": "sha512-OLcrEXzQQ6L9lCTQCZBLpww3Gtde7G7R2U6OiYnpU1Ch6q84G2XrEPU3FLplmEUToS709gaIfeNbZDb59jwUEg==", - "license": "MIT", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-member/-/uui-ref-node-member-1.13.0.tgz", + "integrity": "sha512-UiSAxsPjpivbI0Hm1fZ1O7nTgkSjPigi9z5RWT4P0viiYetrc8ggJpZ5cDFEQH2xBe40qfBQQGr8vJ4Gsz3opg==", "dependencies": { - "@umbraco-ui/uui-base": "1.13.0-rc.2", - "@umbraco-ui/uui-ref-node": "1.13.0-rc.2" + "@umbraco-ui/uui-base": "1.13.0", + "@umbraco-ui/uui-ref-node": "1.13.0" } }, "node_modules/@umbraco-ui/uui-ref-node-package": { - "version": "1.13.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-package/-/uui-ref-node-package-1.13.0-rc.2.tgz", - "integrity": "sha512-PcWGz56HYpb6pxe1rDI7W3LBuhUthzu5hL2O9svcia52wKJV0uwGJ6sYUjQSCvhS/qIjGQgB+5Dq8Y/Y1vTI/w==", - "license": "MIT", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-package/-/uui-ref-node-package-1.13.0.tgz", + "integrity": "sha512-iANsUZDFjLQdalKVI007LuNDlEsruh88peWiBrDN47HtRZlZ/tLV67Ljd5oRjZhAFZLjjFQ1jl0DOkkD3lKIFw==", "dependencies": { - "@umbraco-ui/uui-base": "1.13.0-rc.2", - "@umbraco-ui/uui-ref-node": "1.13.0-rc.2" + "@umbraco-ui/uui-base": "1.13.0", + "@umbraco-ui/uui-ref-node": "1.13.0" } }, "node_modules/@umbraco-ui/uui-ref-node-user": { - "version": "1.13.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-user/-/uui-ref-node-user-1.13.0-rc.2.tgz", - "integrity": "sha512-amM+ovH7G2h/M69d+Ip7QmjyGg6MD0zN5rOw4CNN9t4WqAKb4YjlmQPDMTK/fOzUazyChgCfAIHV41x6NYGqxw==", - "license": "MIT", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-user/-/uui-ref-node-user-1.13.0.tgz", + "integrity": "sha512-XckwV6nrJjWeeBZX7j28fJdJZlzugyhfXIacp6+AnFHrL5NXjsb3Hi4ZLt00CurcxmhVVta+J5uvmOLSVi7Myw==", "dependencies": { - "@umbraco-ui/uui-base": "1.13.0-rc.2", - "@umbraco-ui/uui-ref-node": "1.13.0-rc.2" + "@umbraco-ui/uui-base": "1.13.0", + "@umbraco-ui/uui-ref-node": "1.13.0" } }, "node_modules/@umbraco-ui/uui-scroll-container": { - "version": "1.13.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-scroll-container/-/uui-scroll-container-1.13.0-rc.2.tgz", - "integrity": "sha512-de9JYsi+Cp8J3sgKhwkP0c7r3n9/GQGsDESoSht10VzH/UuxQBdCneUGXCB8cMfJe5An6dm/p0IFR23cby3DtA==", - "license": "MIT", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-scroll-container/-/uui-scroll-container-1.13.0.tgz", + "integrity": "sha512-3Qnl6aGxRs2FYvZzskZYFXnDsej5vBHalu/0b7VKfTPdUMJuAtR+1rz+veLvm9hL5pf9sJbSx4IZe+BubrYmnw==", "dependencies": { - "@umbraco-ui/uui-base": "1.13.0-rc.2" + "@umbraco-ui/uui-base": "1.13.0" } }, "node_modules/@umbraco-ui/uui-select": { - "version": "1.13.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-select/-/uui-select-1.13.0-rc.2.tgz", - "integrity": "sha512-Qp7wg1o6Vg1zlPrI8xbUOQho3tYX4S2+2BICRY69KUa8D8zUuvu0EL5OesDjpWmaPtPg88ku9gTc12PB/pCDuQ==", - "license": "MIT", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-select/-/uui-select-1.13.0.tgz", + "integrity": "sha512-JF4Jtgc/H61tdPVD01kkBRkUofWatrUG9diRMuaGPvQsWEVNvbCJKXJ+Fww9pMQts25EidLhhtqG2hX3ZSsgYA==", "dependencies": { - "@umbraco-ui/uui-base": "1.13.0-rc.2" + "@umbraco-ui/uui-base": "1.13.0" } }, "node_modules/@umbraco-ui/uui-slider": { - "version": "1.13.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-slider/-/uui-slider-1.13.0-rc.2.tgz", - "integrity": "sha512-sDM53G8Ji+SnTjfL0u49TRn62da2hoZcNGy6AwyYSFpbccRZtWmfom/CdkLpVQxN/gJReOWsfOL8nqajSxah5Q==", - "license": "MIT", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-slider/-/uui-slider-1.13.0.tgz", + "integrity": "sha512-r4QE+V0LTyn1NAyHsLBkHAvu1jzqfpQ9mOIzwt7ekpuKUrlbaB+LWVo+lxiX7ShUVHxL+0squ0/1CNrLquz0AA==", "dependencies": { - "@umbraco-ui/uui-base": "1.13.0-rc.2" + "@umbraco-ui/uui-base": "1.13.0" } }, "node_modules/@umbraco-ui/uui-symbol-expand": { - "version": "1.13.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-expand/-/uui-symbol-expand-1.13.0-rc.2.tgz", - "integrity": "sha512-kEhXQ3rg5TH/m3hNvQNhwmY6SWwWuRfb6WdKj7QfLm2WEfJ6n0y2E8O0DGzkWttD39WTURcGOZlL63ZrPHuPgg==", - "license": "MIT", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-expand/-/uui-symbol-expand-1.13.0.tgz", + "integrity": "sha512-nR6Ld0ZrWQX0Ijk1y+3sRXMaAh87uaQkhcIHgS9Ziz+F1JbCf5WCygla3Xux5t+zpxhPVy6yvZc3iWJxQMp1TA==", "dependencies": { - "@umbraco-ui/uui-base": "1.13.0-rc.2" + "@umbraco-ui/uui-base": "1.13.0" } }, "node_modules/@umbraco-ui/uui-symbol-file": { - "version": "1.13.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-file/-/uui-symbol-file-1.13.0-rc.2.tgz", - "integrity": "sha512-ekaK5KWRhtTUGtgRd/PEWGWZShgtizmjx9OfXkx8e6lQZn+eXnzTv5ErxauDKOxK/cPDp42oM2OLDRi73ewMTg==", - "license": "MIT", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-file/-/uui-symbol-file-1.13.0.tgz", + "integrity": "sha512-F3+MyQaGDUYr+Z0VyBmZaIirPKSkON2Gu6jrb8kX04UuqVPIRvoxjubGTmu6wU5M0ATRt/NIG5CzYJp33R8bGA==", "dependencies": { - "@umbraco-ui/uui-base": "1.13.0-rc.2" + "@umbraco-ui/uui-base": "1.13.0" } }, "node_modules/@umbraco-ui/uui-symbol-file-dropzone": { - "version": "1.13.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-file-dropzone/-/uui-symbol-file-dropzone-1.13.0-rc.2.tgz", - "integrity": "sha512-5+tQ9xNnO/asfvhHxAr+O2+8oB0UWeymnebc4CuygNtuQ0A4S+8ypUFY/xvPUxzhCkKVYD9nrwoaDYvT8cMvBg==", - "license": "MIT", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-file-dropzone/-/uui-symbol-file-dropzone-1.13.0.tgz", + "integrity": "sha512-ko3+WSdgd3pG3SI5eUPJ/VbOYTW86AW6EmYDrsALAdRdKhQ5Kusbe7M8Uds8BB3EJ9GT9+xcjocLNMCTxV8soA==", "dependencies": { - "@umbraco-ui/uui-base": "1.13.0-rc.2" + "@umbraco-ui/uui-base": "1.13.0" } }, "node_modules/@umbraco-ui/uui-symbol-file-thumbnail": { - "version": "1.13.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-file-thumbnail/-/uui-symbol-file-thumbnail-1.13.0-rc.2.tgz", - "integrity": "sha512-Bz8fIKiFIbNtniAjerhqjbi4BKAVvnnh8aM/9eHnW/Gbtha8bzTN5zBPDLxzHsEe2VW8EEIE95NC2Gp0MkCscQ==", - "license": "MIT", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-file-thumbnail/-/uui-symbol-file-thumbnail-1.13.0.tgz", + "integrity": "sha512-fgdJcecVz39MuFTTneD9yI8K/4KZQkHaARfvcWmc2rvRD8S5HzGcp/a+y0zOmzLIpKi3Sjlwc/4d123nE3V0NQ==", "dependencies": { - "@umbraco-ui/uui-base": "1.13.0-rc.2" + "@umbraco-ui/uui-base": "1.13.0" } }, "node_modules/@umbraco-ui/uui-symbol-folder": { - "version": "1.13.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-folder/-/uui-symbol-folder-1.13.0-rc.2.tgz", - "integrity": "sha512-XqOxR9xmSsWHFzGVFjA7vd7isdmeEe/t0mt8/ePJTgv+m+pmlqjietaXulYMywJoF5zE3Q2nT4azXLzL/6mTng==", - "license": "MIT", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-folder/-/uui-symbol-folder-1.13.0.tgz", + "integrity": "sha512-TIh45JTtvv6l+/7+UtSQxxyvtIyiv9tVv1QC4SKesW19opUkWiaNd5awaKlshi+Iu9CbXvCVwxTJ6TK5z3hsaA==", "dependencies": { - "@umbraco-ui/uui-base": "1.13.0-rc.2" + "@umbraco-ui/uui-base": "1.13.0" } }, "node_modules/@umbraco-ui/uui-symbol-lock": { - "version": "1.13.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-lock/-/uui-symbol-lock-1.13.0-rc.2.tgz", - "integrity": "sha512-W4wECvErayB31p15Eh6rP+LGxLfwO6HqEGIuvQXZVuXGxQDL6ObRc3L1bpy6LT/VgVFT6fSlYEBOC9110xCTZQ==", - "license": "MIT", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-lock/-/uui-symbol-lock-1.13.0.tgz", + "integrity": "sha512-/39U8n0DfHNI4I2X1WX8dJv6pSOHeJMvpyS1Cla54Q45gtt7RHMU55aNEGBZoF19oPV2W74gl7vfcHGTtnPKNQ==", "dependencies": { - "@umbraco-ui/uui-base": "1.13.0-rc.2" + "@umbraco-ui/uui-base": "1.13.0" } }, "node_modules/@umbraco-ui/uui-symbol-more": { - "version": "1.13.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-more/-/uui-symbol-more-1.13.0-rc.2.tgz", - "integrity": "sha512-YVTBbhSuz2+lDhoP4hLi3Ru8ZLEiUJ1dT7AXfkM3CRvHeAL2oqYlNyCkz2Hwr/DcCJ8kappxkoEesKdi3NtqBw==", - "license": "MIT", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-more/-/uui-symbol-more-1.13.0.tgz", + "integrity": "sha512-mEwbSezTZfG77MUdWrFGXkMaSBHpC899lToDONTnQurkvLBxbBRBlT+xhHo54psAzJX7C6NLRvExTMztGU1OeQ==", "dependencies": { - "@umbraco-ui/uui-base": "1.13.0-rc.2" + "@umbraco-ui/uui-base": "1.13.0" } }, "node_modules/@umbraco-ui/uui-symbol-sort": { - "version": "1.13.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-sort/-/uui-symbol-sort-1.13.0-rc.2.tgz", - "integrity": "sha512-wgW1zTHhnPXEwSmVp0PYFfli856Jta+rvfuxK5LlNbfS+TZX/enOOE1RzdpBfw0eCeMA1RyqpGTZnBZOzs9axg==", - "license": "MIT", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-sort/-/uui-symbol-sort-1.13.0.tgz", + "integrity": "sha512-BDcvHXrueX3d6sFcQa5jzxlV1C0OdhymN1Q5GzXpby2xLJTjNbeGISdgHGCxjLPsmHUAAZ7XCGR8pqI0F+8Hpg==", "dependencies": { - "@umbraco-ui/uui-base": "1.13.0-rc.2" + "@umbraco-ui/uui-base": "1.13.0" } }, "node_modules/@umbraco-ui/uui-table": { - "version": "1.13.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-table/-/uui-table-1.13.0-rc.2.tgz", - "integrity": "sha512-3XTkx08WtRJcA5TwJrcIYFMOC20qCcsfLuDNaTzUtkE9420iHv4uwVYCuLez8tY6aDS4Lzp8B2ej9EsTLGMJkg==", - "license": "MIT", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-table/-/uui-table-1.13.0.tgz", + "integrity": "sha512-CKoPIsqURMtR6PwaSs4UvB56LVLMTop93gArI//yN9Ox1/w7awxnnkRN2skpKIbtDHrbEBI//NJE50jPoS82eg==", "dependencies": { - "@umbraco-ui/uui-base": "1.13.0-rc.2" + "@umbraco-ui/uui-base": "1.13.0" } }, "node_modules/@umbraco-ui/uui-tabs": { - "version": "1.13.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-tabs/-/uui-tabs-1.13.0-rc.2.tgz", - "integrity": "sha512-A+PwNIGHeA2QT74WSXjVoP/rTfZnfNOM58NLKqjHGUSZwNb8PM+ANClqflKUSvvAAWy9KTMQdJe+Pt8F63FMtQ==", - "license": "MIT", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-tabs/-/uui-tabs-1.13.0.tgz", + "integrity": "sha512-b50xJ1Xka8nu51GCR8n2RZtCFjwTYDXV5zQF+s5KXpgC6A8mahCvzmmINHdgGnKm1JNG3c8abhwrueyxxVdI8Q==", "dependencies": { - "@umbraco-ui/uui-base": "1.13.0-rc.2", - "@umbraco-ui/uui-button": "1.13.0-rc.2", - "@umbraco-ui/uui-popover-container": "1.13.0-rc.2", - "@umbraco-ui/uui-symbol-more": "1.13.0-rc.2" + "@umbraco-ui/uui-base": "1.13.0", + "@umbraco-ui/uui-button": "1.13.0", + "@umbraco-ui/uui-popover-container": "1.13.0", + "@umbraco-ui/uui-symbol-more": "1.13.0" } }, "node_modules/@umbraco-ui/uui-tag": { - "version": "1.13.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-tag/-/uui-tag-1.13.0-rc.2.tgz", - "integrity": "sha512-672d/39UffEjScpgWz3lvpDJMEPeWi9WYpONrBtpOlTW/qBrqBke50njSPjyby60TqVNxTmvCMLzoXpyNeffjg==", - "license": "MIT", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-tag/-/uui-tag-1.13.0.tgz", + "integrity": "sha512-SBY9Mi9A89jIag7URKQqXW3omDk5Eczw2LuNF7VnkXmQCuvsiRP6/BzSBCh9m0RrD4QOLSXpYGgSoLSpS7MitA==", "dependencies": { - "@umbraco-ui/uui-base": "1.13.0-rc.2" + "@umbraco-ui/uui-base": "1.13.0" } }, "node_modules/@umbraco-ui/uui-textarea": { - "version": "1.13.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-textarea/-/uui-textarea-1.13.0-rc.2.tgz", - "integrity": "sha512-MTEkXgMt8ttyXk5qPYDJ3mMHbgxFE8mejR5Do2dT9UJPKJkbP73SKpvQNru95slbrumdTwpj4lxAlPS6ZEZg7Q==", - "license": "MIT", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-textarea/-/uui-textarea-1.13.0.tgz", + "integrity": "sha512-H4XChy1m5gq43eySQ3Zp/AsBvh35Gk0VLijFxdhCfV+HHpuyrt0fJsYnjq1W1xoqhyt7h84YRpNIJMyAIm2WHQ==", "dependencies": { - "@umbraco-ui/uui-base": "1.13.0-rc.2" + "@umbraco-ui/uui-base": "1.13.0" } }, "node_modules/@umbraco-ui/uui-toast-notification": { - "version": "1.13.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-toast-notification/-/uui-toast-notification-1.13.0-rc.2.tgz", - "integrity": "sha512-aGLdQbkWEj9C+fBXREFv+OR/1LPZhbGx586UiEykMK57SusT41091imfYmyW+sf3cJ/7jlHO/ykBd6mT3cM6yQ==", - "license": "MIT", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-toast-notification/-/uui-toast-notification-1.13.0.tgz", + "integrity": "sha512-o45G8hWXgqcfGaJM+nhCTDSpevREJd+gPKT5XhTkD2wA99/kevdedmlYIgKS+9wONLk5A0j8qnsbWntinbb+rw==", "dependencies": { - "@umbraco-ui/uui-base": "1.13.0-rc.2", - "@umbraco-ui/uui-button": "1.13.0-rc.2", - "@umbraco-ui/uui-css": "1.13.0-rc.2", - "@umbraco-ui/uui-icon": "1.13.0-rc.2", - "@umbraco-ui/uui-icon-registry-essential": "1.13.0-rc.2" + "@umbraco-ui/uui-base": "1.13.0", + "@umbraco-ui/uui-button": "1.13.0", + "@umbraco-ui/uui-css": "1.13.0", + "@umbraco-ui/uui-icon": "1.13.0", + "@umbraco-ui/uui-icon-registry-essential": "1.13.0" } }, "node_modules/@umbraco-ui/uui-toast-notification-container": { - "version": "1.13.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-toast-notification-container/-/uui-toast-notification-container-1.13.0-rc.2.tgz", - "integrity": "sha512-W2UBjLbDQBh220aIlKThDmdw8sKPxj9Ux4GRuH1Tgh0QZSC5C7PC5gX5MKcrFWKGeyvn/HCfgni8GaED2Jmnxw==", - "license": "MIT", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-toast-notification-container/-/uui-toast-notification-container-1.13.0.tgz", + "integrity": "sha512-9O0t73v7qkb3+VE8i0pD1vo33tNt1U7t3L6699jNMZZr+7R6a5YOAVrFt+gs+kQcQXWt0HCfQxhKJ8opLoBOyw==", "dependencies": { - "@umbraco-ui/uui-base": "1.13.0-rc.2", - "@umbraco-ui/uui-toast-notification": "1.13.0-rc.2" + "@umbraco-ui/uui-base": "1.13.0", + "@umbraco-ui/uui-toast-notification": "1.13.0" } }, "node_modules/@umbraco-ui/uui-toast-notification-layout": { - "version": "1.13.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-toast-notification-layout/-/uui-toast-notification-layout-1.13.0-rc.2.tgz", - "integrity": "sha512-qnLmsAB0KmZ28O3ULg8ieuPERka6GG3Ck80Z8jOPCWNHPnIVTjG7gr7jnB/bkkd3OSh67XPq87CYb9ldSnmABw==", - "license": "MIT", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-toast-notification-layout/-/uui-toast-notification-layout-1.13.0.tgz", + "integrity": "sha512-yhz8msOc1ngA//oBDefrR8pagTbvAenBiyk/fPuEwGQriM43e8bbVCJvhmrsTuAzAL8nn/ilKhAU5lrkn2rAmg==", "dependencies": { - "@umbraco-ui/uui-base": "1.13.0-rc.2", - "@umbraco-ui/uui-css": "1.13.0-rc.2" + "@umbraco-ui/uui-base": "1.13.0", + "@umbraco-ui/uui-css": "1.13.0" } }, "node_modules/@umbraco-ui/uui-toggle": { - "version": "1.13.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-toggle/-/uui-toggle-1.13.0-rc.2.tgz", - "integrity": "sha512-/Uku6MgByYXdW34jfsO5C2qsqXvFJCdzoYl/nxXISB8PzdEYfGWYkWTcF25hfxIzZyoo3e/dDLdFsfhk0gBcXA==", - "license": "MIT", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-toggle/-/uui-toggle-1.13.0.tgz", + "integrity": "sha512-tHzG/Lh9vRLjPu7EhFupaD7jkpVenyEM3iIsA24wBVKmqJGxacpuuuOwpTv6vGGiIYSKfRDXTDk07Q6MHDSy4g==", "dependencies": { - "@umbraco-ui/uui-base": "1.13.0-rc.2", - "@umbraco-ui/uui-boolean-input": "1.13.0-rc.2" + "@umbraco-ui/uui-base": "1.13.0", + "@umbraco-ui/uui-boolean-input": "1.13.0" } }, "node_modules/@umbraco-ui/uui-visually-hidden": { - "version": "1.13.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-visually-hidden/-/uui-visually-hidden-1.13.0-rc.2.tgz", - "integrity": "sha512-jwYrycIDPNQ/pqD6S1GWbKz/3761d0Q7fPZir2psRcJlSA6UDN7esL/lo1nNgNK4gXzC7MLbXPNnG90g1FZT/A==", - "license": "MIT", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-visually-hidden/-/uui-visually-hidden-1.13.0.tgz", + "integrity": "sha512-1ayTJylWnpAl0VQE7X2PBJCKLZ15R+xfZ3yy4ygT751k4wML26nvdWscp/tYfl4MteqrHtNJKTRTFoQ1Dn/r/g==", "dependencies": { - "@umbraco-ui/uui-base": "1.13.0-rc.2" + "@umbraco-ui/uui-base": "1.13.0" } }, "node_modules/@vitest/expect": { @@ -7176,8 +7092,7 @@ "node_modules/colord": { "version": "2.9.3", "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", - "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==", - "license": "MIT" + "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==" }, "node_modules/command-line-args": { "version": "5.2.1", diff --git a/src/Umbraco.Web.UI.Client/package.json b/src/Umbraco.Web.UI.Client/package.json index 371a99763b..82909033a0 100644 --- a/src/Umbraco.Web.UI.Client/package.json +++ b/src/Umbraco.Web.UI.Client/package.json @@ -218,8 +218,8 @@ "@tiptap/pm": "2.11.5", "@tiptap/starter-kit": "2.11.5", "@types/diff": "^7.0.1", - "@umbraco-ui/uui": "1.13.0-rc.2", - "@umbraco-ui/uui-css": "1.13.0-rc.2", + "@umbraco-ui/uui": "^1.13.0", + "@umbraco-ui/uui-css": "^1.13.0", "diff": "^7.0.0", "dompurify": "^3.2.4", "element-internals-polyfill": "^1.3.13", diff --git a/src/Umbraco.Web.UI.Client/src/apps/backoffice/components/backoffice-main.element.ts b/src/Umbraco.Web.UI.Client/src/apps/backoffice/components/backoffice-main.element.ts index 717a07f654..87081f11b1 100644 --- a/src/Umbraco.Web.UI.Client/src/apps/backoffice/components/backoffice-main.element.ts +++ b/src/Umbraco.Web.UI.Client/src/apps/backoffice/components/backoffice-main.element.ts @@ -95,7 +95,7 @@ export class UmbBackofficeMainElement extends UmbLitElement { private _provideSectionContext(sectionManifest: ManifestSection) { if (!this._sectionContext) { - this._sectionContext = new UmbSectionContext(sectionManifest); + this._sectionContext = new UmbSectionContext(this, sectionManifest); this.provideContext(UMB_SECTION_CONTEXT, this._sectionContext); } else { this._sectionContext.setManifest(sectionManifest); diff --git a/src/Umbraco.Web.UI.Client/src/apps/installer/error/installer-error.stories.ts b/src/Umbraco.Web.UI.Client/src/apps/installer/error/installer-error.stories.ts index 6008563367..d60a58df9f 100644 --- a/src/Umbraco.Web.UI.Client/src/apps/installer/error/installer-error.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/apps/installer/error/installer-error.stories.ts @@ -5,6 +5,7 @@ import type { Meta, StoryFn } from '@storybook/web-components'; import { html } from '@umbraco-cms/backoffice/external/lit'; import './installer-error.element.js'; +import type { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api'; const error = { type: 'validation', @@ -20,14 +21,17 @@ const error = { }, }; -const installerContext = new UmbInstallerContext(); -installerContext.setInstallStatus(error); +const installerContextMethod = (host: UmbControllerHostElement) => { + const installerContext = new UmbInstallerContext(host); + installerContext.setInstallStatus(error); + return installerContext; +}; export default { title: 'Apps/Installer/Steps', component: 'umb-installer-error', id: 'umb-installer-error', - decorators: [(story) => installerContextProvider(story, installerContext)], + decorators: [(story) => installerContextProvider(story, installerContextMethod)], } as Meta; export const Step5Error: StoryFn = () => html``; diff --git a/src/Umbraco.Web.UI.Client/src/apps/installer/installer.context.ts b/src/Umbraco.Web.UI.Client/src/apps/installer/installer.context.ts index ad203dbf29..0193999416 100644 --- a/src/Umbraco.Web.UI.Client/src/apps/installer/installer.context.ts +++ b/src/Umbraco.Web.UI.Client/src/apps/installer/installer.context.ts @@ -8,12 +8,14 @@ import { InstallService, TelemetryLevelModel } from '@umbraco-cms/backoffice/ext import { tryExecute } from '@umbraco-cms/backoffice/resources'; import { UmbContextToken } from '@umbraco-cms/backoffice/context-api'; import { UmbObjectState, UmbNumberState } from '@umbraco-cms/backoffice/observable-api'; +import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; +import { UmbContextBase } from '@umbraco-cms/backoffice/class-api'; /** * Context API for the installer * @class UmbInstallerContext */ -export class UmbInstallerContext { +export class UmbInstallerContext extends UmbContextBase { private _data = new UmbObjectState({ user: { name: '', email: '', password: '', subscribeToNewsletter: false }, database: { id: '', providerName: '', useIntegratedAuthentication: false, trustServerCertificate: false }, @@ -30,7 +32,8 @@ export class UmbInstallerContext { private _installStatus = new UmbObjectState(null); public readonly installStatus = this._installStatus.asObservable(); - constructor() { + constructor(host: UmbControllerHost) { + super(host, UMB_INSTALLER_CONTEXT); this._loadInstallerSettings(); } diff --git a/src/Umbraco.Web.UI.Client/src/apps/installer/installer.element.ts b/src/Umbraco.Web.UI.Client/src/apps/installer/installer.element.ts index bbd49dbcc0..7de17887b0 100644 --- a/src/Umbraco.Web.UI.Client/src/apps/installer/installer.element.ts +++ b/src/Umbraco.Web.UI.Client/src/apps/installer/installer.element.ts @@ -1,4 +1,4 @@ -import { UmbInstallerContext, UMB_INSTALLER_CONTEXT } from './installer.context.js'; +import { UmbInstallerContext } from './installer.context.js'; import { html, customElement, state } from '@umbraco-cms/backoffice/external/lit'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; @@ -14,12 +14,7 @@ export class UmbInstallerElement extends UmbLitElement { @state() step = 1; - private _umbInstallerContext = new UmbInstallerContext(); - - constructor() { - super(); - this.provideContext(UMB_INSTALLER_CONTEXT, this._umbInstallerContext); - } + private _umbInstallerContext = new UmbInstallerContext(this); override connectedCallback(): void { super.connectedCallback(); diff --git a/src/Umbraco.Web.UI.Client/src/apps/installer/shared/utils.story-helpers.ts b/src/Umbraco.Web.UI.Client/src/apps/installer/shared/utils.story-helpers.ts index e22e315b24..2828cb638d 100644 --- a/src/Umbraco.Web.UI.Client/src/apps/installer/shared/utils.story-helpers.ts +++ b/src/Umbraco.Web.UI.Client/src/apps/installer/shared/utils.story-helpers.ts @@ -1,14 +1,16 @@ import { UmbInstallerContext } from '../installer.context.js'; +import type { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api'; import { html, type TemplateResult } from '@umbraco-cms/backoffice/external/lit'; export const installerContextProvider = ( story: () => Node | string | TemplateResult, - installerContext = new UmbInstallerContext(), + createContextMethod = (host: UmbControllerHostElement) => { + return new UmbInstallerContext(host); + }, ) => html` - + .create=${createContextMethod}> ${story()} - + `; diff --git a/src/Umbraco.Web.UI.Client/src/external/backend-api/src/sdk.gen.ts b/src/Umbraco.Web.UI.Client/src/external/backend-api/src/sdk.gen.ts index 424deb2926..78a6e36b45 100644 --- a/src/Umbraco.Web.UI.Client/src/external/backend-api/src/sdk.gen.ts +++ b/src/Umbraco.Web.UI.Client/src/external/backend-api/src/sdk.gen.ts @@ -3,7 +3,7 @@ import type { CancelablePromise } from './core/CancelablePromise'; import { OpenAPI } from './core/OpenAPI'; import { request as __request } from './core/request'; -import type { GetCultureData, GetCultureResponse, PostDataTypeData, PostDataTypeResponse, GetDataTypeByIdData, GetDataTypeByIdResponse, DeleteDataTypeByIdData, DeleteDataTypeByIdResponse, PutDataTypeByIdData, PutDataTypeByIdResponse, PostDataTypeByIdCopyData, PostDataTypeByIdCopyResponse, GetDataTypeByIdIsUsedData, GetDataTypeByIdIsUsedResponse, PutDataTypeByIdMoveData, PutDataTypeByIdMoveResponse, GetDataTypeByIdReferencesData, GetDataTypeByIdReferencesResponse, GetDataTypeConfigurationResponse, PostDataTypeFolderData, PostDataTypeFolderResponse, GetDataTypeFolderByIdData, GetDataTypeFolderByIdResponse, DeleteDataTypeFolderByIdData, DeleteDataTypeFolderByIdResponse, PutDataTypeFolderByIdData, PutDataTypeFolderByIdResponse, GetFilterDataTypeData, GetFilterDataTypeResponse, GetItemDataTypeData, GetItemDataTypeResponse, GetItemDataTypeSearchData, GetItemDataTypeSearchResponse, GetTreeDataTypeAncestorsData, GetTreeDataTypeAncestorsResponse, GetTreeDataTypeChildrenData, GetTreeDataTypeChildrenResponse, GetTreeDataTypeRootData, GetTreeDataTypeRootResponse, GetDictionaryData, GetDictionaryResponse, PostDictionaryData, PostDictionaryResponse, GetDictionaryByIdData, GetDictionaryByIdResponse, DeleteDictionaryByIdData, DeleteDictionaryByIdResponse, PutDictionaryByIdData, PutDictionaryByIdResponse, GetDictionaryByIdExportData, GetDictionaryByIdExportResponse, PutDictionaryByIdMoveData, PutDictionaryByIdMoveResponse, PostDictionaryImportData, PostDictionaryImportResponse, GetItemDictionaryData, GetItemDictionaryResponse, GetTreeDictionaryAncestorsData, GetTreeDictionaryAncestorsResponse, GetTreeDictionaryChildrenData, GetTreeDictionaryChildrenResponse, GetTreeDictionaryRootData, GetTreeDictionaryRootResponse, GetCollectionDocumentByIdData, GetCollectionDocumentByIdResponse, PostDocumentData, PostDocumentResponse, GetDocumentByIdData, GetDocumentByIdResponse, DeleteDocumentByIdData, DeleteDocumentByIdResponse, PutDocumentByIdData, PutDocumentByIdResponse, GetDocumentByIdAuditLogData, GetDocumentByIdAuditLogResponse, PostDocumentByIdCopyData, PostDocumentByIdCopyResponse, GetDocumentByIdDomainsData, GetDocumentByIdDomainsResponse, PutDocumentByIdDomainsData, PutDocumentByIdDomainsResponse, PutDocumentByIdMoveData, PutDocumentByIdMoveResponse, PutDocumentByIdMoveToRecycleBinData, PutDocumentByIdMoveToRecycleBinResponse, GetDocumentByIdNotificationsData, GetDocumentByIdNotificationsResponse, PutDocumentByIdNotificationsData, PutDocumentByIdNotificationsResponse, PostDocumentByIdPublicAccessData, PostDocumentByIdPublicAccessResponse, DeleteDocumentByIdPublicAccessData, DeleteDocumentByIdPublicAccessResponse, GetDocumentByIdPublicAccessData, GetDocumentByIdPublicAccessResponse, PutDocumentByIdPublicAccessData, PutDocumentByIdPublicAccessResponse, PutDocumentByIdPublishData, PutDocumentByIdPublishResponse, PutDocumentByIdPublishWithDescendantsData, PutDocumentByIdPublishWithDescendantsResponse, GetDocumentByIdPublishedData, GetDocumentByIdPublishedResponse, GetDocumentByIdReferencedByData, GetDocumentByIdReferencedByResponse, GetDocumentByIdReferencedDescendantsData, GetDocumentByIdReferencedDescendantsResponse, PutDocumentByIdUnpublishData, PutDocumentByIdUnpublishResponse, PutUmbracoManagementApiV11DocumentByIdValidate11Data, PutUmbracoManagementApiV11DocumentByIdValidate11Response, GetDocumentAreReferencedData, GetDocumentAreReferencedResponse, GetDocumentConfigurationResponse, PutDocumentSortData, PutDocumentSortResponse, GetDocumentUrlsData, GetDocumentUrlsResponse, PostDocumentValidateData, PostDocumentValidateResponse, GetItemDocumentData, GetItemDocumentResponse, GetItemDocumentSearchData, GetItemDocumentSearchResponse, DeleteRecycleBinDocumentResponse, DeleteRecycleBinDocumentByIdData, DeleteRecycleBinDocumentByIdResponse, GetRecycleBinDocumentByIdOriginalParentData, GetRecycleBinDocumentByIdOriginalParentResponse, PutRecycleBinDocumentByIdRestoreData, PutRecycleBinDocumentByIdRestoreResponse, GetRecycleBinDocumentChildrenData, GetRecycleBinDocumentChildrenResponse, GetRecycleBinDocumentRootData, GetRecycleBinDocumentRootResponse, GetTreeDocumentAncestorsData, GetTreeDocumentAncestorsResponse, GetTreeDocumentChildrenData, GetTreeDocumentChildrenResponse, GetTreeDocumentRootData, GetTreeDocumentRootResponse, PostDocumentBlueprintData, PostDocumentBlueprintResponse, GetDocumentBlueprintByIdData, GetDocumentBlueprintByIdResponse, DeleteDocumentBlueprintByIdData, DeleteDocumentBlueprintByIdResponse, PutDocumentBlueprintByIdData, PutDocumentBlueprintByIdResponse, PutDocumentBlueprintByIdMoveData, PutDocumentBlueprintByIdMoveResponse, PostDocumentBlueprintFolderData, PostDocumentBlueprintFolderResponse, GetDocumentBlueprintFolderByIdData, GetDocumentBlueprintFolderByIdResponse, DeleteDocumentBlueprintFolderByIdData, DeleteDocumentBlueprintFolderByIdResponse, PutDocumentBlueprintFolderByIdData, PutDocumentBlueprintFolderByIdResponse, PostDocumentBlueprintFromDocumentData, PostDocumentBlueprintFromDocumentResponse, GetItemDocumentBlueprintData, GetItemDocumentBlueprintResponse, GetTreeDocumentBlueprintAncestorsData, GetTreeDocumentBlueprintAncestorsResponse, GetTreeDocumentBlueprintChildrenData, GetTreeDocumentBlueprintChildrenResponse, GetTreeDocumentBlueprintRootData, GetTreeDocumentBlueprintRootResponse, PostDocumentTypeData, PostDocumentTypeResponse, GetDocumentTypeByIdData, GetDocumentTypeByIdResponse, DeleteDocumentTypeByIdData, DeleteDocumentTypeByIdResponse, PutDocumentTypeByIdData, PutDocumentTypeByIdResponse, GetDocumentTypeByIdAllowedChildrenData, GetDocumentTypeByIdAllowedChildrenResponse, GetDocumentTypeByIdBlueprintData, GetDocumentTypeByIdBlueprintResponse, GetDocumentTypeByIdCompositionReferencesData, GetDocumentTypeByIdCompositionReferencesResponse, PostDocumentTypeByIdCopyData, PostDocumentTypeByIdCopyResponse, GetDocumentTypeByIdExportData, GetDocumentTypeByIdExportResponse, PutDocumentTypeByIdImportData, PutDocumentTypeByIdImportResponse, PutDocumentTypeByIdMoveData, PutDocumentTypeByIdMoveResponse, GetDocumentTypeAllowedAtRootData, GetDocumentTypeAllowedAtRootResponse, PostDocumentTypeAvailableCompositionsData, PostDocumentTypeAvailableCompositionsResponse, GetDocumentTypeConfigurationResponse, PostDocumentTypeFolderData, PostDocumentTypeFolderResponse, GetDocumentTypeFolderByIdData, GetDocumentTypeFolderByIdResponse, DeleteDocumentTypeFolderByIdData, DeleteDocumentTypeFolderByIdResponse, PutDocumentTypeFolderByIdData, PutDocumentTypeFolderByIdResponse, PostDocumentTypeImportData, PostDocumentTypeImportResponse, GetItemDocumentTypeData, GetItemDocumentTypeResponse, GetItemDocumentTypeSearchData, GetItemDocumentTypeSearchResponse, GetTreeDocumentTypeAncestorsData, GetTreeDocumentTypeAncestorsResponse, GetTreeDocumentTypeChildrenData, GetTreeDocumentTypeChildrenResponse, GetTreeDocumentTypeRootData, GetTreeDocumentTypeRootResponse, GetDocumentVersionData, GetDocumentVersionResponse, GetDocumentVersionByIdData, GetDocumentVersionByIdResponse, PutDocumentVersionByIdPreventCleanupData, PutDocumentVersionByIdPreventCleanupResponse, PostDocumentVersionByIdRollbackData, PostDocumentVersionByIdRollbackResponse, PostDynamicRootQueryData, PostDynamicRootQueryResponse, GetDynamicRootStepsResponse, GetHealthCheckGroupData, GetHealthCheckGroupResponse, GetHealthCheckGroupByNameData, GetHealthCheckGroupByNameResponse, PostHealthCheckGroupByNameCheckData, PostHealthCheckGroupByNameCheckResponse, PostHealthCheckExecuteActionData, PostHealthCheckExecuteActionResponse, GetHelpData, GetHelpResponse, GetImagingResizeUrlsData, GetImagingResizeUrlsResponse, GetImportAnalyzeData, GetImportAnalyzeResponse, GetIndexerData, GetIndexerResponse, GetIndexerByIndexNameData, GetIndexerByIndexNameResponse, PostIndexerByIndexNameRebuildData, PostIndexerByIndexNameRebuildResponse, GetInstallSettingsResponse, PostInstallSetupData, PostInstallSetupResponse, PostInstallValidateDatabaseData, PostInstallValidateDatabaseResponse, GetItemLanguageData, GetItemLanguageResponse, GetItemLanguageDefaultResponse, GetLanguageData, GetLanguageResponse, PostLanguageData, PostLanguageResponse, GetLanguageByIsoCodeData, GetLanguageByIsoCodeResponse, DeleteLanguageByIsoCodeData, DeleteLanguageByIsoCodeResponse, PutLanguageByIsoCodeData, PutLanguageByIsoCodeResponse, GetLogViewerLevelData, GetLogViewerLevelResponse, GetLogViewerLevelCountData, GetLogViewerLevelCountResponse, GetLogViewerLogData, GetLogViewerLogResponse, GetLogViewerMessageTemplateData, GetLogViewerMessageTemplateResponse, GetLogViewerSavedSearchData, GetLogViewerSavedSearchResponse, PostLogViewerSavedSearchData, PostLogViewerSavedSearchResponse, GetLogViewerSavedSearchByNameData, GetLogViewerSavedSearchByNameResponse, DeleteLogViewerSavedSearchByNameData, DeleteLogViewerSavedSearchByNameResponse, GetLogViewerValidateLogsSizeData, GetLogViewerValidateLogsSizeResponse, GetManifestManifestResponse, GetManifestManifestPrivateResponse, GetManifestManifestPublicResponse, GetCollectionMediaData, GetCollectionMediaResponse, GetItemMediaData, GetItemMediaResponse, GetItemMediaSearchData, GetItemMediaSearchResponse, PostMediaData, PostMediaResponse, GetMediaByIdData, GetMediaByIdResponse, DeleteMediaByIdData, DeleteMediaByIdResponse, PutMediaByIdData, PutMediaByIdResponse, GetMediaByIdAuditLogData, GetMediaByIdAuditLogResponse, PutMediaByIdMoveData, PutMediaByIdMoveResponse, PutMediaByIdMoveToRecycleBinData, PutMediaByIdMoveToRecycleBinResponse, GetMediaByIdReferencedByData, GetMediaByIdReferencedByResponse, GetMediaByIdReferencedDescendantsData, GetMediaByIdReferencedDescendantsResponse, PutMediaByIdValidateData, PutMediaByIdValidateResponse, GetMediaAreReferencedData, GetMediaAreReferencedResponse, GetMediaConfigurationResponse, PutMediaSortData, PutMediaSortResponse, GetMediaUrlsData, GetMediaUrlsResponse, PostMediaValidateData, PostMediaValidateResponse, DeleteRecycleBinMediaResponse, DeleteRecycleBinMediaByIdData, DeleteRecycleBinMediaByIdResponse, GetRecycleBinMediaByIdOriginalParentData, GetRecycleBinMediaByIdOriginalParentResponse, PutRecycleBinMediaByIdRestoreData, PutRecycleBinMediaByIdRestoreResponse, GetRecycleBinMediaChildrenData, GetRecycleBinMediaChildrenResponse, GetRecycleBinMediaRootData, GetRecycleBinMediaRootResponse, GetTreeMediaAncestorsData, GetTreeMediaAncestorsResponse, GetTreeMediaChildrenData, GetTreeMediaChildrenResponse, GetTreeMediaRootData, GetTreeMediaRootResponse, GetItemMediaTypeData, GetItemMediaTypeResponse, GetItemMediaTypeAllowedData, GetItemMediaTypeAllowedResponse, GetItemMediaTypeFoldersData, GetItemMediaTypeFoldersResponse, GetItemMediaTypeSearchData, GetItemMediaTypeSearchResponse, PostMediaTypeData, PostMediaTypeResponse, GetMediaTypeByIdData, GetMediaTypeByIdResponse, DeleteMediaTypeByIdData, DeleteMediaTypeByIdResponse, PutMediaTypeByIdData, PutMediaTypeByIdResponse, GetMediaTypeByIdAllowedChildrenData, GetMediaTypeByIdAllowedChildrenResponse, GetMediaTypeByIdCompositionReferencesData, GetMediaTypeByIdCompositionReferencesResponse, PostMediaTypeByIdCopyData, PostMediaTypeByIdCopyResponse, GetMediaTypeByIdExportData, GetMediaTypeByIdExportResponse, PutMediaTypeByIdImportData, PutMediaTypeByIdImportResponse, PutMediaTypeByIdMoveData, PutMediaTypeByIdMoveResponse, GetMediaTypeAllowedAtRootData, GetMediaTypeAllowedAtRootResponse, PostMediaTypeAvailableCompositionsData, PostMediaTypeAvailableCompositionsResponse, GetMediaTypeConfigurationResponse, PostMediaTypeFolderData, PostMediaTypeFolderResponse, GetMediaTypeFolderByIdData, GetMediaTypeFolderByIdResponse, DeleteMediaTypeFolderByIdData, DeleteMediaTypeFolderByIdResponse, PutMediaTypeFolderByIdData, PutMediaTypeFolderByIdResponse, PostMediaTypeImportData, PostMediaTypeImportResponse, GetTreeMediaTypeAncestorsData, GetTreeMediaTypeAncestorsResponse, GetTreeMediaTypeChildrenData, GetTreeMediaTypeChildrenResponse, GetTreeMediaTypeRootData, GetTreeMediaTypeRootResponse, GetFilterMemberData, GetFilterMemberResponse, GetItemMemberData, GetItemMemberResponse, GetItemMemberSearchData, GetItemMemberSearchResponse, PostMemberData, PostMemberResponse, GetMemberByIdData, GetMemberByIdResponse, DeleteMemberByIdData, DeleteMemberByIdResponse, PutMemberByIdData, PutMemberByIdResponse, PutMemberByIdValidateData, PutMemberByIdValidateResponse, GetMemberConfigurationResponse, PostMemberValidateData, PostMemberValidateResponse, GetItemMemberGroupData, GetItemMemberGroupResponse, GetMemberGroupData, GetMemberGroupResponse, PostMemberGroupData, PostMemberGroupResponse, GetMemberGroupByIdData, GetMemberGroupByIdResponse, DeleteMemberGroupByIdData, DeleteMemberGroupByIdResponse, PutMemberGroupByIdData, PutMemberGroupByIdResponse, GetTreeMemberGroupRootData, GetTreeMemberGroupRootResponse, GetItemMemberTypeData, GetItemMemberTypeResponse, GetItemMemberTypeSearchData, GetItemMemberTypeSearchResponse, PostMemberTypeData, PostMemberTypeResponse, GetMemberTypeByIdData, GetMemberTypeByIdResponse, DeleteMemberTypeByIdData, DeleteMemberTypeByIdResponse, PutMemberTypeByIdData, PutMemberTypeByIdResponse, GetMemberTypeByIdCompositionReferencesData, GetMemberTypeByIdCompositionReferencesResponse, PostMemberTypeByIdCopyData, PostMemberTypeByIdCopyResponse, PostMemberTypeAvailableCompositionsData, PostMemberTypeAvailableCompositionsResponse, GetMemberTypeConfigurationResponse, GetTreeMemberTypeRootData, GetTreeMemberTypeRootResponse, PostModelsBuilderBuildResponse, GetModelsBuilderDashboardResponse, GetModelsBuilderStatusResponse, GetObjectTypesData, GetObjectTypesResponse, GetOembedQueryData, GetOembedQueryResponse, PostPackageByNameRunMigrationData, PostPackageByNameRunMigrationResponse, GetPackageConfigurationResponse, GetPackageCreatedData, GetPackageCreatedResponse, PostPackageCreatedData, PostPackageCreatedResponse, GetPackageCreatedByIdData, GetPackageCreatedByIdResponse, DeletePackageCreatedByIdData, DeletePackageCreatedByIdResponse, PutPackageCreatedByIdData, PutPackageCreatedByIdResponse, GetPackageCreatedByIdDownloadData, GetPackageCreatedByIdDownloadResponse, GetPackageMigrationStatusData, GetPackageMigrationStatusResponse, GetItemPartialViewData, GetItemPartialViewResponse, PostPartialViewData, PostPartialViewResponse, GetPartialViewByPathData, GetPartialViewByPathResponse, DeletePartialViewByPathData, DeletePartialViewByPathResponse, PutPartialViewByPathData, PutPartialViewByPathResponse, PutPartialViewByPathRenameData, PutPartialViewByPathRenameResponse, PostPartialViewFolderData, PostPartialViewFolderResponse, GetPartialViewFolderByPathData, GetPartialViewFolderByPathResponse, DeletePartialViewFolderByPathData, DeletePartialViewFolderByPathResponse, GetPartialViewSnippetData, GetPartialViewSnippetResponse, GetPartialViewSnippetByIdData, GetPartialViewSnippetByIdResponse, GetTreePartialViewAncestorsData, GetTreePartialViewAncestorsResponse, GetTreePartialViewChildrenData, GetTreePartialViewChildrenResponse, GetTreePartialViewRootData, GetTreePartialViewRootResponse, DeletePreviewResponse, PostPreviewResponse, GetProfilingStatusResponse, PutProfilingStatusData, PutProfilingStatusResponse, GetPropertyTypeIsUsedData, GetPropertyTypeIsUsedResponse, PostPublishedCacheRebuildResponse, GetPublishedCacheRebuildStatusResponse, PostPublishedCacheReloadResponse, GetRedirectManagementData, GetRedirectManagementResponse, GetRedirectManagementByIdData, GetRedirectManagementByIdResponse, DeleteRedirectManagementByIdData, DeleteRedirectManagementByIdResponse, GetRedirectManagementStatusResponse, PostRedirectManagementStatusData, PostRedirectManagementStatusResponse, GetRelationByRelationTypeIdData, GetRelationByRelationTypeIdResponse, GetItemRelationTypeData, GetItemRelationTypeResponse, GetRelationTypeData, GetRelationTypeResponse, GetRelationTypeByIdData, GetRelationTypeByIdResponse, GetItemScriptData, GetItemScriptResponse, PostScriptData, PostScriptResponse, GetScriptByPathData, GetScriptByPathResponse, DeleteScriptByPathData, DeleteScriptByPathResponse, PutScriptByPathData, PutScriptByPathResponse, PutScriptByPathRenameData, PutScriptByPathRenameResponse, PostScriptFolderData, PostScriptFolderResponse, GetScriptFolderByPathData, GetScriptFolderByPathResponse, DeleteScriptFolderByPathData, DeleteScriptFolderByPathResponse, GetTreeScriptAncestorsData, GetTreeScriptAncestorsResponse, GetTreeScriptChildrenData, GetTreeScriptChildrenResponse, GetTreeScriptRootData, GetTreeScriptRootResponse, GetSearcherData, GetSearcherResponse, GetSearcherBySearcherNameQueryData, GetSearcherBySearcherNameQueryResponse, GetSecurityConfigurationResponse, PostSecurityForgotPasswordData, PostSecurityForgotPasswordResponse, PostSecurityForgotPasswordResetData, PostSecurityForgotPasswordResetResponse, PostSecurityForgotPasswordVerifyData, PostSecurityForgotPasswordVerifyResponse, GetSegmentData, GetSegmentResponse, GetServerConfigurationResponse, GetServerInformationResponse, GetServerStatusResponse, GetServerTroubleshootingResponse, GetServerUpgradeCheckResponse, GetItemStaticFileData, GetItemStaticFileResponse, GetTreeStaticFileAncestorsData, GetTreeStaticFileAncestorsResponse, GetTreeStaticFileChildrenData, GetTreeStaticFileChildrenResponse, GetTreeStaticFileRootData, GetTreeStaticFileRootResponse, GetItemStylesheetData, GetItemStylesheetResponse, PostStylesheetData, PostStylesheetResponse, GetStylesheetByPathData, GetStylesheetByPathResponse, DeleteStylesheetByPathData, DeleteStylesheetByPathResponse, PutStylesheetByPathData, PutStylesheetByPathResponse, PutStylesheetByPathRenameData, PutStylesheetByPathRenameResponse, PostStylesheetFolderData, PostStylesheetFolderResponse, GetStylesheetFolderByPathData, GetStylesheetFolderByPathResponse, DeleteStylesheetFolderByPathData, DeleteStylesheetFolderByPathResponse, GetTreeStylesheetAncestorsData, GetTreeStylesheetAncestorsResponse, GetTreeStylesheetChildrenData, GetTreeStylesheetChildrenResponse, GetTreeStylesheetRootData, GetTreeStylesheetRootResponse, GetTagData, GetTagResponse, GetTelemetryData, GetTelemetryResponse, GetTelemetryLevelResponse, PostTelemetryLevelData, PostTelemetryLevelResponse, GetItemTemplateData, GetItemTemplateResponse, GetItemTemplateSearchData, GetItemTemplateSearchResponse, PostTemplateData, PostTemplateResponse, GetTemplateByIdData, GetTemplateByIdResponse, DeleteTemplateByIdData, DeleteTemplateByIdResponse, PutTemplateByIdData, PutTemplateByIdResponse, GetTemplateConfigurationResponse, PostTemplateQueryExecuteData, PostTemplateQueryExecuteResponse, GetTemplateQuerySettingsResponse, GetTreeTemplateAncestorsData, GetTreeTemplateAncestorsResponse, GetTreeTemplateChildrenData, GetTreeTemplateChildrenResponse, GetTreeTemplateRootData, GetTreeTemplateRootResponse, PostTemporaryFileData, PostTemporaryFileResponse, GetTemporaryFileByIdData, GetTemporaryFileByIdResponse, DeleteTemporaryFileByIdData, DeleteTemporaryFileByIdResponse, GetTemporaryFileConfigurationResponse, PostUpgradeAuthorizeResponse, GetUpgradeSettingsResponse, GetFilterUserData, GetFilterUserResponse, GetItemUserData, GetItemUserResponse, PostUserData, PostUserResponse, DeleteUserData, DeleteUserResponse, GetUserData, GetUserResponse, GetUserByIdData, GetUserByIdResponse, DeleteUserByIdData, DeleteUserByIdResponse, PutUserByIdData, PutUserByIdResponse, GetUserById2FaData, GetUserById2FaResponse, DeleteUserById2FaByProviderNameData, DeleteUserById2FaByProviderNameResponse, GetUserByIdCalculateStartNodesData, GetUserByIdCalculateStartNodesResponse, PostUserByIdChangePasswordData, PostUserByIdChangePasswordResponse, PostUserByIdClientCredentialsData, PostUserByIdClientCredentialsResponse, GetUserByIdClientCredentialsData, GetUserByIdClientCredentialsResponse, DeleteUserByIdClientCredentialsByClientIdData, DeleteUserByIdClientCredentialsByClientIdResponse, PostUserByIdResetPasswordData, PostUserByIdResetPasswordResponse, DeleteUserAvatarByIdData, DeleteUserAvatarByIdResponse, PostUserAvatarByIdData, PostUserAvatarByIdResponse, GetUserConfigurationResponse, GetUserCurrentResponse, GetUserCurrent2FaResponse, DeleteUserCurrent2FaByProviderNameData, DeleteUserCurrent2FaByProviderNameResponse, PostUserCurrent2FaByProviderNameData, PostUserCurrent2FaByProviderNameResponse, GetUserCurrent2FaByProviderNameData, GetUserCurrent2FaByProviderNameResponse, PostUserCurrentAvatarData, PostUserCurrentAvatarResponse, PostUserCurrentChangePasswordData, PostUserCurrentChangePasswordResponse, GetUserCurrentConfigurationResponse, GetUserCurrentLoginProvidersResponse, GetUserCurrentPermissionsData, GetUserCurrentPermissionsResponse, GetUserCurrentPermissionsDocumentData, GetUserCurrentPermissionsDocumentResponse, GetUserCurrentPermissionsMediaData, GetUserCurrentPermissionsMediaResponse, PostUserDisableData, PostUserDisableResponse, PostUserEnableData, PostUserEnableResponse, PostUserInviteData, PostUserInviteResponse, PostUserInviteCreatePasswordData, PostUserInviteCreatePasswordResponse, PostUserInviteResendData, PostUserInviteResendResponse, PostUserInviteVerifyData, PostUserInviteVerifyResponse, PostUserSetUserGroupsData, PostUserSetUserGroupsResponse, PostUserUnlockData, PostUserUnlockResponse, PostUserDataData, PostUserDataResponse, GetUserDataData, GetUserDataResponse, PutUserDataData, PutUserDataResponse, GetUserDataByIdData, GetUserDataByIdResponse, GetFilterUserGroupData, GetFilterUserGroupResponse, GetItemUserGroupData, GetItemUserGroupResponse, DeleteUserGroupData, DeleteUserGroupResponse, PostUserGroupData, PostUserGroupResponse, GetUserGroupData, GetUserGroupResponse, GetUserGroupByIdData, GetUserGroupByIdResponse, DeleteUserGroupByIdData, DeleteUserGroupByIdResponse, PutUserGroupByIdData, PutUserGroupByIdResponse, DeleteUserGroupByIdUsersData, DeleteUserGroupByIdUsersResponse, PostUserGroupByIdUsersData, PostUserGroupByIdUsersResponse, GetItemWebhookData, GetItemWebhookResponse, GetWebhookData, GetWebhookResponse, PostWebhookData, PostWebhookResponse, GetWebhookByIdData, GetWebhookByIdResponse, DeleteWebhookByIdData, DeleteWebhookByIdResponse, PutWebhookByIdData, PutWebhookByIdResponse, GetWebhookByIdLogsData, GetWebhookByIdLogsResponse, GetWebhookEventsData, GetWebhookEventsResponse, GetWebhookLogsData, GetWebhookLogsResponse } from './types.gen'; +import type { GetCultureData, GetCultureResponse, PostDataTypeData, PostDataTypeResponse, GetDataTypeByIdData, GetDataTypeByIdResponse, DeleteDataTypeByIdData, DeleteDataTypeByIdResponse, PutDataTypeByIdData, PutDataTypeByIdResponse, PostDataTypeByIdCopyData, PostDataTypeByIdCopyResponse, GetDataTypeByIdIsUsedData, GetDataTypeByIdIsUsedResponse, PutDataTypeByIdMoveData, PutDataTypeByIdMoveResponse, GetDataTypeByIdReferencesData, GetDataTypeByIdReferencesResponse, GetDataTypeConfigurationResponse, PostDataTypeFolderData, PostDataTypeFolderResponse, GetDataTypeFolderByIdData, GetDataTypeFolderByIdResponse, DeleteDataTypeFolderByIdData, DeleteDataTypeFolderByIdResponse, PutDataTypeFolderByIdData, PutDataTypeFolderByIdResponse, GetFilterDataTypeData, GetFilterDataTypeResponse, GetItemDataTypeData, GetItemDataTypeResponse, GetItemDataTypeSearchData, GetItemDataTypeSearchResponse, GetTreeDataTypeAncestorsData, GetTreeDataTypeAncestorsResponse, GetTreeDataTypeChildrenData, GetTreeDataTypeChildrenResponse, GetTreeDataTypeRootData, GetTreeDataTypeRootResponse, GetDictionaryData, GetDictionaryResponse, PostDictionaryData, PostDictionaryResponse, GetDictionaryByIdData, GetDictionaryByIdResponse, DeleteDictionaryByIdData, DeleteDictionaryByIdResponse, PutDictionaryByIdData, PutDictionaryByIdResponse, GetDictionaryByIdExportData, GetDictionaryByIdExportResponse, PutDictionaryByIdMoveData, PutDictionaryByIdMoveResponse, PostDictionaryImportData, PostDictionaryImportResponse, GetItemDictionaryData, GetItemDictionaryResponse, GetTreeDictionaryAncestorsData, GetTreeDictionaryAncestorsResponse, GetTreeDictionaryChildrenData, GetTreeDictionaryChildrenResponse, GetTreeDictionaryRootData, GetTreeDictionaryRootResponse, GetCollectionDocumentByIdData, GetCollectionDocumentByIdResponse, PostDocumentData, PostDocumentResponse, GetDocumentByIdData, GetDocumentByIdResponse, DeleteDocumentByIdData, DeleteDocumentByIdResponse, PutDocumentByIdData, PutDocumentByIdResponse, GetDocumentByIdAuditLogData, GetDocumentByIdAuditLogResponse, PostDocumentByIdCopyData, PostDocumentByIdCopyResponse, GetDocumentByIdDomainsData, GetDocumentByIdDomainsResponse, PutDocumentByIdDomainsData, PutDocumentByIdDomainsResponse, PutDocumentByIdMoveData, PutDocumentByIdMoveResponse, PutDocumentByIdMoveToRecycleBinData, PutDocumentByIdMoveToRecycleBinResponse, GetDocumentByIdNotificationsData, GetDocumentByIdNotificationsResponse, PutDocumentByIdNotificationsData, PutDocumentByIdNotificationsResponse, PostDocumentByIdPublicAccessData, PostDocumentByIdPublicAccessResponse, DeleteDocumentByIdPublicAccessData, DeleteDocumentByIdPublicAccessResponse, GetDocumentByIdPublicAccessData, GetDocumentByIdPublicAccessResponse, PutDocumentByIdPublicAccessData, PutDocumentByIdPublicAccessResponse, PutDocumentByIdPublishData, PutDocumentByIdPublishResponse, PutDocumentByIdPublishWithDescendantsData, PutDocumentByIdPublishWithDescendantsResponse, GetDocumentByIdPublishedData, GetDocumentByIdPublishedResponse, GetDocumentByIdReferencedByData, GetDocumentByIdReferencedByResponse, GetDocumentByIdReferencedDescendantsData, GetDocumentByIdReferencedDescendantsResponse, PutDocumentByIdUnpublishData, PutDocumentByIdUnpublishResponse, PutUmbracoManagementApiV11DocumentByIdValidate11Data, PutUmbracoManagementApiV11DocumentByIdValidate11Response, GetDocumentAreReferencedData, GetDocumentAreReferencedResponse, GetDocumentConfigurationResponse, PutDocumentSortData, PutDocumentSortResponse, GetDocumentUrlsData, GetDocumentUrlsResponse, PostDocumentValidateData, PostDocumentValidateResponse, GetItemDocumentData, GetItemDocumentResponse, GetItemDocumentSearchData, GetItemDocumentSearchResponse, DeleteRecycleBinDocumentResponse, DeleteRecycleBinDocumentByIdData, DeleteRecycleBinDocumentByIdResponse, GetRecycleBinDocumentByIdOriginalParentData, GetRecycleBinDocumentByIdOriginalParentResponse, PutRecycleBinDocumentByIdRestoreData, PutRecycleBinDocumentByIdRestoreResponse, GetRecycleBinDocumentChildrenData, GetRecycleBinDocumentChildrenResponse, GetRecycleBinDocumentRootData, GetRecycleBinDocumentRootResponse, GetTreeDocumentAncestorsData, GetTreeDocumentAncestorsResponse, GetTreeDocumentChildrenData, GetTreeDocumentChildrenResponse, GetTreeDocumentRootData, GetTreeDocumentRootResponse, PostDocumentBlueprintData, PostDocumentBlueprintResponse, GetDocumentBlueprintByIdData, GetDocumentBlueprintByIdResponse, DeleteDocumentBlueprintByIdData, DeleteDocumentBlueprintByIdResponse, PutDocumentBlueprintByIdData, PutDocumentBlueprintByIdResponse, PutDocumentBlueprintByIdMoveData, PutDocumentBlueprintByIdMoveResponse, PostDocumentBlueprintFolderData, PostDocumentBlueprintFolderResponse, GetDocumentBlueprintFolderByIdData, GetDocumentBlueprintFolderByIdResponse, DeleteDocumentBlueprintFolderByIdData, DeleteDocumentBlueprintFolderByIdResponse, PutDocumentBlueprintFolderByIdData, PutDocumentBlueprintFolderByIdResponse, PostDocumentBlueprintFromDocumentData, PostDocumentBlueprintFromDocumentResponse, GetItemDocumentBlueprintData, GetItemDocumentBlueprintResponse, GetTreeDocumentBlueprintAncestorsData, GetTreeDocumentBlueprintAncestorsResponse, GetTreeDocumentBlueprintChildrenData, GetTreeDocumentBlueprintChildrenResponse, GetTreeDocumentBlueprintRootData, GetTreeDocumentBlueprintRootResponse, PostDocumentTypeData, PostDocumentTypeResponse, GetDocumentTypeByIdData, GetDocumentTypeByIdResponse, DeleteDocumentTypeByIdData, DeleteDocumentTypeByIdResponse, PutDocumentTypeByIdData, PutDocumentTypeByIdResponse, GetDocumentTypeByIdAllowedChildrenData, GetDocumentTypeByIdAllowedChildrenResponse, GetDocumentTypeByIdBlueprintData, GetDocumentTypeByIdBlueprintResponse, GetDocumentTypeByIdCompositionReferencesData, GetDocumentTypeByIdCompositionReferencesResponse, PostDocumentTypeByIdCopyData, PostDocumentTypeByIdCopyResponse, GetDocumentTypeByIdExportData, GetDocumentTypeByIdExportResponse, PutDocumentTypeByIdImportData, PutDocumentTypeByIdImportResponse, PutDocumentTypeByIdMoveData, PutDocumentTypeByIdMoveResponse, GetDocumentTypeAllowedAtRootData, GetDocumentTypeAllowedAtRootResponse, PostDocumentTypeAvailableCompositionsData, PostDocumentTypeAvailableCompositionsResponse, GetDocumentTypeConfigurationResponse, PostDocumentTypeFolderData, PostDocumentTypeFolderResponse, GetDocumentTypeFolderByIdData, GetDocumentTypeFolderByIdResponse, DeleteDocumentTypeFolderByIdData, DeleteDocumentTypeFolderByIdResponse, PutDocumentTypeFolderByIdData, PutDocumentTypeFolderByIdResponse, PostDocumentTypeImportData, PostDocumentTypeImportResponse, GetItemDocumentTypeData, GetItemDocumentTypeResponse, GetItemDocumentTypeSearchData, GetItemDocumentTypeSearchResponse, GetTreeDocumentTypeAncestorsData, GetTreeDocumentTypeAncestorsResponse, GetTreeDocumentTypeChildrenData, GetTreeDocumentTypeChildrenResponse, GetTreeDocumentTypeRootData, GetTreeDocumentTypeRootResponse, GetDocumentVersionData, GetDocumentVersionResponse, GetDocumentVersionByIdData, GetDocumentVersionByIdResponse, PutDocumentVersionByIdPreventCleanupData, PutDocumentVersionByIdPreventCleanupResponse, PostDocumentVersionByIdRollbackData, PostDocumentVersionByIdRollbackResponse, PostDynamicRootQueryData, PostDynamicRootQueryResponse, GetDynamicRootStepsResponse, GetHealthCheckGroupData, GetHealthCheckGroupResponse, GetHealthCheckGroupByNameData, GetHealthCheckGroupByNameResponse, PostHealthCheckGroupByNameCheckData, PostHealthCheckGroupByNameCheckResponse, PostHealthCheckExecuteActionData, PostHealthCheckExecuteActionResponse, GetHelpData, GetHelpResponse, GetImagingResizeUrlsData, GetImagingResizeUrlsResponse, GetImportAnalyzeData, GetImportAnalyzeResponse, GetIndexerData, GetIndexerResponse, GetIndexerByIndexNameData, GetIndexerByIndexNameResponse, PostIndexerByIndexNameRebuildData, PostIndexerByIndexNameRebuildResponse, GetInstallSettingsResponse, PostInstallSetupData, PostInstallSetupResponse, PostInstallValidateDatabaseData, PostInstallValidateDatabaseResponse, GetItemLanguageData, GetItemLanguageResponse, GetItemLanguageDefaultResponse, GetLanguageData, GetLanguageResponse, PostLanguageData, PostLanguageResponse, GetLanguageByIsoCodeData, GetLanguageByIsoCodeResponse, DeleteLanguageByIsoCodeData, DeleteLanguageByIsoCodeResponse, PutLanguageByIsoCodeData, PutLanguageByIsoCodeResponse, GetLogViewerLevelData, GetLogViewerLevelResponse, GetLogViewerLevelCountData, GetLogViewerLevelCountResponse, GetLogViewerLogData, GetLogViewerLogResponse, GetLogViewerMessageTemplateData, GetLogViewerMessageTemplateResponse, GetLogViewerSavedSearchData, GetLogViewerSavedSearchResponse, PostLogViewerSavedSearchData, PostLogViewerSavedSearchResponse, GetLogViewerSavedSearchByNameData, GetLogViewerSavedSearchByNameResponse, DeleteLogViewerSavedSearchByNameData, DeleteLogViewerSavedSearchByNameResponse, GetLogViewerValidateLogsSizeData, GetLogViewerValidateLogsSizeResponse, GetManifestManifestResponse, GetManifestManifestPrivateResponse, GetManifestManifestPublicResponse, GetCollectionMediaData, GetCollectionMediaResponse, GetItemMediaData, GetItemMediaResponse, GetItemMediaSearchData, GetItemMediaSearchResponse, PostMediaData, PostMediaResponse, GetMediaByIdData, GetMediaByIdResponse, DeleteMediaByIdData, DeleteMediaByIdResponse, PutMediaByIdData, PutMediaByIdResponse, GetMediaByIdAuditLogData, GetMediaByIdAuditLogResponse, PutMediaByIdMoveData, PutMediaByIdMoveResponse, PutMediaByIdMoveToRecycleBinData, PutMediaByIdMoveToRecycleBinResponse, GetMediaByIdReferencedByData, GetMediaByIdReferencedByResponse, GetMediaByIdReferencedDescendantsData, GetMediaByIdReferencedDescendantsResponse, PutMediaByIdValidateData, PutMediaByIdValidateResponse, GetMediaAreReferencedData, GetMediaAreReferencedResponse, GetMediaConfigurationResponse, PutMediaSortData, PutMediaSortResponse, GetMediaUrlsData, GetMediaUrlsResponse, PostMediaValidateData, PostMediaValidateResponse, DeleteRecycleBinMediaResponse, DeleteRecycleBinMediaByIdData, DeleteRecycleBinMediaByIdResponse, GetRecycleBinMediaByIdOriginalParentData, GetRecycleBinMediaByIdOriginalParentResponse, PutRecycleBinMediaByIdRestoreData, PutRecycleBinMediaByIdRestoreResponse, GetRecycleBinMediaChildrenData, GetRecycleBinMediaChildrenResponse, GetRecycleBinMediaRootData, GetRecycleBinMediaRootResponse, GetTreeMediaAncestorsData, GetTreeMediaAncestorsResponse, GetTreeMediaChildrenData, GetTreeMediaChildrenResponse, GetTreeMediaRootData, GetTreeMediaRootResponse, GetItemMediaTypeData, GetItemMediaTypeResponse, GetItemMediaTypeAllowedData, GetItemMediaTypeAllowedResponse, GetItemMediaTypeFoldersData, GetItemMediaTypeFoldersResponse, GetItemMediaTypeSearchData, GetItemMediaTypeSearchResponse, PostMediaTypeData, PostMediaTypeResponse, GetMediaTypeByIdData, GetMediaTypeByIdResponse, DeleteMediaTypeByIdData, DeleteMediaTypeByIdResponse, PutMediaTypeByIdData, PutMediaTypeByIdResponse, GetMediaTypeByIdAllowedChildrenData, GetMediaTypeByIdAllowedChildrenResponse, GetMediaTypeByIdCompositionReferencesData, GetMediaTypeByIdCompositionReferencesResponse, PostMediaTypeByIdCopyData, PostMediaTypeByIdCopyResponse, GetMediaTypeByIdExportData, GetMediaTypeByIdExportResponse, PutMediaTypeByIdImportData, PutMediaTypeByIdImportResponse, PutMediaTypeByIdMoveData, PutMediaTypeByIdMoveResponse, GetMediaTypeAllowedAtRootData, GetMediaTypeAllowedAtRootResponse, PostMediaTypeAvailableCompositionsData, PostMediaTypeAvailableCompositionsResponse, GetMediaTypeConfigurationResponse, PostMediaTypeFolderData, PostMediaTypeFolderResponse, GetMediaTypeFolderByIdData, GetMediaTypeFolderByIdResponse, DeleteMediaTypeFolderByIdData, DeleteMediaTypeFolderByIdResponse, PutMediaTypeFolderByIdData, PutMediaTypeFolderByIdResponse, PostMediaTypeImportData, PostMediaTypeImportResponse, GetTreeMediaTypeAncestorsData, GetTreeMediaTypeAncestorsResponse, GetTreeMediaTypeChildrenData, GetTreeMediaTypeChildrenResponse, GetTreeMediaTypeRootData, GetTreeMediaTypeRootResponse, GetFilterMemberData, GetFilterMemberResponse, GetItemMemberData, GetItemMemberResponse, GetItemMemberSearchData, GetItemMemberSearchResponse, PostMemberData, PostMemberResponse, GetMemberByIdData, GetMemberByIdResponse, DeleteMemberByIdData, DeleteMemberByIdResponse, PutMemberByIdData, PutMemberByIdResponse, GetMemberByIdReferencedByData, GetMemberByIdReferencedByResponse, GetMemberByIdReferencedDescendantsData, GetMemberByIdReferencedDescendantsResponse, PutMemberByIdValidateData, PutMemberByIdValidateResponse, GetMemberAreReferencedData, GetMemberAreReferencedResponse, GetMemberConfigurationResponse, PostMemberValidateData, PostMemberValidateResponse, GetItemMemberGroupData, GetItemMemberGroupResponse, GetMemberGroupData, GetMemberGroupResponse, PostMemberGroupData, PostMemberGroupResponse, GetMemberGroupByIdData, GetMemberGroupByIdResponse, DeleteMemberGroupByIdData, DeleteMemberGroupByIdResponse, PutMemberGroupByIdData, PutMemberGroupByIdResponse, GetTreeMemberGroupRootData, GetTreeMemberGroupRootResponse, GetItemMemberTypeData, GetItemMemberTypeResponse, GetItemMemberTypeSearchData, GetItemMemberTypeSearchResponse, PostMemberTypeData, PostMemberTypeResponse, GetMemberTypeByIdData, GetMemberTypeByIdResponse, DeleteMemberTypeByIdData, DeleteMemberTypeByIdResponse, PutMemberTypeByIdData, PutMemberTypeByIdResponse, GetMemberTypeByIdCompositionReferencesData, GetMemberTypeByIdCompositionReferencesResponse, PostMemberTypeByIdCopyData, PostMemberTypeByIdCopyResponse, PostMemberTypeAvailableCompositionsData, PostMemberTypeAvailableCompositionsResponse, GetMemberTypeConfigurationResponse, GetTreeMemberTypeRootData, GetTreeMemberTypeRootResponse, PostModelsBuilderBuildResponse, GetModelsBuilderDashboardResponse, GetModelsBuilderStatusResponse, GetObjectTypesData, GetObjectTypesResponse, GetOembedQueryData, GetOembedQueryResponse, PostPackageByNameRunMigrationData, PostPackageByNameRunMigrationResponse, GetPackageConfigurationResponse, GetPackageCreatedData, GetPackageCreatedResponse, PostPackageCreatedData, PostPackageCreatedResponse, GetPackageCreatedByIdData, GetPackageCreatedByIdResponse, DeletePackageCreatedByIdData, DeletePackageCreatedByIdResponse, PutPackageCreatedByIdData, PutPackageCreatedByIdResponse, GetPackageCreatedByIdDownloadData, GetPackageCreatedByIdDownloadResponse, GetPackageMigrationStatusData, GetPackageMigrationStatusResponse, GetItemPartialViewData, GetItemPartialViewResponse, PostPartialViewData, PostPartialViewResponse, GetPartialViewByPathData, GetPartialViewByPathResponse, DeletePartialViewByPathData, DeletePartialViewByPathResponse, PutPartialViewByPathData, PutPartialViewByPathResponse, PutPartialViewByPathRenameData, PutPartialViewByPathRenameResponse, PostPartialViewFolderData, PostPartialViewFolderResponse, GetPartialViewFolderByPathData, GetPartialViewFolderByPathResponse, DeletePartialViewFolderByPathData, DeletePartialViewFolderByPathResponse, GetPartialViewSnippetData, GetPartialViewSnippetResponse, GetPartialViewSnippetByIdData, GetPartialViewSnippetByIdResponse, GetTreePartialViewAncestorsData, GetTreePartialViewAncestorsResponse, GetTreePartialViewChildrenData, GetTreePartialViewChildrenResponse, GetTreePartialViewRootData, GetTreePartialViewRootResponse, DeletePreviewResponse, PostPreviewResponse, GetProfilingStatusResponse, PutProfilingStatusData, PutProfilingStatusResponse, GetPropertyTypeIsUsedData, GetPropertyTypeIsUsedResponse, PostPublishedCacheRebuildResponse, GetPublishedCacheRebuildStatusResponse, PostPublishedCacheReloadResponse, GetRedirectManagementData, GetRedirectManagementResponse, GetRedirectManagementByIdData, GetRedirectManagementByIdResponse, DeleteRedirectManagementByIdData, DeleteRedirectManagementByIdResponse, GetRedirectManagementStatusResponse, PostRedirectManagementStatusData, PostRedirectManagementStatusResponse, GetRelationByRelationTypeIdData, GetRelationByRelationTypeIdResponse, GetItemRelationTypeData, GetItemRelationTypeResponse, GetRelationTypeData, GetRelationTypeResponse, GetRelationTypeByIdData, GetRelationTypeByIdResponse, GetItemScriptData, GetItemScriptResponse, PostScriptData, PostScriptResponse, GetScriptByPathData, GetScriptByPathResponse, DeleteScriptByPathData, DeleteScriptByPathResponse, PutScriptByPathData, PutScriptByPathResponse, PutScriptByPathRenameData, PutScriptByPathRenameResponse, PostScriptFolderData, PostScriptFolderResponse, GetScriptFolderByPathData, GetScriptFolderByPathResponse, DeleteScriptFolderByPathData, DeleteScriptFolderByPathResponse, GetTreeScriptAncestorsData, GetTreeScriptAncestorsResponse, GetTreeScriptChildrenData, GetTreeScriptChildrenResponse, GetTreeScriptRootData, GetTreeScriptRootResponse, GetSearcherData, GetSearcherResponse, GetSearcherBySearcherNameQueryData, GetSearcherBySearcherNameQueryResponse, GetSecurityConfigurationResponse, PostSecurityForgotPasswordData, PostSecurityForgotPasswordResponse, PostSecurityForgotPasswordResetData, PostSecurityForgotPasswordResetResponse, PostSecurityForgotPasswordVerifyData, PostSecurityForgotPasswordVerifyResponse, GetSegmentData, GetSegmentResponse, GetServerConfigurationResponse, GetServerInformationResponse, GetServerStatusResponse, GetServerTroubleshootingResponse, GetServerUpgradeCheckResponse, GetItemStaticFileData, GetItemStaticFileResponse, GetTreeStaticFileAncestorsData, GetTreeStaticFileAncestorsResponse, GetTreeStaticFileChildrenData, GetTreeStaticFileChildrenResponse, GetTreeStaticFileRootData, GetTreeStaticFileRootResponse, GetItemStylesheetData, GetItemStylesheetResponse, PostStylesheetData, PostStylesheetResponse, GetStylesheetByPathData, GetStylesheetByPathResponse, DeleteStylesheetByPathData, DeleteStylesheetByPathResponse, PutStylesheetByPathData, PutStylesheetByPathResponse, PutStylesheetByPathRenameData, PutStylesheetByPathRenameResponse, PostStylesheetFolderData, PostStylesheetFolderResponse, GetStylesheetFolderByPathData, GetStylesheetFolderByPathResponse, DeleteStylesheetFolderByPathData, DeleteStylesheetFolderByPathResponse, GetTreeStylesheetAncestorsData, GetTreeStylesheetAncestorsResponse, GetTreeStylesheetChildrenData, GetTreeStylesheetChildrenResponse, GetTreeStylesheetRootData, GetTreeStylesheetRootResponse, GetTagData, GetTagResponse, GetTelemetryData, GetTelemetryResponse, GetTelemetryLevelResponse, PostTelemetryLevelData, PostTelemetryLevelResponse, GetItemTemplateData, GetItemTemplateResponse, GetItemTemplateSearchData, GetItemTemplateSearchResponse, PostTemplateData, PostTemplateResponse, GetTemplateByIdData, GetTemplateByIdResponse, DeleteTemplateByIdData, DeleteTemplateByIdResponse, PutTemplateByIdData, PutTemplateByIdResponse, GetTemplateConfigurationResponse, PostTemplateQueryExecuteData, PostTemplateQueryExecuteResponse, GetTemplateQuerySettingsResponse, GetTreeTemplateAncestorsData, GetTreeTemplateAncestorsResponse, GetTreeTemplateChildrenData, GetTreeTemplateChildrenResponse, GetTreeTemplateRootData, GetTreeTemplateRootResponse, PostTemporaryFileData, PostTemporaryFileResponse, GetTemporaryFileByIdData, GetTemporaryFileByIdResponse, DeleteTemporaryFileByIdData, DeleteTemporaryFileByIdResponse, GetTemporaryFileConfigurationResponse, PostUpgradeAuthorizeResponse, GetUpgradeSettingsResponse, GetFilterUserData, GetFilterUserResponse, GetItemUserData, GetItemUserResponse, PostUserData, PostUserResponse, DeleteUserData, DeleteUserResponse, GetUserData, GetUserResponse, GetUserByIdData, GetUserByIdResponse, DeleteUserByIdData, DeleteUserByIdResponse, PutUserByIdData, PutUserByIdResponse, GetUserById2FaData, GetUserById2FaResponse, DeleteUserById2FaByProviderNameData, DeleteUserById2FaByProviderNameResponse, GetUserByIdCalculateStartNodesData, GetUserByIdCalculateStartNodesResponse, PostUserByIdChangePasswordData, PostUserByIdChangePasswordResponse, PostUserByIdClientCredentialsData, PostUserByIdClientCredentialsResponse, GetUserByIdClientCredentialsData, GetUserByIdClientCredentialsResponse, DeleteUserByIdClientCredentialsByClientIdData, DeleteUserByIdClientCredentialsByClientIdResponse, PostUserByIdResetPasswordData, PostUserByIdResetPasswordResponse, DeleteUserAvatarByIdData, DeleteUserAvatarByIdResponse, PostUserAvatarByIdData, PostUserAvatarByIdResponse, GetUserConfigurationResponse, GetUserCurrentResponse, GetUserCurrent2FaResponse, DeleteUserCurrent2FaByProviderNameData, DeleteUserCurrent2FaByProviderNameResponse, PostUserCurrent2FaByProviderNameData, PostUserCurrent2FaByProviderNameResponse, GetUserCurrent2FaByProviderNameData, GetUserCurrent2FaByProviderNameResponse, PostUserCurrentAvatarData, PostUserCurrentAvatarResponse, PostUserCurrentChangePasswordData, PostUserCurrentChangePasswordResponse, GetUserCurrentConfigurationResponse, GetUserCurrentLoginProvidersResponse, GetUserCurrentPermissionsData, GetUserCurrentPermissionsResponse, GetUserCurrentPermissionsDocumentData, GetUserCurrentPermissionsDocumentResponse, GetUserCurrentPermissionsMediaData, GetUserCurrentPermissionsMediaResponse, PostUserDisableData, PostUserDisableResponse, PostUserEnableData, PostUserEnableResponse, PostUserInviteData, PostUserInviteResponse, PostUserInviteCreatePasswordData, PostUserInviteCreatePasswordResponse, PostUserInviteResendData, PostUserInviteResendResponse, PostUserInviteVerifyData, PostUserInviteVerifyResponse, PostUserSetUserGroupsData, PostUserSetUserGroupsResponse, PostUserUnlockData, PostUserUnlockResponse, PostUserDataData, PostUserDataResponse, GetUserDataData, GetUserDataResponse, PutUserDataData, PutUserDataResponse, GetUserDataByIdData, GetUserDataByIdResponse, GetFilterUserGroupData, GetFilterUserGroupResponse, GetItemUserGroupData, GetItemUserGroupResponse, DeleteUserGroupData, DeleteUserGroupResponse, PostUserGroupData, PostUserGroupResponse, GetUserGroupData, GetUserGroupResponse, GetUserGroupByIdData, GetUserGroupByIdResponse, DeleteUserGroupByIdData, DeleteUserGroupByIdResponse, PutUserGroupByIdData, PutUserGroupByIdResponse, DeleteUserGroupByIdUsersData, DeleteUserGroupByIdUsersResponse, PostUserGroupByIdUsersData, PostUserGroupByIdUsersResponse, GetItemWebhookData, GetItemWebhookResponse, GetWebhookData, GetWebhookResponse, PostWebhookData, PostWebhookResponse, GetWebhookByIdData, GetWebhookByIdResponse, DeleteWebhookByIdData, DeleteWebhookByIdResponse, PutWebhookByIdData, PutWebhookByIdResponse, GetWebhookByIdLogsData, GetWebhookByIdLogsResponse, GetWebhookEventsData, GetWebhookEventsResponse, GetWebhookLogsData, GetWebhookLogsResponse } from './types.gen'; export class CultureService { /** @@ -1464,6 +1464,7 @@ export class DocumentService { /** * @param data The data for the request. * @param data.query + * @param data.trashed * @param data.skip * @param data.take * @param data.parentId @@ -1477,6 +1478,7 @@ export class DocumentService { url: '/umbraco/management/api/v1/item/document/search', query: { query: data.query, + trashed: data.trashed, skip: data.skip, take: data.take, parentId: data.parentId, @@ -2477,6 +2479,7 @@ export class DocumentTypeService { /** * @param data The data for the request. * @param data.query + * @param data.isElement * @param data.skip * @param data.take * @returns unknown OK @@ -2488,6 +2491,7 @@ export class DocumentTypeService { url: '/umbraco/management/api/v1/item/document-type/search', query: { query: data.query, + isElement: data.isElement, skip: data.skip, take: data.take }, @@ -3471,6 +3475,7 @@ export class MediaService { /** * @param data The data for the request. * @param data.query + * @param data.trashed * @param data.skip * @param data.take * @param data.parentId @@ -3484,6 +3489,7 @@ export class MediaService { url: '/umbraco/management/api/v1/item/media/search', query: { query: data.query, + trashed: data.trashed, skip: data.skip, take: data.take, parentId: data.parentId, @@ -4797,6 +4803,58 @@ export class MemberService { }); } + /** + * @param data The data for the request. + * @param data.id + * @param data.skip + * @param data.take + * @returns unknown OK + * @throws ApiError + */ + public static getMemberByIdReferencedBy(data: GetMemberByIdReferencedByData): CancelablePromise { + return __request(OpenAPI, { + method: 'GET', + url: '/umbraco/management/api/v1/member/{id}/referenced-by', + path: { + id: data.id + }, + query: { + skip: data.skip, + take: data.take + }, + errors: { + 401: 'The resource is protected and requires an authentication token', + 403: 'The authenticated user does not have access to this resource' + } + }); + } + + /** + * @param data The data for the request. + * @param data.id + * @param data.skip + * @param data.take + * @returns unknown OK + * @throws ApiError + */ + public static getMemberByIdReferencedDescendants(data: GetMemberByIdReferencedDescendantsData): CancelablePromise { + return __request(OpenAPI, { + method: 'GET', + url: '/umbraco/management/api/v1/member/{id}/referenced-descendants', + path: { + id: data.id + }, + query: { + skip: data.skip, + take: data.take + }, + errors: { + 401: 'The resource is protected and requires an authentication token', + 403: 'The authenticated user does not have access to this resource' + } + }); + } + /** * @param data The data for the request. * @param data.id @@ -4823,6 +4881,30 @@ export class MemberService { }); } + /** + * @param data The data for the request. + * @param data.id + * @param data.skip + * @param data.take + * @returns unknown OK + * @throws ApiError + */ + public static getMemberAreReferenced(data: GetMemberAreReferencedData = {}): CancelablePromise { + return __request(OpenAPI, { + method: 'GET', + url: '/umbraco/management/api/v1/member/are-referenced', + query: { + id: data.id, + skip: data.skip, + take: data.take + }, + errors: { + 401: 'The resource is protected and requires an authentication token', + 403: 'The authenticated user does not have access to this resource' + } + }); + } + /** * @returns unknown OK * @throws ApiError diff --git a/src/Umbraco.Web.UI.Client/src/external/backend-api/src/types.gen.ts b/src/Umbraco.Web.UI.Client/src/external/backend-api/src/types.gen.ts index be037a53dc..3a826a3c86 100644 --- a/src/Umbraco.Web.UI.Client/src/external/backend-api/src/types.gen.ts +++ b/src/Umbraco.Web.UI.Client/src/external/backend-api/src/types.gen.ts @@ -686,6 +686,7 @@ export type DocumentReferenceResponseModel = { name?: (string) | null; published?: (boolean) | null; documentType: (TrackedReferenceDocumentTypeModel); + variants: Array<(DocumentVariantItemResponseModel)>; }; export type DocumentResponseModel = { @@ -1391,6 +1392,13 @@ export enum MemberKindModel { API = 'Api' } +export type MemberReferenceResponseModel = { + $type: string; + id: string; + name?: (string) | null; + memberType: (TrackedReferenceMemberTypeModel); +}; + export type MemberResponseModel = { values: Array<(MemberValueResponseModel)>; variants: Array<(MemberVariantResponseModel)>; @@ -1736,7 +1744,7 @@ export type PagedIndexResponseModel = { export type PagedIReferenceResponseModel = { total: number; - items: Array<(DefaultReferenceResponseModel | DocumentReferenceResponseModel | MediaReferenceResponseModel)>; + items: Array<(DefaultReferenceResponseModel | DocumentReferenceResponseModel | MediaReferenceResponseModel | MemberReferenceResponseModel)>; }; export type PagedLanguageResponseModel = { @@ -2392,6 +2400,12 @@ export type TrackedReferenceMediaTypeModel = { name?: (string) | null; }; +export type TrackedReferenceMemberTypeModel = { + icon?: (string) | null; + alias?: (string) | null; + name?: (string) | null; +}; + export type UnknownTypePermissionPresentationModel = { $type: string; verbs: Array<(string)>; @@ -3335,6 +3349,7 @@ export type GetItemDocumentSearchData = { query?: string; skip?: number; take?: number; + trashed?: boolean; }; export type GetItemDocumentSearchResponse = ((PagedModelDocumentItemResponseModel)); @@ -3618,6 +3633,7 @@ export type GetItemDocumentTypeData = { export type GetItemDocumentTypeResponse = (Array<(DocumentTypeItemResponseModel)>); export type GetItemDocumentTypeSearchData = { + isElement?: boolean; query?: string; skip?: number; take?: number; @@ -3905,6 +3921,7 @@ export type GetItemMediaSearchData = { query?: string; skip?: number; take?: number; + trashed?: boolean; }; export type GetItemMediaSearchResponse = ((PagedModelMediaItemResponseModel)); @@ -4286,6 +4303,22 @@ export type PutMemberByIdData = { export type PutMemberByIdResponse = (string); +export type GetMemberByIdReferencedByData = { + id: string; + skip?: number; + take?: number; +}; + +export type GetMemberByIdReferencedByResponse = ((PagedIReferenceResponseModel)); + +export type GetMemberByIdReferencedDescendantsData = { + id: string; + skip?: number; + take?: number; +}; + +export type GetMemberByIdReferencedDescendantsResponse = ((PagedReferenceByIdModel)); + export type PutMemberByIdValidateData = { id: string; requestBody?: (UpdateMemberRequestModel); @@ -4293,6 +4326,14 @@ export type PutMemberByIdValidateData = { export type PutMemberByIdValidateResponse = (string); +export type GetMemberAreReferencedData = { + id?: Array<(string)>; + skip?: number; + take?: number; +}; + +export type GetMemberAreReferencedResponse = ((PagedReferenceByIdModel)); + export type GetMemberConfigurationResponse = ((MemberConfigurationResponseModel)); export type PostMemberValidateData = { diff --git a/src/Umbraco.Web.UI.Client/src/external/router-slot/util/router.ts b/src/Umbraco.Web.UI.Client/src/external/router-slot/util/router.ts index 0602181f10..7c731abe59 100644 --- a/src/Umbraco.Web.UI.Client/src/external/router-slot/util/router.ts +++ b/src/Umbraco.Web.UI.Client/src/external/router-slot/util/router.ts @@ -160,7 +160,7 @@ export async function resolvePageComponent(route: IComponentRoute, info: IRoutin // Setup the component using the callback. if (route.setup != null) { - route.setup(component, info); + await route.setup(component, info); } return component; diff --git a/src/Umbraco.Web.UI.Client/src/libs/context-api/provide/context-provider.ts b/src/Umbraco.Web.UI.Client/src/libs/context-api/provide/context-provider.ts index 8ac0fd6795..9c729080e2 100644 --- a/src/Umbraco.Web.UI.Client/src/libs/context-api/provide/context-provider.ts +++ b/src/Umbraco.Web.UI.Client/src/libs/context-api/provide/context-provider.ts @@ -105,8 +105,7 @@ export class UmbContextProvider { expect(controller.duration(inTenSeconds, now)).to.equal('10 seconds'); }); - it('should compare between two dates', () => { - const twoDaysAgo = new Date(); - twoDaysAgo.setDate(twoDaysAgo.getDate() - 2); - const inTwoDays = new Date(); - inTwoDays.setDate(inTwoDays.getDate() + 2); - - expect(controller.duration(inTwoDays, twoDaysAgo)).to.equal('4 days'); - }); - it('should return a negative duration', () => { expect(controller.duration('2020-01-01', '2019-12-30')).to.equal('2 days'); }); - - it('should update the relative compounded time when the language changes', async () => { - const now = new Date(); - const inTwoDays = new Date(); - inTwoDays.setDate(inTwoDays.getDate() + 2); - - expect(controller.duration(inTwoDays, now)).to.equal('2 days'); - - // Switch browser to Danish - document.documentElement.lang = danishRegional.$code; - await aTimeout(0); - - expect(controller.duration(inTwoDays, now)).to.equal('2 dage'); - }); }); describe('list format', () => { diff --git a/src/Umbraco.Web.UI.Client/src/mocks/data/tracked-reference.data.ts b/src/Umbraco.Web.UI.Client/src/mocks/data/tracked-reference.data.ts index bbd02fb59b..1137b79c47 100644 --- a/src/Umbraco.Web.UI.Client/src/mocks/data/tracked-reference.data.ts +++ b/src/Umbraco.Web.UI.Client/src/mocks/data/tracked-reference.data.ts @@ -2,10 +2,11 @@ import type { DefaultReferenceResponseModel, DocumentReferenceResponseModel, MediaReferenceResponseModel, + MemberReferenceResponseModel, } from '@umbraco-cms/backoffice/external/backend-api'; export const items: Array< - DefaultReferenceResponseModel | DocumentReferenceResponseModel | MediaReferenceResponseModel + DefaultReferenceResponseModel | DocumentReferenceResponseModel | MediaReferenceResponseModel | MemberReferenceResponseModel > = [ { $type: 'DocumentReferenceResponseModel', @@ -17,6 +18,7 @@ export const items: Array< icon: 'icon-document', name: 'Simple Document Type', }, + variants: [] } satisfies DocumentReferenceResponseModel, { $type: 'DocumentReferenceResponseModel', @@ -28,6 +30,7 @@ export const items: Array< icon: 'icon-settings', name: 'Image Block', }, + variants: [] } satisfies DocumentReferenceResponseModel, { $type: 'MediaReferenceResponseModel', diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/block-grid-manager/block-grid-manager.context.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/block-grid-manager/block-grid-manager.context.ts index 31ef32310f..4c2c68ffa8 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/block-grid-manager/block-grid-manager.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/block-grid-manager/block-grid-manager.context.ts @@ -10,7 +10,7 @@ import { import { transformServerPathToClientPath } from '@umbraco-cms/backoffice/utils'; import { UmbBlockManagerContext } from '@umbraco-cms/backoffice/block'; import { UMB_APP_CONTEXT } from '@umbraco-cms/backoffice/app'; -import type { UmbBlockDataModel, UmbBlockDataObjectModel } from '@umbraco-cms/backoffice/block'; +import type { UmbBlockDataModel } from '@umbraco-cms/backoffice/block'; import type { UmbBlockTypeGroup } from '@umbraco-cms/backoffice/block-type'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; import type { UmbNumberRangeValueType } from '@umbraco-cms/backoffice/models'; @@ -105,9 +105,8 @@ export class UmbBlockGridManagerContext< // This property is used by some implementations, but not used in this. Do not remove. [NL] // eslint-disable-next-line @typescript-eslint/no-unused-vars _originData?: UmbBlockGridWorkspaceOriginData, - ) { + ): never { throw new Error('Method deparecated use createWithPresets'); - return {} as UmbBlockDataObjectModel; } async createWithPresets( diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block-list/context/block-list-manager.context.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block-list/context/block-list-manager.context.ts index c8c66a1a3a..1f9b8da98f 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/block/block-list/context/block-list-manager.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/block/block-list/context/block-list-manager.context.ts @@ -2,7 +2,7 @@ import type { UmbBlockListLayoutModel, UmbBlockListTypeModel } from '../types.js import type { UmbBlockListWorkspaceOriginData } from '../index.js'; import type { UmbBlockDataModel } from '../../block/types.js'; import { UmbBooleanState } from '@umbraco-cms/backoffice/observable-api'; -import { UmbBlockManagerContext, type UmbBlockDataObjectModel } from '@umbraco-cms/backoffice/block'; +import { UmbBlockManagerContext } from '@umbraco-cms/backoffice/block'; /** * A implementation of the Block Manager specifically for the Block List Editor. @@ -35,9 +35,8 @@ export class UmbBlockListManagerContext< // This property is used by some implementations, but not used in this. Do not remove. [NL] // eslint-disable-next-line @typescript-eslint/no-unused-vars _originData?: UmbBlockListWorkspaceOriginData, - ) { + ): never { throw new Error('Method deparecated use createWithPresets'); - return {} as UmbBlockDataObjectModel; } async createWithPresets( contentElementTypeKey: string, diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block-rte/context/block-rte-manager.context.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block-rte/context/block-rte-manager.context.ts index 79cfb81b40..c18d7b9b7c 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/block/block-rte/context/block-rte-manager.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/block/block-rte/context/block-rte-manager.context.ts @@ -1,7 +1,7 @@ import type { UmbBlockRteWorkspaceOriginData } from '../workspace/block-rte-workspace.modal-token.js'; import type { UmbBlockRteLayoutModel, UmbBlockRteTypeModel } from '../types.js'; import type { UmbBlockDataModel } from '../../block/types.js'; -import { UmbBlockManagerContext, type UmbBlockDataObjectModel } from '@umbraco-cms/backoffice/block'; +import { UmbBlockManagerContext } from '@umbraco-cms/backoffice/block'; import '../components/block-rte-entry/index.js'; @@ -32,9 +32,8 @@ export class UmbBlockRteManagerContext< // This property is used by some implementations, but not used in this. Do not remove. [NL] // eslint-disable-next-line @typescript-eslint/no-unused-vars _originData?: UmbBlockRteWorkspaceOriginData, - ) { + ): never { throw new Error('Method deparecated use createWithPresets'); - return {} as UmbBlockDataObjectModel; } async createWithPresets( contentElementTypeKey: string, diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block/context/block-manager.context.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block/context/block-manager.context.ts index da15247980..64bd00ab96 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/block/block/context/block-manager.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/block/block/context/block-manager.context.ts @@ -334,7 +334,7 @@ export abstract class UmbBlockManagerContext< contentElementTypeKey: string, partialLayoutEntry?: Omit, originData?: BlockOriginDataType, - ): UmbBlockDataObjectModel | undefined; + ): never; abstract createWithPresets( contentElementTypeKey: string, diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/components/backoffice-modal-container/backoffice-modal-container.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/components/backoffice-modal-container/backoffice-modal-container.element.ts index 61cd3892a0..1295413273 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/components/backoffice-modal-container/backoffice-modal-container.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/components/backoffice-modal-container/backoffice-modal-container.element.ts @@ -49,8 +49,11 @@ export class UmbBackofficeModalContainerElement extends UmbLitElement { oldModals.forEach((modal) => { // TODO: I would not think this works as expected, the callback method has to be the exact same instance as the one added: [NL] - this._modalElementMap.get(modal.key)?.removeEventListener('close-end', this.#onCloseEnd.bind(this, modal.key)); + const modalElement = this._modalElementMap.get(modal.key); + modalElement?.removeEventListener('close-end', this.#onCloseEnd.bind(this, modal.key)); + modalElement?.destroy(); this._modalElementMap.delete(modal.key); + modal.destroy(); }); if (this._modals.length === 0) { diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/menu/components/menu/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/menu/components/menu/index.ts index ed60e33603..242a263f7a 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/menu/components/menu/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/menu/components/menu/index.ts @@ -1,2 +1 @@ export * from './menu.element.js'; -export * from './menu.context.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/menu/components/menu/menu.context.ts b/src/Umbraco.Web.UI.Client/src/packages/core/menu/components/menu/menu.context.ts deleted file mode 100644 index c96cdbb94e..0000000000 --- a/src/Umbraco.Web.UI.Client/src/packages/core/menu/components/menu/menu.context.ts +++ /dev/null @@ -1,15 +0,0 @@ -import type { ManifestMenu } from '../../menu.extension.js'; -import { UmbContextToken } from '@umbraco-cms/backoffice/context-api'; -import { UmbDeepState } from '@umbraco-cms/backoffice/observable-api'; - -export class UmbMenuContext { - #manifest = new UmbDeepState(undefined); - public readonly manifest = this.#manifest.asObservable(); - public readonly alias = this.#manifest.asObservablePart((x) => x?.alias); - - public setManifest(manifest: ManifestMenu | undefined) { - this.#manifest.setValue(manifest); - } -} - -export const UMB_MENU_CONTEXT = new UmbContextToken('UMB_MENU_CONTEXT'); diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/menu/components/menu/menu.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/menu/components/menu/menu.element.ts index 026a6277f3..7e051db0e0 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/menu/components/menu/menu.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/menu/components/menu/menu.element.ts @@ -10,11 +10,6 @@ export class UmbMenuElement extends UmbLitElement { @property({ attribute: false }) manifest?: ManifestMenu; - constructor() { - super(); - //this.provideContext(UMB_MENU_CONTEXT, new UmbMenuContext()); - } - override render() { return html` ) { super(host, args); + console.error( + 'Condition of alias `Umb.Condition.MenuAlias` is not implemented. Please report this issue if you where expecting this condition to work.', + ); + /* this.consumeContext(UMB_MENU_CONTEXT, (context) => { this.observe( context.alias, @@ -21,6 +24,7 @@ export class UmbMenuAliasCondition extends UmbConditionBase { #manifestAlias = new UmbStringState(undefined); #manifestPathname = new UmbStringState(undefined); #manifestLabel = new UmbStringState(undefined); @@ -10,7 +12,8 @@ export class UmbSectionContext { public readonly pathname = this.#manifestPathname.asObservable(); public readonly label = this.#manifestLabel.asObservable(); - constructor(manifest: ManifestSection) { + constructor(host: UmbControllerHost, manifest: ManifestSection) { + super(host, UMB_SECTION_CONTEXT); this.setManifest(manifest); } diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/tree/expansion-manager/tree-expansion-manager.test.ts b/src/Umbraco.Web.UI.Client/src/packages/core/tree/expansion-manager/tree-expansion-manager.test.ts index 9f9adb5d7a..178834786d 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/tree/expansion-manager/tree-expansion-manager.test.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/tree/expansion-manager/tree-expansion-manager.test.ts @@ -57,7 +57,6 @@ describe('UmbTreeExpansionManager', () => { const isExpanded = manager.isExpanded(item); expect(isExpanded).to.be.an.instanceOf(Observable); manager.isExpanded(item).subscribe((value) => { - console.log('VALUE', value); expect(value).to.be.true; done(); }); diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/validation/controllers/validation.controller.ts b/src/Umbraco.Web.UI.Client/src/packages/core/validation/controllers/validation.controller.ts index 6e497a22e7..d8231bc11d 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/validation/controllers/validation.controller.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/validation/controllers/validation.controller.ts @@ -172,9 +172,6 @@ export class UmbValidationController extends UmbControllerBase implements UmbVal setDataPath(dataPath: string): void { if (this.#baseDataPath) { if (this.#baseDataPath === dataPath) return; - // Just fire an error, as I haven't made the right clean up jet. Or haven't thought about what should happen if it changes while already setup. - // cause maybe all the messages should be removed as we are not interested in the old once any more. But then on the other side, some might be relevant as this is the same entity that changed its paths? - throw new Error('Data path is already set, we do not support changing the context data-path as of now.'); } if (!dataPath) { this.#stopInheritance(); @@ -197,12 +194,12 @@ export class UmbValidationController extends UmbControllerBase implements UmbVal this.#parent.removeValidator(this); } this.#parent = parent; - this.#readyToSync(); this.messages.clear(); this.#localMessages = undefined; this.#baseDataPath = dataPath; + this.#readyToSync(); // @deprecated - Will be removed in v.17 this.observe( diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/workspace/info-app/global-components/workspace-info-app-layout.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/workspace/info-app/global-components/workspace-info-app-layout.element.ts index 3b6388299e..83a10560ff 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/workspace/info-app/global-components/workspace-info-app-layout.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/workspace/info-app/global-components/workspace-info-app-layout.element.ts @@ -10,7 +10,9 @@ export class UmbWorkspaceInfoAppLayoutElement extends UmbLitElement { return html` - +
+ +
`; } @@ -20,6 +22,10 @@ export class UmbWorkspaceInfoAppLayoutElement extends UmbLitElement { uui-box { --uui-box-default-padding: 0; } + + #container { + padding-left: var(--uui-size-space-4) + } `, ]; } diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/global-contexts/document-configuration.context.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/global-contexts/document-configuration.context.ts index b69994d8a9..8829599ee0 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/global-contexts/document-configuration.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/global-contexts/document-configuration.context.ts @@ -1,4 +1,4 @@ -import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api'; +import { UmbContextBase } from '@umbraco-cms/backoffice/class-api'; import { UmbContextToken } from '@umbraco-cms/backoffice/context-api'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; import type { UmbApi } from '@umbraco-cms/backoffice/extension-api'; @@ -10,15 +10,17 @@ import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources'; * A context for fetching and caching the document configuration. * @deprecated Do not use this one, it will have ot change in near future. */ -export class UmbDocumentConfigurationContext extends UmbControllerBase implements UmbApi { +export class UmbDocumentConfigurationContext + extends UmbContextBase + implements UmbApi +{ /** * The cached document configuration. */ static #DocumentConfiguration: Promise; constructor(host: UmbControllerHost) { - super(host); - this.provideContext(UMB_DOCUMENT_CONFIGURATION_CONTEXT, this); + super(host, UMB_DOCUMENT_CONFIGURATION_CONTEXT); } /** diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/save-modal/document-save-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/save-modal/document-save-modal.element.ts index eeb910ea37..5b89bcfea9 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/save-modal/document-save-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/save-modal/document-save-modal.element.ts @@ -56,7 +56,7 @@ export class UmbDocumentSaveModalElement extends UmbModalBaseElement< } override render() { - return html` + return html`

Choose which variants to be saved.

@@ -74,7 +74,7 @@ export class UmbDocumentSaveModalElement extends UmbModalBaseElement< color="positive" @click=${this.#submit}> -
`; + `; } static override styles = [ diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/publishing/publish-with-descendants/modal/document-publish-with-descendants-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/publishing/publish-with-descendants/modal/document-publish-with-descendants-modal.element.ts index 6fb46c3812..56509ca263 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/publishing/publish-with-descendants/modal/document-publish-with-descendants-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/publishing/publish-with-descendants/modal/document-publish-with-descendants-modal.element.ts @@ -96,7 +96,7 @@ export class UmbDocumentPublishWithDescendantsModalElement extends UmbModalBaseE } override render() { - return html` + return html`

${this._options.length === 1 ? html` - `; + `; } static override styles = [ diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/publishing/publish/modal/document-publish-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/publishing/publish/modal/document-publish-modal.element.ts index 0257004049..0ffd7f83dc 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/publishing/publish/modal/document-publish-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/publishing/publish/modal/document-publish-modal.element.ts @@ -88,7 +88,7 @@ export class UmbDocumentPublishModalElement extends UmbModalBaseElement< } override render() { - return html` + return html`

Which variants would you like to publish?

@@ -107,7 +107,7 @@ export class UmbDocumentPublishModalElement extends UmbModalBaseElement< ?disabled=${this._hasNotSelectedMandatory} @click=${this.#submit}> -
`; + `; } static override styles = [ diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/publishing/schedule-publish/modal/document-schedule-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/publishing/schedule-publish/modal/document-schedule-modal.element.ts index 1b26cfdec1..63d07f8f65 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/publishing/schedule-publish/modal/document-schedule-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/publishing/schedule-publish/modal/document-schedule-modal.element.ts @@ -72,6 +72,8 @@ export class UmbDocumentScheduleModalElement extends UmbModalBaseElement< //Getting not published mandatory options — the options that are mandatory and not currently published. const missingMandatoryOptions = this._options.filter(isNotPublishedMandatory); this._hasNotSelectedMandatory = missingMandatoryOptions.some((option) => !selection.includes(option.unique)); + + this.requestUpdate(); }, '_selection', ); @@ -157,7 +159,7 @@ export class UmbDocumentScheduleModalElement extends UmbModalBaseElement< } override render() { - return html` + return html`

${when( this._options.length > 1, @@ -184,7 +186,7 @@ export class UmbDocumentScheduleModalElement extends UmbModalBaseElement< ?disabled=${!this._selection.length || this._hasNotSelectedMandatory} @click=${this.#submit}> - `; + `; } #renderOptions() { diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/publishing/unpublish/modal/document-unpublish-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/publishing/unpublish/modal/document-unpublish-modal.element.ts index 72e7de20b8..46a3a29556 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/publishing/unpublish/modal/document-unpublish-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/publishing/unpublish/modal/document-unpublish-modal.element.ts @@ -1,5 +1,5 @@ import { UmbDocumentVariantState, type UmbDocumentVariantOptionModel } from '../../../types.js'; -import { UmbDocumentReferenceRepository } from '../../../reference/index.js'; +import { UMB_DOCUMENT_ITEM_REPOSITORY_ALIAS, UMB_DOCUMENT_REFERENCE_REPOSITORY_ALIAS } from '../../../constants.js'; import { UMB_DOCUMENT_CONFIGURATION_CONTEXT } from '../../../global-contexts/index.js'; import type { UmbDocumentUnpublishModalData, @@ -9,6 +9,11 @@ import { css, customElement, html, nothing, state } from '@umbraco-cms/backoffic import { UmbModalBaseElement } from '@umbraco-cms/backoffice/modal'; import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; import { UmbSelectionManager } from '@umbraco-cms/backoffice/utils'; +import type { + UmbConfirmActionModalEntityReferencesConfig, + UmbConfirmActionModalEntityReferencesElement, +} from '@umbraco-cms/backoffice/relations'; +import type { UmbChangeEvent } from '@umbraco-cms/backoffice/event'; import '../../../modals/shared/document-variant-language-picker.element.js'; @@ -30,7 +35,6 @@ export class UmbDocumentUnpublishModalElement extends UmbModalBaseElement< UmbDocumentUnpublishModalValue > { protected readonly _selectionManager = new UmbSelectionManager(this); - #referencesRepository = new UmbDocumentReferenceRepository(this); @state() _options: Array = []; @@ -39,10 +43,7 @@ export class UmbDocumentUnpublishModalElement extends UmbModalBaseElement< _selection: Array = []; @state() - _hasReferences = false; - - @state() - _hasUnpublishPermission = true; + _canUnpublish = true; @state() _hasInvalidSelection = true; @@ -50,6 +51,9 @@ export class UmbDocumentUnpublishModalElement extends UmbModalBaseElement< @state() _isInvariant = false; + @state() + _referencesConfig?: UmbConfirmActionModalEntityReferencesConfig; + #pickableFilter = (option: UmbDocumentVariantOptionModel) => { if (!option.variant) { return false; @@ -58,7 +62,7 @@ export class UmbDocumentUnpublishModalElement extends UmbModalBaseElement< }; override firstUpdated() { - this.#getReferences(); + this.#configureReferences(); // If invariant, don't display the variant selection component. if (this.data?.options.length === 1 && this.data.options[0].unique === 'invariant') { @@ -70,6 +74,16 @@ export class UmbDocumentUnpublishModalElement extends UmbModalBaseElement< this.#configureSelectionManager(); } + #configureReferences() { + if (!this.data?.documentUnique) return; + + this._referencesConfig = { + itemRepositoryAlias: UMB_DOCUMENT_ITEM_REPOSITORY_ALIAS, + referenceRepositoryAlias: UMB_DOCUMENT_REFERENCE_REPOSITORY_ALIAS, + unique: this.data.documentUnique, + }; + } + async #configureSelectionManager() { this._selectionManager.setMultiple(true); this._selectionManager.setSelectable(true); @@ -103,33 +117,8 @@ export class UmbDocumentUnpublishModalElement extends UmbModalBaseElement< ); } - async #getReferences() { - if (!this.data?.documentUnique) return; - - const { data, error } = await this.#referencesRepository.requestReferencedBy(this.data?.documentUnique, 0, 1); - - if (error) { - console.error(error); - return; - } - - if (!data) return; - - this._hasReferences = data.total > 0; - - // If there are references, we also want to check if we are allowed to unpublish the document: - if (this._hasReferences) { - const documentConfigurationContext = await this.getContext(UMB_DOCUMENT_CONFIGURATION_CONTEXT); - if (!documentConfigurationContext) { - throw new Error('Document configuration context not found'); - } - this._hasUnpublishPermission = - (await documentConfigurationContext.getDocumentConfiguration())?.disableUnpublishWhenReferenced === false; - } - } - #submit() { - if (this._hasUnpublishPermission) { + if (this._canUnpublish) { const selection = this._isInvariant ? ['invariant'] : this._selection; this.value = { selection }; this.modalContext?.submit(); @@ -142,12 +131,25 @@ export class UmbDocumentUnpublishModalElement extends UmbModalBaseElement< this.modalContext?.reject(); } + async #onReferencesChange(event: UmbChangeEvent) { + event.stopPropagation(); + const target = event.target as UmbConfirmActionModalEntityReferencesElement; + const getReferencedByTotal = target.getTotalReferencedBy(); + const descendantsWithReferencesTotal = target.getTotalDescendantsWithReferences(); + const total = getReferencedByTotal + descendantsWithReferencesTotal; + + if (total > 0) { + const context = await this.getContext(UMB_DOCUMENT_CONFIGURATION_CONTEXT); + this._canUnpublish = (await context?.getDocumentConfiguration())?.disableUnpublishWhenReferenced === false; + } + } + private _requiredFilter = (variantOption: UmbDocumentVariantOptionModel): boolean => { return variantOption.language.isMandatory && !this._selection.includes(variantOption.unique); }; override render() { - return html` + return html` ${!this._isInvariant ? html`

@@ -169,20 +171,10 @@ export class UmbDocumentUnpublishModalElement extends UmbModalBaseElement<

- ${this.data?.documentUnique - ? html` - - ` - : nothing} - ${this._hasReferences - ? html` - - This item or its descendants is being referenced. Unpublishing can lead to broken links on your website. - Please take the appropriate actions. - - ` + ${this._referencesConfig + ? html`` : nothing}
@@ -190,13 +182,13 @@ export class UmbDocumentUnpublishModalElement extends UmbModalBaseElement<
-
`; + `; } static override styles = [ diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/components/document-reference-table.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/components/document-reference-table.element.ts index 5e73b4c2e9..1574e85a49 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/components/document-reference-table.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/components/document-reference-table.element.ts @@ -6,9 +6,15 @@ import { type UmbReferenceModel, isDocumentReference, isMediaReference, + isMemberReference, isDefaultReference, } from '@umbraco-cms/backoffice/relations'; +import { UmbDeprecation } from '@umbraco-cms/backoffice/utils'; +/** + * @deprecated Deprecated from 15.4. The element will be removed in v17.0.0. For modals use the or element instead + * @class UmbDocumentReferenceTableElement + */ @customElement('umb-document-reference-table') export class UmbDocumentReferenceTableElement extends UmbLitElement { #documentReferenceRepository = new UmbDocumentReferenceRepository(this); @@ -31,6 +37,13 @@ export class UmbDocumentReferenceTableElement extends UmbLitElement { _errorMessage = ''; override firstUpdated() { + new UmbDeprecation({ + removeInVersion: '17', + deprecated: ' element', + solution: + 'For modals use the or element instead', + }).warn(); + this.#getReferences(); } @@ -61,6 +74,9 @@ export class UmbDocumentReferenceTableElement extends UmbLitElement { if (isMediaReference(item)) { return item.mediaType.icon ?? 'icon-picture'; } + if (isMemberReference(item)) { + return item.memberType.icon ?? 'icon-user'; + } if (isDefaultReference(item)) { return item.icon ?? 'icon-document'; } diff --git a/src/Umbraco.Web.UI.Client/src/packages/health-check/dashboard-health-check.element.ts b/src/Umbraco.Web.UI.Client/src/packages/health-check/dashboard-health-check.element.ts index cb468209f7..fd5e06405f 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/health-check/dashboard-health-check.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/health-check/dashboard-health-check.element.ts @@ -1,7 +1,7 @@ import type { UmbDashboardHealthCheckGroupElement } from './views/health-check-group.element.js'; -import { UmbHealthCheckDashboardContext, UMB_HEALTHCHECK_DASHBOARD_CONTEXT } from './health-check-dashboard.context.js'; +import { UmbHealthCheckDashboardContext } from './health-check-dashboard.context.js'; import type { ManifestHealthCheck } from './health-check.extension.js'; -import { html, customElement, state } from '@umbraco-cms/backoffice/external/lit'; +import { html, customElement, state, type PropertyValueMap } from '@umbraco-cms/backoffice/external/lit'; import type { HealthCheckGroupResponseModel } from '@umbraco-cms/backoffice/external/backend-api'; import { HealthCheckService } from '@umbraco-cms/backoffice/external/backend-api'; import type { UmbRoute } from '@umbraco-cms/backoffice/router'; @@ -35,14 +35,14 @@ export class UmbDashboardHealthCheckElement extends UmbLitElement { constructor() { super(); - this.provideContext(UMB_HEALTHCHECK_DASHBOARD_CONTEXT, this._healthCheckDashboardContext); this.observe(umbExtensionsRegistry.byType('healthCheck'), (healthCheckManifests) => { this._healthCheckDashboardContext.manifests = healthCheckManifests; }); } - protected override firstUpdated() { + protected override firstUpdated(_changedProperties: PropertyValueMap | Map) { + super.firstUpdated(_changedProperties); this.#registerHealthChecks(); } diff --git a/src/Umbraco.Web.UI.Client/src/packages/health-check/health-check-dashboard.context.ts b/src/Umbraco.Web.UI.Client/src/packages/health-check/health-check-dashboard.context.ts index 2801a13365..516bf4b191 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/health-check/health-check-dashboard.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/health-check/health-check-dashboard.context.ts @@ -1,9 +1,14 @@ +import { UmbContextBase } from '@umbraco-cms/backoffice/class-api'; import { UmbHealthCheckContext } from './health-check.context.js'; import type { ManifestHealthCheck } from './health-check.extension.js'; import { UmbContextToken } from '@umbraco-cms/backoffice/context-api'; import { loadManifestApi } from '@umbraco-cms/backoffice/extension-api'; +import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; -export class UmbHealthCheckDashboardContext { +export class UmbHealthCheckDashboardContext extends UmbContextBase< + UmbHealthCheckDashboardContext, + typeof UMB_HEALTHCHECK_DASHBOARD_CONTEXT +> { #manifests: ManifestHealthCheck[] = []; set manifests(value: ManifestHealthCheck[]) { this.#manifests = value; @@ -14,10 +19,9 @@ export class UmbHealthCheckDashboardContext { } public apis = new Map(); - public host: HTMLElement; - constructor(host: HTMLElement) { - this.host = host; + constructor(host: UmbControllerHost) { + super(host, UMB_HEALTHCHECK_DASHBOARD_CONTEXT); } async checkAll() { @@ -32,7 +36,7 @@ export class UmbHealthCheckDashboardContext { if (!manifest.api) return; const api = await loadManifestApi(manifest.api); if (!api) return; - const apiInstance = new api(this.host); + const apiInstance = new api(this); if (api && UmbHealthCheckContext.isInstanceLike(apiInstance)) this.apis.set(manifest.meta.label, apiInstance); }); } diff --git a/src/Umbraco.Web.UI.Client/src/packages/log-viewer/workspace/logviewer-workspace.context.ts b/src/Umbraco.Web.UI.Client/src/packages/log-viewer/workspace/logviewer-workspace.context.ts index 0c1f7c84f2..664927d4a6 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/log-viewer/workspace/logviewer-workspace.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/log-viewer/workspace/logviewer-workspace.context.ts @@ -11,7 +11,7 @@ import type { } from '@umbraco-cms/backoffice/external/backend-api'; import { DirectionModel, LogLevelModel } from '@umbraco-cms/backoffice/external/backend-api'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; -import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api'; +import { UmbContextBase } from '@umbraco-cms/backoffice/class-api'; import { query } from '@umbraco-cms/backoffice/router'; import type { UmbWorkspaceContext } from '@umbraco-cms/backoffice/workspace'; import { UMB_WORKSPACE_CONTEXT } from '@umbraco-cms/backoffice/workspace'; @@ -27,7 +27,10 @@ export interface LogViewerDateRange { } // TODO: Revisit usage of workspace for this case... -export class UmbLogViewerWorkspaceContext extends UmbControllerBase implements UmbWorkspaceContext { +export class UmbLogViewerWorkspaceContext + extends UmbContextBase + implements UmbWorkspaceContext +{ public readonly workspaceAlias: string = 'Umb.Workspace.LogViewer'; #repository: UmbLogViewerRepository; @@ -104,10 +107,9 @@ export class UmbLogViewerWorkspaceContext extends UmbControllerBase implements U currentPage = 1; constructor(host: UmbControllerHost) { - super(host); + super(host, UMB_APP_LOG_VIEWER_CONTEXT); + // TODO: Revisit usage of workspace for this case... currently no other workspace context provides them self with their own token, we need to update UMB_APP_LOG_VIEWER_CONTEXT to become a workspace context. [NL] this.provideContext(UMB_WORKSPACE_CONTEXT, this); - // TODO: Revisit usage of workspace for this case... currently no other workspace context provides them self with their own token. - this.provideContext(UMB_APP_LOG_VIEWER_CONTEXT, this); this.#repository = new UmbLogViewerRepository(host); } diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-actions/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-actions/manifests.ts index f1c4effd40..ec4f69d43c 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-actions/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-actions/manifests.ts @@ -14,7 +14,7 @@ export const manifests: Array = [ { type: 'entityAction', alias: 'Umb.EntityAction.Media.Delete', - name: 'Delete Media Entity Action ', + name: 'Delete Media Entity Action', kind: 'deleteWithRelation', forEntityTypes: [UMB_MEDIA_ENTITY_TYPE], meta: { diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/info-app/media-references-workspace-info-app.element.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/info-app/media-references-workspace-info-app.element.ts index b1f46e6fd9..5a6151a8c4 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/info-app/media-references-workspace-info-app.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/info-app/media-references-workspace-info-app.element.ts @@ -59,10 +59,6 @@ export class UmbMediaReferencesWorkspaceInfoAppElement extends UmbLitElement { ); } - protected override firstUpdated(): void { - this.#getReferences(); - } - async #getReferences() { if (!this.#mediaUnique) { throw new Error('Media unique is required'); diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/constants.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/constants.ts index c2e40ebfe7..cc342219ab 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/members/member/constants.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member/constants.ts @@ -4,6 +4,7 @@ export { UMB_MEMBER_VARIANT_CONTEXT } from './property-dataset-context/member-pr export * from './collection/constants.js'; export * from './entity-actions/constants.js'; export * from './item/constants.js'; +export * from './reference/constants.js'; export * from './repository/constants.js'; export * from './search/constants.js'; export * from './workspace/constants.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/entity-actions/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/entity-actions/manifests.ts index 933d3a563b..56072ee35b 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/members/member/entity-actions/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member/entity-actions/manifests.ts @@ -2,18 +2,20 @@ import { UMB_MEMBER_ITEM_REPOSITORY_ALIAS } from '../item/constants.js'; import { UMB_MEMBER_ENTITY_TYPE } from '../entity.js'; import { UMB_MEMBER_DETAIL_REPOSITORY_ALIAS } from '../repository/detail/manifests.js'; import { manifests as createManifests } from './create/manifests.js'; +import { UMB_MEMBER_REFERENCE_REPOSITORY_ALIAS } from '../reference/constants.js'; export const manifests: Array = [ { type: 'entityAction', - kind: 'delete', alias: 'Umb.EntityAction.Member.Delete', name: 'Delete Member Entity Action', + kind: 'deleteWithRelation', forEntityTypes: [UMB_MEMBER_ENTITY_TYPE], meta: { - detailRepositoryAlias: UMB_MEMBER_DETAIL_REPOSITORY_ALIAS, itemRepositoryAlias: UMB_MEMBER_ITEM_REPOSITORY_ALIAS, + detailRepositoryAlias: UMB_MEMBER_DETAIL_REPOSITORY_ALIAS, + referenceRepositoryAlias: UMB_MEMBER_REFERENCE_REPOSITORY_ALIAS, }, }, ...createManifests, -]; +]; \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/item/repository/types.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/item/repository/types.ts index 660b7d84fc..2a105e08b4 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/members/member/item/repository/types.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member/item/repository/types.ts @@ -11,10 +11,19 @@ export interface UmbMemberItemModel { icon: string; collection: UmbReferenceByUnique | null; }; - variants: Array; + variants: Array; kind: UmbMemberKindType; } +export interface UmbMemberItemVariantModel { + name: string; + culture: string | null; +} + +/** + * @deprecated Deprecated in favor of UmbMemberItemVariantModel. Will be removed in v17.0.0 + * @interface UmbMemberVariantItemModel + */ export interface UmbMemberVariantItemModel { name: string; culture: string | null; diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/manifests.ts index 470f6503b3..7814ae8c8a 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/members/member/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member/manifests.ts @@ -5,6 +5,7 @@ import { manifests as memberPickerModalManifests } from './components/member-pic import { manifests as menuItemManifests } from './menu-item/manifests.js'; import { manifests as pickerManifests } from './picker/manifests.js'; import { manifests as propertyEditorManifests } from './property-editor/manifests.js'; +import { manifests as referenceManifests } from './reference/manifests.js'; import { manifests as repositoryManifests } from './repository/manifests.js'; import { manifests as searchManifests } from './search/manifests.js'; import { manifests as workspaceManifests } from './workspace/manifests.js'; @@ -19,6 +20,7 @@ export const manifests: Array = ...menuItemManifests, ...pickerManifests, ...propertyEditorManifests, + ...referenceManifests, ...repositoryManifests, ...searchManifests, ...workspaceManifests, diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/reference/constants.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/reference/constants.ts new file mode 100644 index 0000000000..41a409dec1 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member/reference/constants.ts @@ -0,0 +1 @@ +export * from './repository/constants.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/reference/index.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/reference/index.ts new file mode 100644 index 0000000000..3d76f338dd --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member/reference/index.ts @@ -0,0 +1 @@ +export * from './repository/index.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/reference/info-app/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/reference/info-app/manifests.ts new file mode 100644 index 0000000000..7ebbb37e12 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member/reference/info-app/manifests.ts @@ -0,0 +1,18 @@ +import { UMB_MEMBER_WORKSPACE_ALIAS } from '../../workspace/constants.js'; +import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; + +export const manifests: Array = [ + { + type: 'workspaceInfoApp', + name: 'Member References Workspace Info App', + alias: 'Umb.WorkspaceInfoApp.Member.References', + element: () => import('./member-references-workspace-info-app.element.js'), + weight: 90, + conditions: [ + { + alias: UMB_WORKSPACE_CONDITION_ALIAS, + match: UMB_MEMBER_WORKSPACE_ALIAS, + }, + ], + }, +]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/reference/info-app/member-references-workspace-info-app.element.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/reference/info-app/member-references-workspace-info-app.element.ts new file mode 100644 index 0000000000..23828e7026 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member/reference/info-app/member-references-workspace-info-app.element.ts @@ -0,0 +1,161 @@ +import { UmbMemberReferenceRepository } from '../repository/index.js'; +import { UMB_MEMBER_WORKSPACE_CONTEXT } from '../../workspace/constants.js'; +import { css, customElement, html, nothing, repeat, state, when } from '@umbraco-cms/backoffice/external/lit'; +import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; +import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; +import type { UmbReferenceItemModel } from '@umbraco-cms/backoffice/relations'; +import type { UUIPaginationEvent } from '@umbraco-cms/backoffice/external/uui'; +import type { UmbEntityUnique } from '@umbraco-cms/backoffice/entity'; + +@customElement('umb-member-references-workspace-info-app') +export class UmbMemberReferencesWorkspaceInfoAppElement extends UmbLitElement { + #itemsPerPage = 10; + + #referenceRepository; + + @state() + private _currentPage = 1; + + @state() + private _total = 0; + + @state() + private _items?: Array = []; + + @state() + private _loading = true; + + #workspaceContext?: typeof UMB_MEMBER_WORKSPACE_CONTEXT.TYPE; + #memberUnique?: UmbEntityUnique; + + constructor() { + super(); + this.#referenceRepository = new UmbMemberReferenceRepository(this); + + this.consumeContext(UMB_MEMBER_WORKSPACE_CONTEXT, (context) => { + this.#workspaceContext = context; + this.#observeMemberUnique(); + }); + } + + #observeMemberUnique() { + this.observe( + this.#workspaceContext?.unique, + (unique) => { + if (!unique) { + this.#memberUnique = undefined; + this._items = []; + return; + } + + if (this.#memberUnique === unique) { + return; + } + + this.#memberUnique = unique; + this.#getReferences(); + }, + 'umbReferencesDocumentUniqueObserver', + ); + } + + async #getReferences() { + if (!this.#memberUnique) { + throw new Error('Member unique is required'); + } + + this._loading = true; + + const { data } = await this.#referenceRepository.requestReferencedBy( + this.#memberUnique, + (this._currentPage - 1) * this.#itemsPerPage, + this.#itemsPerPage, + ); + + if (!data) return; + + this._total = data.total; + this._items = data.items; + + this._loading = false; + } + + #onPageChange(event: UUIPaginationEvent) { + if (this._currentPage === event.target.current) return; + this._currentPage = event.target.current; + + this.#getReferences(); + } + + override render() { + if (!this._items?.length) return nothing; + return html` + + ${when( + this._loading, + () => html``, + () => html`${this.#renderItems()} ${this.#renderPagination()}`, + )} + + `; + } + + #renderItems() { + if (!this._items) return; + return html` + + ${repeat( + this._items, + (item) => item.unique, + (item) => html``, + )} + + `; + } + + #renderPagination() { + if (!this._total) return nothing; + + const totalPages = Math.ceil(this._total / this.#itemsPerPage); + + if (totalPages <= 1) return nothing; + + return html` + + `; + } + + static override styles = [ + UmbTextStyles, + css` + :host { + display: contents; + } + + uui-table-cell { + color: var(--uui-color-text-alt); + } + + uui-pagination { + flex: 1; + display: inline-block; + } + + .pagination { + display: flex; + justify-content: center; + margin-top: var(--uui-size-space-4); + } + `, + ]; +} + +export default UmbMemberReferencesWorkspaceInfoAppElement; + +declare global { + interface HTMLElementTagNameMap { + 'umb-member-references-workspace-info-app': UmbMemberReferencesWorkspaceInfoAppElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/reference/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/reference/manifests.ts new file mode 100644 index 0000000000..cad6350ec8 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member/reference/manifests.ts @@ -0,0 +1,4 @@ +import { manifests as repositoryManifests } from './repository/manifests.js'; +import { manifests as infoAppManifests } from './info-app/manifests.js'; + +export const manifests: Array = [...repositoryManifests, ...infoAppManifests]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/reference/repository/constants.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/reference/repository/constants.ts new file mode 100644 index 0000000000..b715312e79 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member/reference/repository/constants.ts @@ -0,0 +1 @@ +export const UMB_MEMBER_REFERENCE_REPOSITORY_ALIAS = 'Umb.Repository.Member.Reference'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/reference/repository/index.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/reference/repository/index.ts new file mode 100644 index 0000000000..25fce74586 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member/reference/repository/index.ts @@ -0,0 +1 @@ +export * from './member-reference.repository.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/reference/repository/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/reference/repository/manifests.ts new file mode 100644 index 0000000000..745fc200fc --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member/reference/repository/manifests.ts @@ -0,0 +1,19 @@ +import { UMB_MEMBER_REFERENCE_REPOSITORY_ALIAS } from './constants.js'; +import { UMB_MANAGEMENT_API_DATA_SOURCE_ALIAS } from '@umbraco-cms/backoffice/repository'; + +export const manifests: Array = [ + { + type: 'repository', + alias: UMB_MEMBER_REFERENCE_REPOSITORY_ALIAS, + name: 'Member Reference Repository', + api: () => import('./member-reference.repository.js'), + }, + { + type: 'dataSourceDataMapping', + alias: 'Umb.DataSourceDataMapping.ManagementApi.MemberReferenceResponse', + name: 'Member Reference Response Management Api Data Mapping', + api: () => import('./member-reference-response.management-api.mapping.js'), + forDataSource: UMB_MANAGEMENT_API_DATA_SOURCE_ALIAS, + forDataModel: 'MemberReferenceResponseModel', + }, +]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/reference/repository/member-reference-response.management-api.mapping.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/reference/repository/member-reference-response.management-api.mapping.ts new file mode 100644 index 0000000000..e6418503e8 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member/reference/repository/member-reference-response.management-api.mapping.ts @@ -0,0 +1,32 @@ +import { UMB_MEMBER_ENTITY_TYPE } from '../../entity.js'; +import type { UmbMemberReferenceModel } from './types.js'; +import type { MemberReferenceResponseModel } from '@umbraco-cms/backoffice/external/backend-api'; +import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api'; +import type { UmbDataSourceDataMapping } from '@umbraco-cms/backoffice/repository'; + +export class UmbMemberReferenceResponseManagementApiDataMapping + extends UmbControllerBase + implements UmbDataSourceDataMapping +{ + async map(data: MemberReferenceResponseModel): Promise { + return { + entityType: UMB_MEMBER_ENTITY_TYPE, + memberType: { + alias: data.memberType.alias, + icon: data.memberType.icon, + name: data.memberType.name, + }, + name: data.name, + // TODO: this is a hardcoded array until the server can return the correct variants array + variants: [ + { + culture: null, + name: data.name ?? '', + }, + ], + unique: data.id, + }; + } +} + +export { UmbMemberReferenceResponseManagementApiDataMapping as api }; diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/reference/repository/member-reference.repository.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/reference/repository/member-reference.repository.ts new file mode 100644 index 0000000000..4db055d64f --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member/reference/repository/member-reference.repository.ts @@ -0,0 +1,36 @@ +import { UmbMemberReferenceServerDataSource } from './member-reference.server.data.js'; +import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; +import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api'; +import type { UmbEntityReferenceRepository } from '@umbraco-cms/backoffice/relations'; +import type { UmbEntityModel } from '@umbraco-cms/backoffice/entity'; +import type { UmbRepositoryResponse, UmbPagedModel } from '@umbraco-cms/backoffice/repository'; + +export class UmbMemberReferenceRepository extends UmbControllerBase implements UmbEntityReferenceRepository { + #referenceSource: UmbMemberReferenceServerDataSource; + + constructor(host: UmbControllerHost) { + super(host); + this.#referenceSource = new UmbMemberReferenceServerDataSource(this); + } + + async requestReferencedBy(unique: string, skip = 0, take = 20) { + if (!unique) throw new Error(`unique is required`); + return this.#referenceSource.getReferencedBy(unique, skip, take); + } + + async requestDescendantsWithReferences(unique: string, skip = 0, take = 20) { + if (!unique) throw new Error(`unique is required`); + return this.#referenceSource.getReferencedDescendants(unique, skip, take); + } + + async requestAreReferenced( + uniques: Array, + skip?: number, + take?: number, + ): Promise>> { + if (!uniques || uniques.length === 0) throw new Error(`uniques is required`); + return this.#referenceSource.getAreReferenced(uniques, skip, take); + } +} + +export default UmbMemberReferenceRepository; diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/reference/repository/member-reference.server.data.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/reference/repository/member-reference.server.data.ts new file mode 100644 index 0000000000..3ad6b90a6b --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member/reference/repository/member-reference.server.data.ts @@ -0,0 +1,121 @@ +import { UMB_MEMBER_ENTITY_TYPE } from '../../entity.js'; +import { MemberService } from '@umbraco-cms/backoffice/external/backend-api'; +import { UmbManagementApiDataMapper } from '@umbraco-cms/backoffice/repository'; +import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources'; +import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api'; +import type { UmbEntityModel } from '@umbraco-cms/backoffice/entity'; +import type { UmbEntityReferenceDataSource, UmbReferenceItemModel } from '@umbraco-cms/backoffice/relations'; +import type { UmbPagedModel, UmbDataSourceResponse } from '@umbraco-cms/backoffice/repository'; + +/** + * @class UmbMemberReferenceServerDataSource + * @implements {UmbEntityReferenceDataSource} + */ +export class UmbMemberReferenceServerDataSource extends UmbControllerBase implements UmbEntityReferenceDataSource { + #dataMapper = new UmbManagementApiDataMapper(this); + + /** + * Fetches the item for the given unique from the server + * @param {string} unique - The unique identifier of the item to fetch + * @param {number} skip - The number of items to skip + * @param {number} take - The number of items to take + * @returns {Promise>>} - Items that are referenced by the given unique + * @memberof UmbMemberReferenceServerDataSource + */ + async getReferencedBy( + unique: string, + skip: number = 0, + take: number = 20, + ): Promise>> { + const { data, error } = await tryExecuteAndNotify( + this, + MemberService.getMemberByIdReferencedBy({ id: unique, skip, take }), + ); + + if (data) { + const promises = data.items.map(async (item) => { + return this.#dataMapper.map({ + forDataModel: item.$type, + data: item, + fallback: async () => { + return { + ...item, + unique: item.id, + entityType: 'unknown', + }; + }, + }); + }); + + const items = await Promise.all(promises); + + return { data: { items, total: data.total } }; + } + + return { data, error }; + } + + /** + * Checks if the items are referenced by other items + * @param {Array} uniques - The unique identifiers of the items to fetch + * @param {number} skip - The number of items to skip + * @param {number} take - The number of items to take + * @returns {Promise>>} - Items that are referenced by other items + * @memberof UmbMemberReferenceServerDataSource + */ + async getAreReferenced( + uniques: Array, + skip: number = 0, + take: number = 20, + ): Promise>> { + const { data, error } = await tryExecuteAndNotify( + this, + MemberService.getMemberAreReferenced({ id: uniques, skip, take }), + ); + + if (data) { + const items: Array = data.items.map((item) => { + return { + unique: item.id, + entityType: UMB_MEMBER_ENTITY_TYPE, + }; + }); + + return { data: { items, total: data.total } }; + } + + return { data, error }; + } + + /** + * Returns any descendants of the given unique that is referenced by other items + * @param {string} unique - The unique identifier of the item to fetch descendants for + * @param {number} skip - The number of items to skip + * @param {number} take - The number of items to take + * @returns {Promise>>} - Any descendants of the given unique that is referenced by other items + * @memberof UmbMemberReferenceServerDataSource + */ + async getReferencedDescendants( + unique: string, + skip: number = 0, + take: number = 20, + ): Promise>> { + const { data, error } = await tryExecuteAndNotify( + this, + MemberService.getMemberByIdReferencedDescendants({ id: unique, skip, take }), + ); + + if (data) { + const items: Array = data.items.map((item) => { + return { + unique: item.id, + entityType: UMB_MEMBER_ENTITY_TYPE, + }; + }); + + return { data: { items, total: data.total } }; + } + + return { data, error }; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/reference/repository/types.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/reference/repository/types.ts new file mode 100644 index 0000000000..bc62433db5 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member/reference/repository/types.ts @@ -0,0 +1,14 @@ +import type { UmbMemberItemVariantModel } from '../../item/types.js'; +import type { UmbEntityModel } from '@umbraco-cms/backoffice/entity'; +import type { TrackedReferenceMemberTypeModel } from '@umbraco-cms/backoffice/external/backend-api'; + +export interface UmbMemberReferenceModel extends UmbEntityModel { + /** + * @deprecated use name on the variant array instead + * @type {(string | null)} + * @memberof UmbMemberReferenceModel + */ + name?: string | null; + memberType: TrackedReferenceMemberTypeModel; + variants: Array; +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/workspace/member/views/member/member-workspace-view-member-info.element.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/workspace/member/views/member/member-workspace-view-member-info.element.ts index 090f63cee1..4f6e625a1c 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/members/member/workspace/member/views/member/member-workspace-view-member-info.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member/workspace/member/views/member/member-workspace-view-member-info.element.ts @@ -8,7 +8,7 @@ import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import type { UmbWorkspaceViewElement } from '@umbraco-cms/backoffice/workspace'; import { UMB_WORKSPACE_MODAL } from '@umbraco-cms/backoffice/workspace'; import { UmbModalRouteRegistrationController } from '@umbraco-cms/backoffice/router'; -import { UmbMemberTypeItemRepository } from '@umbraco-cms/backoffice/member-type'; +import { UMB_MEMBER_TYPE_ENTITY_TYPE, UmbMemberTypeItemRepository } from '@umbraco-cms/backoffice/member-type'; import { UMB_SECTION_USER_PERMISSION_CONDITION_ALIAS } from '@umbraco-cms/backoffice/section'; import { UMB_SETTINGS_SECTION_ALIAS } from '@umbraco-cms/backoffice/settings'; import { createExtensionApiByAlias } from '@umbraco-cms/backoffice/extension-registry'; @@ -51,7 +51,7 @@ export class UmbMemberWorkspaceViewMemberInfoElement extends UmbLitElement imple new UmbModalRouteRegistrationController(this, UMB_WORKSPACE_MODAL) .addAdditionalPath('member-type') .onSetup(() => { - return { data: { entityType: 'member-type', preset: {} } }; + return { data: { entityType: UMB_MEMBER_TYPE_ENTITY_TYPE, preset: {} } }; }) .observeRouteBuilder((routeBuilder) => { this._editMemberTypePath = routeBuilder({}); diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/workspace/member/views/member/member-workspace-view-member.element.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/workspace/member/views/member/member-workspace-view-member.element.ts index de613acd6f..b8a2ccb8cc 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/members/member/workspace/member/views/member/member-workspace-view-member.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member/workspace/member/views/member/member-workspace-view-member.element.ts @@ -198,6 +198,10 @@ export class UmbMemberWorkspaceViewMemberElement extends UmbLitElement implement + +
+ +
`; } @@ -269,6 +273,9 @@ export class UmbMemberWorkspaceViewMemberElement extends UmbLitElement implement #left-column { /* Is there a way to make the wrapped right column grow only when wrapped? */ flex: 9999 1 500px; + display: flex; + flex-direction: column; + gap: var(--uui-size-space-4); } #right-column { flex: 1 1 350px; diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-delete/modal/bulk-delete-with-relation-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-delete/modal/bulk-delete-with-relation-modal.element.ts index c7d2a22c79..a6fb984818 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-delete/modal/bulk-delete-with-relation-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-delete/modal/bulk-delete-with-relation-modal.element.ts @@ -1,3 +1,4 @@ +import type { UmbConfirmBulkActionModalEntityReferencesConfig } from '../../../global-components/types.js'; import type { UmbBulkDeleteWithRelationConfirmModalData, UmbBulkDeleteWithRelationConfirmModalValue, @@ -15,16 +16,13 @@ import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; import { UmbModalBaseElement } from '@umbraco-cms/backoffice/modal'; import { umbFocus } from '@umbraco-cms/backoffice/lit-element'; -// import of local component -import '../../local-components/confirm-bulk-action-entity-references.element.js'; - @customElement('umb-bulk-delete-with-relation-confirm-modal') export class UmbBulkDeleteWithRelationConfirmModalElement extends UmbModalBaseElement< UmbBulkDeleteWithRelationConfirmModalData, UmbBulkDeleteWithRelationConfirmModalValue > { @state() - _referencesConfig?: any; + _referencesConfig?: UmbConfirmBulkActionModalEntityReferencesConfig; protected override firstUpdated(_changedProperties: PropertyValues): void { super.firstUpdated(_changedProperties); diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-trash/modal/bulk-trash-with-relation-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-trash/modal/bulk-trash-with-relation-modal.element.ts index 8785fe42e1..6468189296 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-trash/modal/bulk-trash-with-relation-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-trash/modal/bulk-trash-with-relation-modal.element.ts @@ -1,3 +1,4 @@ +import type { UmbConfirmBulkActionModalEntityReferencesConfig } from '../../../global-components/types.js'; import type { UmbBulkTrashWithRelationConfirmModalData, UmbBulkTrashWithRelationConfirmModalValue, @@ -15,16 +16,13 @@ import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; import { UmbModalBaseElement } from '@umbraco-cms/backoffice/modal'; import { umbFocus } from '@umbraco-cms/backoffice/lit-element'; -// import of local component -import '../../local-components/confirm-bulk-action-entity-references.element.js'; - @customElement('umb-bulk-trash-with-relation-confirm-modal') export class UmbBulkTrashWithRelationConfirmModalElement extends UmbModalBaseElement< UmbBulkTrashWithRelationConfirmModalData, UmbBulkTrashWithRelationConfirmModalValue > { @state() - _referencesConfig?: any; + _referencesConfig?: UmbConfirmBulkActionModalEntityReferencesConfig; protected override firstUpdated(_changedProperties: PropertyValues): void { super.firstUpdated(_changedProperties); diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/delete/modal/delete-with-relation-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/delete/modal/delete-with-relation-modal.element.ts index 539568c271..9df34a33b0 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/delete/modal/delete-with-relation-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/delete/modal/delete-with-relation-modal.element.ts @@ -1,3 +1,4 @@ +import type { UmbConfirmActionModalEntityReferencesConfig } from '../../../global-components/types.js'; import type { UmbDeleteWithRelationConfirmModalData, UmbDeleteWithRelationConfirmModalValue, @@ -17,8 +18,6 @@ import { umbFocus } from '@umbraco-cms/backoffice/lit-element'; import type { UmbItemRepository } from '@umbraco-cms/backoffice/repository'; import { createExtensionApiByAlias } from '@umbraco-cms/backoffice/extension-registry'; -import '../../local-components/confirm-action-entity-references.element.js'; - @customElement('umb-delete-with-relation-confirm-modal') export class UmbDeleteWithRelationConfirmModalElement extends UmbModalBaseElement< UmbDeleteWithRelationConfirmModalData, @@ -28,7 +27,7 @@ export class UmbDeleteWithRelationConfirmModalElement extends UmbModalBaseElemen _name?: string; @state() - _referencesConfig?: any; + _referencesConfig?: UmbConfirmActionModalEntityReferencesConfig; #itemRepository?: UmbItemRepository; diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/trash/modal/trash-with-relation-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/trash/modal/trash-with-relation-modal.element.ts index 61f40cf2bc..e6f3e21a42 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/trash/modal/trash-with-relation-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/trash/modal/trash-with-relation-modal.element.ts @@ -1,3 +1,4 @@ +import type { UmbConfirmActionModalEntityReferencesConfig } from '../../../global-components/types.js'; import type { UmbTrashWithRelationConfirmModalData, UmbTrashWithRelationConfirmModalValue, @@ -17,9 +18,6 @@ import { umbFocus } from '@umbraco-cms/backoffice/lit-element'; import type { UmbItemRepository } from '@umbraco-cms/backoffice/repository'; import { createExtensionApiByAlias } from '@umbraco-cms/backoffice/extension-registry'; -// import of local component -import '../../local-components/confirm-action-entity-references.element.js'; - @customElement('umb-trash-with-relation-confirm-modal') export class UmbTrashWithRelationConfirmModalElement extends UmbModalBaseElement< UmbTrashWithRelationConfirmModalData, @@ -29,7 +27,7 @@ export class UmbTrashWithRelationConfirmModalElement extends UmbModalBaseElement _name?: string; @state() - _referencesConfig?: any; + _referencesConfig?: UmbConfirmActionModalEntityReferencesConfig; #itemRepository?: UmbItemRepository; diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/local-components/confirm-action-entity-references.element.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/global-components/confirm-action-modal-entity-references.element.ts similarity index 89% rename from src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/local-components/confirm-action-entity-references.element.ts rename to src/Umbraco.Web.UI.Client/src/packages/relations/relations/global-components/confirm-action-modal-entity-references.element.ts index 282d2c2987..37cac2a5f2 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/local-components/confirm-action-entity-references.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/global-components/confirm-action-modal-entity-references.element.ts @@ -1,4 +1,4 @@ -import type { UmbEntityReferenceRepository, UmbReferenceItemModel } from '../../reference/types.js'; +import type { UmbEntityReferenceRepository, UmbReferenceItemModel } from '../reference/types.js'; import { html, customElement, @@ -12,16 +12,18 @@ import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; import type { UmbItemRepository } from '@umbraco-cms/backoffice/repository'; import { createExtensionApiByAlias } from '@umbraco-cms/backoffice/extension-registry'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; +import { UmbChangeEvent } from '@umbraco-cms/backoffice/event'; + +export interface UmbConfirmActionModalEntityReferencesConfig { + itemRepositoryAlias: string; + referenceRepositoryAlias: string; + unique: string; +} @customElement('umb-confirm-action-modal-entity-references') export class UmbConfirmActionModalEntityReferencesElement extends UmbLitElement { @property({ type: Object, attribute: false }) - config?: { - itemRepositoryAlias: string; - referenceRepositoryAlias: string; - entityType: string; - unique: string; - }; + config?: UmbConfirmActionModalEntityReferencesConfig; @state() _referencedByItems: Array = []; @@ -40,6 +42,14 @@ export class UmbConfirmActionModalEntityReferencesElement extends UmbLitElement #limitItems = 3; + getTotalReferencedBy() { + return this._totalReferencedByItems; + } + + getTotalDescendantsWithReferences() { + return this._totalDescendantsWithReferences; + } + protected override firstUpdated(_changedProperties: PropertyValues): void { super.firstUpdated(_changedProperties); this.#initData(); @@ -88,6 +98,7 @@ export class UmbConfirmActionModalEntityReferencesElement extends UmbLitElement if (data) { this._referencedByItems = [...data.items]; this._totalReferencedByItems = data.total; + this.dispatchEvent(new UmbChangeEvent()); } } @@ -118,6 +129,7 @@ export class UmbConfirmActionModalEntityReferencesElement extends UmbLitElement const uniques = data.items.map((item) => item.unique).filter((unique) => unique) as Array; const { data: items } = await this.#itemRepository.requestItems(uniques); this._descendantsWithReferences = items ?? []; + this.dispatchEvent(new UmbChangeEvent()); } } @@ -163,8 +175,6 @@ export class UmbConfirmActionModalEntityReferencesElement extends UmbLitElement ]; } -export { UmbConfirmActionModalEntityReferencesElement as element }; - declare global { interface HTMLElementTagNameMap { 'umb-confirm-action-modal-entity-references': UmbConfirmActionModalEntityReferencesElement; diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/local-components/confirm-bulk-action-entity-references.element.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/global-components/confirm-bulk-action-modal-entity-references.element.ts similarity index 93% rename from src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/local-components/confirm-bulk-action-entity-references.element.ts rename to src/Umbraco.Web.UI.Client/src/packages/relations/relations/global-components/confirm-bulk-action-modal-entity-references.element.ts index 4d07370a05..4c7f4f75b4 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/local-components/confirm-bulk-action-entity-references.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/global-components/confirm-bulk-action-modal-entity-references.element.ts @@ -1,4 +1,4 @@ -import type { UmbEntityReferenceRepository } from '../../reference/types.js'; +import type { UmbEntityReferenceRepository } from '../reference/types.js'; import { html, customElement, @@ -13,6 +13,12 @@ import type { UmbItemRepository } from '@umbraco-cms/backoffice/repository'; import { createExtensionApiByAlias } from '@umbraco-cms/backoffice/extension-registry'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; +export interface UmbConfirmBulkActionModalEntityReferencesConfig { + uniques: Array; + itemRepositoryAlias: string; + referenceRepositoryAlias: string; +} + @customElement('umb-confirm-bulk-action-modal-entity-references') export class UmbConfirmBulkActionModalEntityReferencesElement extends UmbLitElement { @property({ type: Object, attribute: false }) @@ -125,8 +131,6 @@ export class UmbConfirmBulkActionModalEntityReferencesElement extends UmbLitElem ]; } -export { UmbConfirmBulkActionModalEntityReferencesElement as element }; - declare global { interface HTMLElementTagNameMap { 'umb-confirm-bulk-action-modal-entity-references': UmbConfirmBulkActionModalEntityReferencesElement; diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/global-components/index.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/global-components/index.ts new file mode 100644 index 0000000000..5c2fd4749d --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/global-components/index.ts @@ -0,0 +1,5 @@ +import './confirm-action-modal-entity-references.element.js'; +import './confirm-bulk-action-modal-entity-references.element.js'; + +export * from './confirm-action-modal-entity-references.element.js'; +export * from './confirm-bulk-action-modal-entity-references.element.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/global-components/types.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/global-components/types.ts new file mode 100644 index 0000000000..44d4676fc7 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/global-components/types.ts @@ -0,0 +1,2 @@ +export type * from './confirm-action-modal-entity-references.element.js'; +export type * from './confirm-bulk-action-modal-entity-references.element.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/index.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/index.ts index 52a1c94b33..6bea1f6141 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/index.ts @@ -1,6 +1,7 @@ -export * from './constants.js'; export * from './collection/index.js'; +export * from './constants.js'; export * from './entity.js'; +export * from './global-components/index.js'; export * from './utils.js'; export type * from './types.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/reference/types.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/reference/types.ts index 599ee7559b..2567a3ece5 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/reference/types.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/reference/types.ts @@ -4,6 +4,7 @@ import type { DefaultReferenceResponseModel, DocumentReferenceResponseModel, MediaReferenceResponseModel, + MemberReferenceResponseModel, } from '@umbraco-cms/backoffice/external/backend-api'; import type { UmbDataSourceResponse, UmbPagedModel, UmbRepositoryResponse } from '@umbraco-cms/backoffice/repository'; @@ -13,7 +14,8 @@ export interface UmbReferenceItemModel extends UmbEntityModel {} export type UmbReferenceModel = | DefaultReferenceResponseModel | DocumentReferenceResponseModel - | MediaReferenceResponseModel; + | MediaReferenceResponseModel + | MemberReferenceResponseModel; export interface UmbEntityReferenceRepository extends UmbApi { requestReferencedBy( diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/types.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/types.ts index f82c4baafe..3306f451e1 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/types.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/types.ts @@ -1,4 +1,5 @@ import type { UmbRelationEntityType } from './entity.js'; +export type * from './global-components/types.js'; export type * from './reference/types.js'; export interface UmbRelationDetailModel { diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/utils.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/utils.ts index 6d1fab486c..cfe15b7fa7 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/utils.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/utils.ts @@ -3,6 +3,7 @@ import type { DefaultReferenceResponseModel, DocumentReferenceResponseModel, MediaReferenceResponseModel, + MemberReferenceResponseModel, } from '@umbraco-cms/backoffice/external/backend-api'; /** @@ -21,6 +22,14 @@ export function isMediaReference(item: UmbReferenceModel): item is MediaReferenc return typeof (item as MediaReferenceResponseModel).mediaType !== 'undefined'; } +/** + * + * @param item + */ +export function isMemberReference(item: UmbReferenceModel): item is MemberReferenceResponseModel { + return typeof (item as MemberReferenceResponseModel).memberType !== 'undefined'; +} + /** * * @param item diff --git a/src/Umbraco.Web.UI.Client/src/packages/user/user/collection/views/grid/user-grid-collection-view.element.ts b/src/Umbraco.Web.UI.Client/src/packages/user/user/collection/views/grid/user-grid-collection-view.element.ts index 812790a01f..06e8e96027 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/user/user/collection/views/grid/user-grid-collection-view.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/user/user/collection/views/grid/user-grid-collection-view.element.ts @@ -78,7 +78,7 @@ export class UmbUserGridCollectionViewElement extends UmbLitElement { return html` 0} diff --git a/tests/Umbraco.Tests.AcceptanceTest/package-lock.json b/tests/Umbraco.Tests.AcceptanceTest/package-lock.json index 3454d8ffe7..fddf89e58a 100644 --- a/tests/Umbraco.Tests.AcceptanceTest/package-lock.json +++ b/tests/Umbraco.Tests.AcceptanceTest/package-lock.json @@ -8,7 +8,7 @@ "hasInstallScript": true, "dependencies": { "@umbraco/json-models-builders": "^2.0.31", - "@umbraco/playwright-testhelpers": "^15.0.40", + "@umbraco/playwright-testhelpers": "^15.0.41", "camelize": "^1.0.0", "dotenv": "^16.3.1", "node-fetch": "^2.6.7" @@ -67,9 +67,9 @@ } }, "node_modules/@umbraco/playwright-testhelpers": { - "version": "15.0.40", - "resolved": "https://registry.npmjs.org/@umbraco/playwright-testhelpers/-/playwright-testhelpers-15.0.40.tgz", - "integrity": "sha512-dxXCCYeUH0rlASdHHNu8gQQrhK52gxGcwb/K1BlXFsr7Z7dz1U5eYMPUiVjDVg6LNCbqmQ/tmZqoAZLU5zDzIw==", + "version": "15.0.41", + "resolved": "https://registry.npmjs.org/@umbraco/playwright-testhelpers/-/playwright-testhelpers-15.0.41.tgz", + "integrity": "sha512-yZEhC3iSqT+O/2TBz0QGGEZyKleZ+qIW4YHTpm2nxPSdBAUaKqE4lb6UwylcQZtYnZVssXdi62jbzRPbG8XBlw==", "dependencies": { "@umbraco/json-models-builders": "2.0.31", "node-fetch": "^2.6.7" diff --git a/tests/Umbraco.Tests.AcceptanceTest/package.json b/tests/Umbraco.Tests.AcceptanceTest/package.json index 63aafd3813..38315b91a4 100644 --- a/tests/Umbraco.Tests.AcceptanceTest/package.json +++ b/tests/Umbraco.Tests.AcceptanceTest/package.json @@ -21,7 +21,7 @@ }, "dependencies": { "@umbraco/json-models-builders": "^2.0.31", - "@umbraco/playwright-testhelpers": "^15.0.40", + "@umbraco/playwright-testhelpers": "^15.0.41", "camelize": "^1.0.0", "dotenv": "^16.3.1", "node-fetch": "^2.6.7" diff --git a/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Content/BlockGrid/ContentWithBlockGrid.spec.ts b/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Content/BlockGrid/ContentWithBlockGrid.spec.ts index 6f4939d88e..2bec221ba9 100644 --- a/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Content/BlockGrid/ContentWithBlockGrid.spec.ts +++ b/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Content/BlockGrid/ContentWithBlockGrid.spec.ts @@ -265,3 +265,50 @@ test.skip('can add settings model for the block in the content', async ({umbraco test.skip('can move blocks in the content', async ({umbracoApi, umbracoUi}) => { // TODO: Implement it later }); + +test('can create content with a block grid with the inline editing mode enabled', async ({umbracoApi, umbracoUi}) => { + // Arrange + const customDataTypeId = await umbracoApi.dataType.createBlockGridWithABlockWithInlineEditingMode(customDataTypeName, elementTypeId); + await umbracoApi.documentType.createDocumentTypeWithPropertyEditor(documentTypeName, customDataTypeName, customDataTypeId); + await umbracoUi.goToBackOffice(); + await umbracoUi.content.goToSection(ConstantHelper.sections.content); + + // Act + await umbracoUi.content.clickActionsMenuAtRoot(); + await umbracoUi.content.clickCreateButton(); + await umbracoUi.content.chooseDocumentType(documentTypeName); + await umbracoUi.content.enterContentName(contentName); + await umbracoUi.content.clickSaveButton(); + + // Assert + await umbracoUi.content.doesSuccessNotificationHaveText(NotificationConstantHelper.success.created); + expect(await umbracoApi.document.doesNameExist(contentName)).toBeTruthy(); +}); + +test('can add a block element with inline editing mode enabled', async ({umbracoApi, umbracoUi}) => { + // Arrange + const inputText = 'This is block test'; + const customDataTypeId = await umbracoApi.dataType.createBlockGridWithABlockWithInlineEditingMode(customDataTypeName, elementTypeId); + const documentTypeId = await umbracoApi.documentType.createDocumentTypeWithPropertyEditor(documentTypeName, customDataTypeName, customDataTypeId); + await umbracoApi.document.createDefaultDocument(contentName, documentTypeId); + await umbracoUi.goToBackOffice(); + await umbracoUi.content.goToSection(ConstantHelper.sections.content); + + // Act + await umbracoUi.content.goToContentWithName(contentName); + await umbracoUi.content.clickAddBlockElementButton(); + await umbracoUi.content.clickTextButtonWithName(elementTypeName); + await umbracoUi.content.enterTextstring(inputText); + await umbracoUi.content.clickCreateModalButton(); + await umbracoUi.content.clickSaveAndPublishButton(); + + // Assert + await umbracoUi.content.doesSuccessNotificationHaveText(NotificationConstantHelper.success.saved); + await umbracoUi.content.doesSuccessNotificationHaveText(NotificationConstantHelper.success.published); + expect(await umbracoApi.document.doesNameExist(contentName)).toBeTruthy(); + const contentData = await umbracoApi.document.getByName(contentName); + expect(contentData.values[0].value.contentData[0].values[0].value).toEqual(inputText); + const blockListValue = contentData.values.find(item => item.editorAlias === "Umbraco.BlockGrid")?.value; + expect(blockListValue).toBeTruthy(); + await umbracoUi.content.doesPropertyContainValue(propertyInBlock, inputText); +}); \ No newline at end of file diff --git a/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Content/BlockList/ContentWithBlockList.spec.ts b/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Content/BlockList/ContentWithBlockList.spec.ts index fccdb0f9de..5d8b87da74 100644 --- a/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Content/BlockList/ContentWithBlockList.spec.ts +++ b/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Content/BlockList/ContentWithBlockList.spec.ts @@ -81,7 +81,7 @@ test('can add a block element in the content', async ({umbracoApi, umbracoUi}) = // Act await umbracoUi.content.goToContentWithName(contentName); await umbracoUi.content.clickAddBlockElementButton(); - await umbracoUi.content.clickTextButtonWithName(elementTypeName); + await umbracoUi.content.clickBlockElementWithName(elementTypeName); await umbracoUi.content.enterTextstring(inputText); await umbracoUi.content.clickCreateModalButton(); await umbracoUi.content.clickSaveButton(); @@ -132,9 +132,9 @@ test('can delete block element in the content', async ({umbracoApi, umbracoUi}) expect(blockGridValue).toBeFalsy(); }); -// Skip this flaky tests as sometimes the modal to choose block item is not displayed -test.skip('cannot add number of block element greater than the maximum amount', async ({umbracoApi, umbracoUi}) => { +test('cannot add number of block element greater than the maximum amount', async ({umbracoApi, umbracoUi}) => { // Arrange + const inputText = 'This is block test'; const customDataTypeId = await umbracoApi.dataType.createBlockListWithABlockAndMinAndMaxAmount(customDataTypeName, elementTypeId, 0, 1); const documentTypeId = await umbracoApi.documentType.createDocumentTypeWithPropertyEditor(documentTypeName, customDataTypeName, customDataTypeId); await umbracoApi.document.createDefaultDocument(contentName, documentTypeId); @@ -144,10 +144,12 @@ test.skip('cannot add number of block element greater than the maximum amount', // Act await umbracoUi.content.goToContentWithName(contentName); await umbracoUi.content.clickAddBlockElementButton(); - await umbracoUi.content.clickTextButtonWithName(elementTypeName); + await umbracoUi.content.clickBlockElementWithName(elementTypeName); + await umbracoUi.content.enterTextstring(inputText); await umbracoUi.content.clickCreateModalButton(); await umbracoUi.content.clickAddBlockElementButton(); await umbracoUi.content.clickTextButtonWithName(elementTypeName); + await umbracoUi.content.enterTextstring(inputText); await umbracoUi.content.clickCreateModalButton(); // Assert @@ -155,8 +157,7 @@ test.skip('cannot add number of block element greater than the maximum amount', await umbracoUi.content.doesFormValidationMessageContainText('too many'); }); -// Skip this flaky tests as sometimes the modal to choose block item is not displayed -test.skip('can set the label of block element in the content', async ({umbracoApi, umbracoUi}) => { +test('can set the label of block element in the content', async ({umbracoApi, umbracoUi}) => { // Arrange const blockLabel = 'Test Block Label'; const customDataTypeId = await umbracoApi.dataType.createBlockListDataTypeWithLabel(customDataTypeName, elementTypeId, blockLabel); @@ -168,7 +169,7 @@ test.skip('can set the label of block element in the content', async ({umbracoAp // Act await umbracoUi.content.goToContentWithName(contentName); await umbracoUi.content.clickAddBlockElementButton(); - await umbracoUi.content.clickTextButtonWithName(elementTypeName); + await umbracoUi.content.clickBlockElementWithName(elementTypeName); await umbracoUi.content.clickCreateModalButton(); await umbracoUi.content.clickSaveButton(); @@ -214,3 +215,49 @@ test.skip('can add settings model for the block in the content', async ({umbraco test.skip('can move blocks in the content', async ({umbracoApi, umbracoUi}) => { // TODO: Implement it later }); + +test('can create content with a block list with the inline editing mode enabled', async ({umbracoApi, umbracoUi}) => { + // Arrange + const customDataTypeId = await umbracoApi.dataType.createBlockListDataTypeWithInlineEditingMode(customDataTypeName, elementTypeId); + await umbracoApi.documentType.createDocumentTypeWithPropertyEditor(documentTypeName, customDataTypeName, customDataTypeId); + await umbracoUi.goToBackOffice(); + await umbracoUi.content.goToSection(ConstantHelper.sections.content); + + // Act + await umbracoUi.content.clickActionsMenuAtRoot(); + await umbracoUi.content.clickCreateButton(); + await umbracoUi.content.chooseDocumentType(documentTypeName); + await umbracoUi.content.enterContentName(contentName); + await umbracoUi.content.clickSaveButton(); + + // Assert + await umbracoUi.content.doesSuccessNotificationHaveText(NotificationConstantHelper.success.created); + expect(await umbracoApi.document.doesNameExist(contentName)).toBeTruthy(); +}); + +test('can add a block element with inline editing mode enabled', async ({umbracoApi, umbracoUi}) => { + // Arrange + const inputText = 'This is block test'; + const customDataTypeId = await umbracoApi.dataType.createBlockListDataTypeWithInlineEditingModeAndABlock(customDataTypeName, elementTypeId); + const documentTypeId = await umbracoApi.documentType.createDocumentTypeWithPropertyEditor(documentTypeName, customDataTypeName, customDataTypeId); + await umbracoApi.document.createDefaultDocument(contentName, documentTypeId); + await umbracoUi.goToBackOffice(); + await umbracoUi.content.goToSection(ConstantHelper.sections.content); + + // Act + await umbracoUi.content.goToContentWithName(contentName); + await umbracoUi.content.clickAddBlockElementButton(); + await umbracoUi.content.clickTextButtonWithName(elementTypeName); + await umbracoUi.content.clickInlineBlockCaretButtonForName(elementTypeName); + await umbracoUi.content.enterTextstring(inputText); + await umbracoUi.content.clickSaveAndPublishButton(); + + // Assert + await umbracoUi.content.doesSuccessNotificationHaveText(NotificationConstantHelper.success.saved); + await umbracoUi.content.doesSuccessNotificationHaveText(NotificationConstantHelper.success.published); + expect(await umbracoApi.document.doesNameExist(contentName)).toBeTruthy(); + const contentData = await umbracoApi.document.getByName(contentName); + expect(contentData.values[0].value.contentData[0].values[0].value).toEqual(inputText); + const blockListValue = contentData.values.find(item => item.editorAlias === "Umbraco.BlockList")?.value; + expect(blockListValue).toBeTruthy(); +}); \ No newline at end of file diff --git a/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Settings/DocumentType/DocumentTypeDesignTab.spec.ts b/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Settings/DocumentType/DocumentTypeDesignTab.spec.ts index f0ce32091b..e022b8b726 100644 --- a/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Settings/DocumentType/DocumentTypeDesignTab.spec.ts +++ b/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Settings/DocumentType/DocumentTypeDesignTab.spec.ts @@ -1,4 +1,4 @@ -import {ConstantHelper, test} from "@umbraco/playwright-testhelpers"; +import {ConstantHelper, NotificationConstantHelper, test} from "@umbraco/playwright-testhelpers"; import {expect} from "@playwright/test"; const documentTypeName = 'TestDocumentType'; @@ -28,7 +28,7 @@ test('can add a property to a document type', {tag: '@smoke'}, async ({umbracoAp await umbracoUi.documentType.clickSaveButton(); // Assert - await umbracoUi.documentType.isSuccessNotificationVisible(); + await umbracoUi.documentType.doesSuccessNotificationHaveText(NotificationConstantHelper.success.saved); expect(await umbracoApi.documentType.doesNameExist(documentTypeName)).toBeTruthy(); const documentTypeData = await umbracoApi.documentType.getByName(documentTypeName); const dataType = await umbracoApi.dataType.getByName(dataTypeName); @@ -49,7 +49,7 @@ test('can update a property in a document type', {tag: '@smoke'}, async ({umbrac await umbracoUi.documentType.clickSaveButton(); // Assert - await umbracoUi.documentType.isSuccessNotificationVisible(); + await umbracoUi.documentType.doesSuccessNotificationHaveText(NotificationConstantHelper.success.saved); expect(await umbracoApi.documentType.doesNameExist(documentTypeName)).toBeTruthy(); const documentTypeData = await umbracoApi.documentType.getByName(documentTypeName); const dataType = await umbracoApi.dataType.getByName(newDataTypeName); @@ -70,7 +70,7 @@ test('can update group name in a document type', async ({umbracoApi, umbracoUi}) await umbracoUi.documentType.clickSaveButton(); // Assert - await umbracoUi.documentType.isSuccessNotificationVisible(); + await umbracoUi.documentType.doesSuccessNotificationHaveText(NotificationConstantHelper.success.saved); expect(await umbracoApi.documentType.doesNameExist(documentTypeName)).toBeTruthy(); const documentTypeData = await umbracoApi.documentType.getByName(documentTypeName); expect(documentTypeData.containers[0].name).toBe(newGroupName); @@ -89,7 +89,7 @@ test('can delete a group in a document type', {tag: '@smoke'}, async ({umbracoAp await umbracoUi.documentType.clickSaveButton(); // Assert - await umbracoUi.documentType.isSuccessNotificationVisible(); + await umbracoUi.documentType.doesSuccessNotificationHaveText(NotificationConstantHelper.success.saved); const documentTypeData = await umbracoApi.documentType.getByName(documentTypeName); expect(documentTypeData.containers.length).toBe(0); expect(documentTypeData.properties.length).toBe(0); @@ -108,7 +108,7 @@ test('can delete a tab in a document type', async ({umbracoApi, umbracoUi}) => { await umbracoUi.documentType.clickSaveButton(); // Assert - await umbracoUi.documentType.isSuccessNotificationVisible(); + await umbracoUi.documentType.doesSuccessNotificationHaveText(NotificationConstantHelper.success.saved); expect(await umbracoApi.documentType.doesNameExist(documentTypeName)).toBeTruthy(); const documentTypeData = await umbracoApi.documentType.getByName(documentTypeName); expect(documentTypeData.containers.length).toBe(0); @@ -126,7 +126,7 @@ test('can delete a property editor in a document type', {tag: '@smoke'}, async ( await umbracoUi.documentType.clickSaveButton(); // Assert - await umbracoUi.documentType.isSuccessNotificationVisible(); + await umbracoUi.documentType.doesSuccessNotificationHaveText(NotificationConstantHelper.success.saved); expect(await umbracoApi.documentType.doesNameExist(documentTypeName)).toBeTruthy(); const documentTypeData = await umbracoApi.documentType.getByName(documentTypeName); expect(documentTypeData.properties.length).toBe(0); @@ -147,7 +147,7 @@ test('can create a document type with a property in a tab', {tag: '@smoke'}, asy await umbracoUi.documentType.clickSaveButton(); // Assert - await umbracoUi.documentType.isSuccessNotificationVisible(); + await umbracoUi.documentType.doesSuccessNotificationHaveText(NotificationConstantHelper.success.saved); expect(await umbracoApi.documentType.doesNameExist(documentTypeName)).toBeTruthy(); const documentTypeData = await umbracoApi.documentType.getByName(documentTypeName); expect(await umbracoApi.documentType.doesTabContainCorrectPropertyEditorInGroup(documentTypeName, dataTypeName, documentTypeData.properties[0].dataType.id, tabName, groupName)).toBeTruthy(); @@ -170,7 +170,7 @@ test('can create a document type with multiple groups', async ({umbracoApi, umbr await umbracoUi.documentType.clickSaveButton(); // Assert - await umbracoUi.documentType.isSuccessNotificationVisible(); + await umbracoUi.documentType.doesSuccessNotificationHaveText(NotificationConstantHelper.success.saved); expect(await umbracoApi.documentType.doesNameExist(documentTypeName)).toBeTruthy(); expect(await umbracoApi.documentType.doesGroupContainCorrectPropertyEditor(documentTypeName, dataTypeName, dataTypeData.id, groupName)).toBeTruthy(); expect(await umbracoApi.documentType.doesGroupContainCorrectPropertyEditor(documentTypeName, secondDataTypeName, secondDataType.id, secondGroupName)).toBeTruthy(); @@ -196,7 +196,7 @@ test('can create a document type with multiple tabs', async ({umbracoApi, umbrac await umbracoUi.documentType.clickSaveButton(); // Assert - await umbracoUi.documentType.isSuccessNotificationVisible(); + await umbracoUi.documentType.doesSuccessNotificationHaveText(NotificationConstantHelper.success.saved); expect(await umbracoApi.documentType.doesNameExist(documentTypeName)).toBeTruthy(); expect(await umbracoApi.documentType.doesTabContainCorrectPropertyEditorInGroup(documentTypeName, dataTypeName, dataTypeData.id, tabName, groupName)).toBeTruthy(); expect(await umbracoApi.documentType.doesTabContainCorrectPropertyEditorInGroup(documentTypeName, secondDataTypeName, secondDataType.id, secondTabName, secondGroupName)).toBeTruthy(); @@ -220,7 +220,7 @@ test('can create a document type with a composition', {tag: '@smoke'}, async ({u await umbracoUi.documentType.clickSaveButton(); // Assert - await umbracoUi.documentType.isSuccessNotificationVisible(); + await umbracoUi.documentType.doesSuccessNotificationHaveText(NotificationConstantHelper.success.saved); expect(umbracoUi.documentType.doesGroupHaveValue(groupName)).toBeTruthy(); // Checks if the composition in the document type is correct const documentTypeData = await umbracoApi.documentType.getByName(documentTypeName); @@ -249,7 +249,7 @@ test('can remove a composition from a document type', async ({umbracoApi, umbrac await umbracoUi.documentType.clickSaveButton(); // Assert - await umbracoUi.documentType.isSuccessNotificationVisible(); + await umbracoUi.documentType.doesSuccessNotificationHaveText(NotificationConstantHelper.success.saved); await umbracoUi.documentType.isGroupVisible(groupName, false); const documentTypeData = await umbracoApi.documentType.getByName(documentTypeName); expect(documentTypeData.compositions).toEqual([]); @@ -275,7 +275,7 @@ test('can reorder groups in a document type', async ({umbracoApi, umbracoUi}) => await umbracoUi.documentType.clickSaveButton(); // Assert - await umbracoUi.documentType.isSuccessNotificationVisible(); + await umbracoUi.documentType.doesSuccessNotificationHaveText(NotificationConstantHelper.success.saved); // Since we swapped sorting order, the firstGroupValue should have sortOrder 1 and the secondGroupValue should have sortOrder 0 expect(await umbracoApi.documentType.doesDocumentTypeGroupNameContainCorrectSortOrder(documentTypeName, secondGroupValue, 0)).toBeTruthy(); expect(await umbracoApi.documentType.doesDocumentTypeGroupNameContainCorrectSortOrder(documentTypeName, firstGroupValue, 1)).toBeTruthy(); @@ -300,7 +300,7 @@ test.skip('can reorder properties in a document type', async ({umbracoApi, umbra await umbracoUi.documentType.clickSaveButton(); // Assert - await umbracoUi.documentType.isSuccessNotificationVisible(); + await umbracoUi.documentType.doesSuccessNotificationHaveText(NotificationConstantHelper.success.saved); const documentTypeData = await umbracoApi.documentType.getByName(documentTypeName); expect(documentTypeData.properties[0].name).toBe(dataTypeNameTwo); expect(documentTypeData.properties[1].name).toBe(dataTypeName); @@ -324,7 +324,7 @@ test.skip('can reorder tabs in a document type', {tag: '@smoke'}, async ({umbrac await umbracoUi.documentType.clickSaveButton(); // Assert - await umbracoUi.documentType.isSuccessNotificationVisible(); + await umbracoUi.documentType.doesSuccessNotificationHaveText(NotificationConstantHelper.success.saved); expect(await umbracoApi.documentType.doesDocumentTypeTabNameContainCorrectSortOrder(documentTypeName, secondTabName, 0)).toBeTruthy(); expect(await umbracoApi.documentType.doesDocumentTypeTabNameContainCorrectSortOrder(documentTypeName, tabName, 1)).toBeTruthy(); }); @@ -344,7 +344,7 @@ test('can add a description to a property in a document type', async ({umbracoAp await umbracoUi.documentType.clickSaveButton(); // Assert - await umbracoUi.documentType.isSuccessNotificationVisible(); + await umbracoUi.documentType.doesSuccessNotificationHaveText(NotificationConstantHelper.success.saved); await expect(umbracoUi.documentType.enterDescriptionTxt).toBeVisible(); expect(umbracoUi.documentType.doesDescriptionHaveValue(descriptionText)).toBeTruthy(); const documentTypeData = await umbracoApi.documentType.getByName(documentTypeName); @@ -365,7 +365,7 @@ test('can set is mandatory for a property in a document type', {tag: '@smoke'}, await umbracoUi.documentType.clickSaveButton(); // Assert - await umbracoUi.documentType.isSuccessNotificationVisible(); + await umbracoUi.documentType.doesSuccessNotificationHaveText(NotificationConstantHelper.success.saved); const documentTypeData = await umbracoApi.documentType.getByName(documentTypeName); expect(documentTypeData.properties[0].validation.mandatory).toBeTruthy(); }); @@ -388,7 +388,7 @@ test('can enable validation for a property in a document type', async ({umbracoA await umbracoUi.documentType.clickSaveButton(); // Assert - await umbracoUi.documentType.isSuccessNotificationVisible(); + await umbracoUi.documentType.doesSuccessNotificationHaveText(NotificationConstantHelper.success.saved); const documentTypeData = await umbracoApi.documentType.getByName(documentTypeName); expect(documentTypeData.properties[0].validation.regEx).toBe(regex); expect(documentTypeData.properties[0].validation.regExMessage).toBe(regexMessage); @@ -408,7 +408,7 @@ test('can allow vary by culture for a property in a document type', {tag: '@smok await umbracoUi.documentType.clickSaveButton(); // Assert - await umbracoUi.documentType.isSuccessNotificationVisible(); + await umbracoUi.documentType.doesSuccessNotificationHaveText(NotificationConstantHelper.success.saved); const documentTypeData = await umbracoApi.documentType.getByName(documentTypeName); expect(documentTypeData.properties[0].variesByCulture).toBeTruthy(); }); @@ -427,7 +427,33 @@ test('can set appearance to label on top for a property in a document type', asy await umbracoUi.documentType.clickSaveButton(); // Assert - await umbracoUi.documentType.isSuccessNotificationVisible(); + await umbracoUi.documentType.doesSuccessNotificationHaveText(NotificationConstantHelper.success.saved); const documentTypeData = await umbracoApi.documentType.getByName(documentTypeName); expect(documentTypeData.properties[0].appearance.labelOnTop).toBeTruthy(); }); + +test('can add a block list property with inline editing mode to a document type', {tag: '@smoke'}, async ({umbracoApi, umbracoUi}) => { + // Arrange + const blockListDataTypeName = 'TestBlockList'; + await umbracoApi.documentType.createDefaultDocumentType(documentTypeName); + await umbracoApi.dataType.createBlockListDataTypeWithInlineEditingMode(blockListDataTypeName, true); + await umbracoUi.documentType.goToSection(ConstantHelper.sections.settings); + + // Act + await umbracoUi.documentType.goToDocumentType(documentTypeName); + await umbracoUi.documentType.clickAddGroupButton(); + await umbracoUi.documentType.addPropertyEditor(blockListDataTypeName); + await umbracoUi.documentType.enterGroupName(groupName); + await umbracoUi.documentType.clickSaveButton(); + + // Assert + await umbracoUi.documentType.doesSuccessNotificationHaveText(NotificationConstantHelper.success.saved); + expect(await umbracoApi.documentType.doesNameExist(documentTypeName)).toBeTruthy(); + const documentTypeData = await umbracoApi.documentType.getByName(documentTypeName); + const blockListDataTypeData = await umbracoApi.dataType.getByName(blockListDataTypeName); + // Checks if the correct property was added to the document type + expect(documentTypeData.properties[0].dataType.id).toBe(blockListDataTypeData.id); + + // Clean + await umbracoApi.dataType.ensureNameNotExists(blockListDataTypeName); +}); diff --git a/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/RelationRepositoryTest.cs b/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/RelationRepositoryTest.cs index c32b0be6a4..002c7a463b 100644 --- a/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/RelationRepositoryTest.cs +++ b/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/RelationRepositoryTest.cs @@ -225,20 +225,22 @@ internal sealed class RelationRepositoryTest : UmbracoIntegrationTest RelationService.GetRelationTypeByAlias(Constants.Conventions.RelationTypes.RelatedMediaAlias); var relatedContentRelType = RelationService.GetRelationTypeByAlias(Constants.Conventions.RelationTypes.RelatedDocumentAlias); + var relatedMemberRelType = + RelationService.GetRelationTypeByAlias(Constants.Conventions.RelationTypes.RelatedMemberAlias); - parents = repository.GetPagedParentEntitiesByChildId(createdMedia[0].Id, 0, 11, out totalRecords, new[] { relatedContentRelType.Id, relatedMediaRelType.Id }).ToList(); + parents = repository.GetPagedParentEntitiesByChildId(createdMedia[0].Id, 0, 11, out totalRecords, [relatedContentRelType.Id, relatedMediaRelType.Id, relatedMemberRelType.Id]).ToList(); Assert.AreEqual(6, totalRecords); Assert.AreEqual(6, parents.Count); - parents = repository.GetPagedParentEntitiesByChildId(createdMedia[0].Id, 1, 11, out totalRecords, new[] { relatedContentRelType.Id, relatedMediaRelType.Id }).ToList(); + parents = repository.GetPagedParentEntitiesByChildId(createdMedia[0].Id, 1, 11, out totalRecords, [relatedContentRelType.Id, relatedMediaRelType.Id, relatedMemberRelType.Id]).ToList(); Assert.AreEqual(6, totalRecords); Assert.AreEqual(0, parents.Count); - parents = repository.GetPagedParentEntitiesByChildId(createdContent[0].Id, 0, 6, out totalRecords, new[] { relatedContentRelType.Id, relatedMediaRelType.Id }).ToList(); + parents = repository.GetPagedParentEntitiesByChildId(createdContent[0].Id, 0, 6, out totalRecords, [relatedContentRelType.Id, relatedMediaRelType.Id, relatedMemberRelType.Id]).ToList(); Assert.AreEqual(3, totalRecords); Assert.AreEqual(3, parents.Count); - parents = repository.GetPagedParentEntitiesByChildId(createdContent[0].Id, 1, 6, out totalRecords, new[] { relatedContentRelType.Id, relatedMediaRelType.Id }).ToList(); + parents = repository.GetPagedParentEntitiesByChildId(createdContent[0].Id, 1, 6, out totalRecords, [relatedContentRelType.Id, relatedMediaRelType.Id, relatedMemberRelType.Id]).ToList(); Assert.AreEqual(3, totalRecords); Assert.AreEqual(0, parents.Count); } @@ -281,15 +283,15 @@ internal sealed class RelationRepositoryTest : UmbracoIntegrationTest var repository = CreateRepository(ScopeProvider, out _); // Get parent entities for child id - var parents = repository.GetPagedChildEntitiesByParentId(createdContent[0].Id, 0, 6, out var totalRecords) + var parents = repository.GetPagedChildEntitiesByParentId(createdContent[0].Id, 0, 9, out var totalRecords) .ToList(); - Assert.AreEqual(6, totalRecords); - Assert.AreEqual(6, parents.Count); + Assert.AreEqual(9, totalRecords); + Assert.AreEqual(9, parents.Count); // Add the next page - parents.AddRange(repository.GetPagedChildEntitiesByParentId(createdContent[0].Id, 1, 6, out totalRecords)); - Assert.AreEqual(6, totalRecords); - Assert.AreEqual(6, parents.Count); + parents.AddRange(repository.GetPagedChildEntitiesByParentId(createdContent[0].Id, 1, 9, out totalRecords)); + Assert.AreEqual(9, totalRecords); + Assert.AreEqual(9, parents.Count); var contentEntities = parents.OfType().ToList(); var mediaEntities = parents.OfType().ToList(); @@ -297,7 +299,7 @@ internal sealed class RelationRepositoryTest : UmbracoIntegrationTest Assert.AreEqual(3, contentEntities.Count); Assert.AreEqual(3, mediaEntities.Count); - Assert.AreEqual(0, memberEntities.Count); + Assert.AreEqual(3, memberEntities.Count); // only of a certain type parents.AddRange(repository.GetPagedChildEntitiesByParentId(createdContent[0].Id, 0, 100, out totalRecords, UmbracoObjectTypes.Media.GetGuid())); @@ -307,20 +309,22 @@ internal sealed class RelationRepositoryTest : UmbracoIntegrationTest Assert.AreEqual(3, totalRecords); parents.AddRange(repository.GetPagedChildEntitiesByParentId(createdContent[0].Id, 0, 100, out totalRecords, UmbracoObjectTypes.Member.GetGuid())); - Assert.AreEqual(0, totalRecords); + Assert.AreEqual(3, totalRecords); // Test getting relations of specified relation types var relatedMediaRelType = RelationService.GetRelationTypeByAlias(Constants.Conventions.RelationTypes.RelatedMediaAlias); var relatedContentRelType = RelationService.GetRelationTypeByAlias(Constants.Conventions.RelationTypes.RelatedDocumentAlias); + var relatedMemberRelType = + RelationService.GetRelationTypeByAlias(Constants.Conventions.RelationTypes.RelatedMemberAlias); - parents = repository.GetPagedChildEntitiesByParentId(createdContent[0].Id, 0, 6, out totalRecords, new[] { relatedContentRelType.Id, relatedMediaRelType.Id }).ToList(); - Assert.AreEqual(3, totalRecords); - Assert.AreEqual(3, parents.Count); + parents = repository.GetPagedChildEntitiesByParentId(createdContent[0].Id, 0, 6, out totalRecords, [relatedContentRelType.Id, relatedMediaRelType.Id, relatedMemberRelType.Id]).ToList(); + Assert.AreEqual(6, totalRecords); + Assert.AreEqual(6, parents.Count); - parents = repository.GetPagedChildEntitiesByParentId(createdContent[0].Id, 1, 6, out totalRecords, new[] { relatedContentRelType.Id, relatedMediaRelType.Id }).ToList(); - Assert.AreEqual(3, totalRecords); + parents = repository.GetPagedChildEntitiesByParentId(createdContent[0].Id, 1, 6, out totalRecords, [relatedContentRelType.Id, relatedMediaRelType.Id, relatedMemberRelType.Id]).ToList(); + Assert.AreEqual(6, totalRecords); Assert.AreEqual(0, parents.Count); } } @@ -368,6 +372,8 @@ internal sealed class RelationRepositoryTest : UmbracoIntegrationTest RelationService.GetRelationTypeByAlias(Constants.Conventions.RelationTypes.RelatedMediaAlias); var relatedContentRelType = RelationService.GetRelationTypeByAlias(Constants.Conventions.RelationTypes.RelatedDocumentAlias); + var relatedMemberRelType = + RelationService.GetRelationTypeByAlias(Constants.Conventions.RelationTypes.RelatedMemberAlias); // Relate content to media foreach (var content in createdContent) @@ -387,6 +393,15 @@ internal sealed class RelationRepositoryTest : UmbracoIntegrationTest } } + // Relate content to member + foreach (var content in createdContent) + { + foreach (var member in createdMembers) + { + RelationService.Relate(content.Id, member.Id, relatedMemberRelType); + } + } + // Relate members to media foreach (var member in createdMembers) { diff --git a/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/RelationTypeRepositoryTest.cs b/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/RelationTypeRepositoryTest.cs index 72b81aa1ba..948cd07287 100644 --- a/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/RelationTypeRepositoryTest.cs +++ b/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/RelationTypeRepositoryTest.cs @@ -100,7 +100,7 @@ internal sealed class RelationTypeRepositoryTest : UmbracoIntegrationTest var repository = CreateRepository(provider); // Act - var relationType = repository.Get(8) as IRelationTypeWithIsDependency; + var relationType = repository.Get(9) as IRelationTypeWithIsDependency; // Assert Assert.That(relationType, Is.Not.Null); @@ -130,7 +130,7 @@ internal sealed class RelationTypeRepositoryTest : UmbracoIntegrationTest Assert.That(relationTypes, Is.Not.Null); Assert.That(relationTypes.Any(), Is.True); Assert.That(relationTypes.Any(x => x == null), Is.False); - Assert.That(relationTypes.Count(), Is.EqualTo(8)); + Assert.That(relationTypes.Count(), Is.EqualTo(9)); } } @@ -165,7 +165,7 @@ internal sealed class RelationTypeRepositoryTest : UmbracoIntegrationTest // Act var exists = repository.Exists(3); - var doesntExist = repository.Exists(9); + var doesntExist = repository.Exists(99); // Assert Assert.That(exists, Is.True); diff --git a/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/RelationServiceTests.cs b/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/RelationServiceTests.cs index 951b6ecd2d..cd65b0d356 100644 --- a/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/RelationServiceTests.cs +++ b/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/RelationServiceTests.cs @@ -26,6 +26,10 @@ internal sealed class RelationServiceTests : UmbracoIntegrationTest private IMediaService MediaService => GetRequiredService(); + private IMemberTypeService MemberTypeService => GetRequiredService(); + + private IMemberService MemberService => GetRequiredService(); + private IRelationService RelationService => GetRequiredService(); [Test] @@ -115,6 +119,39 @@ internal sealed class RelationServiceTests : UmbracoIntegrationTest Assert.AreEqual(6, entities.Count); } + [Test] + public void Return_List_Of_Content_Items_Where_Member_Item_Referenced() + { + var memberType = MemberTypeBuilder.CreateSimpleMemberType("testMemberType", "Test Member Type"); + MemberTypeService.Save(memberType); + var member = MemberBuilder.CreateSimpleMember(memberType, "Test Member", "test@test.com", "xxxxxxxx", "testMember"); + MemberService.Save(member); + + var ct = ContentTypeBuilder.CreateTextPageContentType("richTextTest"); + ct.AllowedTemplates = Enumerable.Empty(); + ContentTypeService.Save(ct); + + void CreateContentWithMemberRefs() + { + var content = ContentBuilder.CreateTextpageContent(ct, "my content 2", -1); + + // 'bodyText' is a property with a RTE property editor which we knows automatically tracks relations + content.Properties["bodyText"].SetValue(@"
"); + ContentService.Save(content); + } + + for (var i = 0; i < 6; i++) + { + CreateContentWithMemberRefs(); // create 6 content items referencing the same member + } + + var relations = RelationService.GetByChildId(member.Id, Constants.Conventions.RelationTypes.RelatedMemberAlias).ToList(); + Assert.AreEqual(6, relations.Count); + + var entities = RelationService.GetParentEntitiesFromRelations(relations).ToList(); + Assert.AreEqual(6, entities.Count); + } + [Test] public void Can_Create_RelationType_Without_Name() { diff --git a/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/TrackRelationsTests.cs b/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/TrackRelationsTests.cs index 2a9fde92e1..ee05d4fef5 100644 --- a/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/TrackRelationsTests.cs +++ b/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/TrackRelationsTests.cs @@ -23,6 +23,10 @@ internal sealed class TrackRelationsTests : UmbracoIntegrationTestWithContent private IMediaService MediaService => GetRequiredService(); + private IMemberTypeService MemberTypeService => GetRequiredService(); + + private IMemberService MemberService => GetRequiredService(); + private IRelationService RelationService => GetRequiredService(); // protected override void CustomTestSetup(IUmbracoBuilder builder) @@ -42,6 +46,11 @@ internal sealed class TrackRelationsTests : UmbracoIntegrationTestWithContent MediaService.Save(m1); MediaService.Save(m2); + var memberType = MemberTypeBuilder.CreateSimpleMemberType("testMemberType", "Test Member Type"); + MemberTypeService.Save(memberType); + var member = MemberBuilder.CreateSimpleMember(memberType, "Test Member", "test@test.com", "xxxxxxxx", "testMember"); + MemberService.Save(member); + var template = TemplateBuilder.CreateTextPageTemplate(); FileService.SaveTemplate(template); @@ -62,17 +71,24 @@ internal sealed class TrackRelationsTests : UmbracoIntegrationTestWithContent

hello +

+

+ +

"); ContentService.Save(c2); var relations = RelationService.GetByParentId(c2.Id).ToList(); - Assert.AreEqual(3, relations.Count); + Assert.AreEqual(4, relations.Count); Assert.AreEqual(Constants.Conventions.RelationTypes.RelatedMediaAlias, relations[0].RelationType.Alias); Assert.AreEqual(m1.Id, relations[0].ChildId); Assert.AreEqual(Constants.Conventions.RelationTypes.RelatedMediaAlias, relations[1].RelationType.Alias); Assert.AreEqual(m2.Id, relations[1].ChildId); Assert.AreEqual(Constants.Conventions.RelationTypes.RelatedDocumentAlias, relations[2].RelationType.Alias); Assert.AreEqual(c1.Id, relations[2].ChildId); + Assert.AreEqual(Constants.Conventions.RelationTypes.RelatedMemberAlias, relations[3].RelationType.Alias); + Assert.AreEqual(member.Id, relations[3].ChildId); + } }